1package com.fs.starfarer.api.impl.campaign.skills;
4import java.util.ArrayList;
5import java.util.Collections;
6import java.util.Comparator;
7import java.util.HashSet;
11import com.fs.starfarer.api.GameState;
12import com.fs.starfarer.api.Global;
13import com.fs.starfarer.api.campaign.AICoreOfficerPlugin;
14import com.fs.starfarer.api.campaign.CampaignFleetAPI;
15import com.fs.starfarer.api.campaign.FleetDataAPI;
16import com.fs.starfarer.api.characters.CustomSkillDescription;
17import com.fs.starfarer.api.characters.FleetTotalItem;
18import com.fs.starfarer.api.characters.MutableCharacterStatsAPI;
19import com.fs.starfarer.api.characters.MutableCharacterStatsAPI.SkillLevelAPI;
20import com.fs.starfarer.api.characters.PersonAPI;
21import com.fs.starfarer.api.characters.SkillSpecAPI;
22import com.fs.starfarer.api.combat.MutableShipStatsAPI;
23import com.fs.starfarer.api.combat.ShipHullSpecAPI.ShipTypeHints;
24import com.fs.starfarer.api.combat.ShipVariantAPI;
25import com.fs.starfarer.api.fleet.FleetMemberAPI;
26import com.fs.starfarer.api.impl.campaign.ids.HullMods;
27import com.fs.starfarer.api.impl.campaign.intel.BaseIntelPlugin;
28import com.fs.starfarer.api.impl.hullmods.Automated;
29import com.fs.starfarer.api.ui.BaseTooltipCreator;
30import com.fs.starfarer.api.ui.TooltipMakerAPI;
31import com.fs.starfarer.api.ui.TooltipMakerAPI.TooltipCreator;
32import com.fs.starfarer.api.util.Misc;
72 public static enum ThresholdBonusType {
90 public void init(MutableCharacterStatsAPI stats, SkillSpecAPI skill) {
91 indent = BaseIntelPlugin.BULLET;
92 tc = Misc.getTextColor();
93 hc = Misc.getHighlightColor();
94 dhc = Misc.setAlpha(
hc, 155);
96 float level = stats.getSkillLevel(skill.getId());
98 tc = Misc.getGrayColor();
102 dtc = Misc.getGrayColor();
105 public void initElite(MutableCharacterStatsAPI stats, SkillSpecAPI skill) {
106 indent = BaseIntelPlugin.BULLET;
107 tc = Misc.getTextColor();
108 hc = Misc.getHighlightColor();
109 dhc = Misc.setAlpha(
hc, 155);
111 float level = stats.getSkillLevel(skill.getId());
113 tc = Misc.getGrayColor();
117 dtc = Misc.getGrayColor();
123 String baysStr =
"fighter bays";
124 if (bays == 1) baysStr =
"fighter bay";
126 info.addPara(
indent +
"Maximum at %s or less fighter bays in fleet, your fleet has %s " + baysStr,
131 info.addPara(
indent +
"Maximum at %s or less fighter bays in fleet",
137 public void addOPThresholdInfo(TooltipMakerAPI info, FleetDataAPI data, MutableCharacterStatsAPI cStats) {
140 public void addOPThresholdInfo(TooltipMakerAPI info, FleetDataAPI data, MutableCharacterStatsAPI cStats,
float threshold) {
144 info.addPara(
indent +
"Maximum at %s or less total combat ship " +
RECOVERY_COST +
", your fleet's total is %s",
146 "" + (
int) threshold,
147 "" + (
int)Math.round(op));
149 info.addPara(
indent +
"Maximum at %s or less total combat ship " +
RECOVERY_COST +
" for fleet",
151 "" + (
int) threshold);
157 String opStr =
"points";
158 if (op == 1) opStr =
"point";
159 info.addPara(
indent +
"Maximum at %s or less total combat ship ordnance points in fleet, your fleet has %s " + opStr,
161 "" + (
int) threshold,
162 "" + (
int)Math.round(op));
164 info.addPara(
indent +
"Maximum at %s or less total combat ship ordnance points in fleet",
166 "" + (
int) threshold);
170 public void addOPThresholdAll(TooltipMakerAPI info, FleetDataAPI data, MutableCharacterStatsAPI cStats,
float threshold) {
174 info.addPara(
indent +
"Maximum at %s or less total " +
RECOVERY_COST +
", your fleet's total is %s",
176 "" + (
int) threshold,
177 "" + (
int)Math.round(op));
181 "" + (
int) threshold);
189 String opStr =
"points";
190 if (op == 1) opStr =
"point";
191 info.addPara(
indent +
"Maximum at %s or less total ordnance points in fleet, your fleet has %s " + opStr,
193 "" + (
int) threshold,
194 "" + (
int)Math.round(op));
196 info.addPara(
indent +
"Maximum at %s or less total ordnance points in fleet",
198 "" + (
int) threshold);
206 info.addPara(
indent +
"Maximum at %s or less total combat phase ship " +
RECOVERY_COST +
", your fleet's total is %s",
209 "" + (
int)Math.round(op));
211 info.addPara(
indent +
"Maximum at %s or less total combat phase ship " +
RECOVERY_COST +
" for fleet",
220 String opStr =
"points";
221 if (op == 1) opStr =
"point";
222 info.addPara(
indent +
"Maximum at %s or less total combat phase ship ordnance points in fleet, your fleet has %s " + opStr,
225 "" + (
int)Math.round(op));
227 info.addPara(
indent +
"Maximum at %s or less total combat phase ship ordnance points in fleet",
237 info.addPara(
indent +
"Maximum at %s or less total automated ship points*, your fleet's total is %s ",
240 "" + (
int)Math.round(op));
242 info.addPara(
indent +
"Maximum at %s or less total automated ship points* for fleet",
250 String opStr =
"points";
251 if (op == 1) opStr =
"point";
252 info.addPara(
indent +
"Maximum at %s or less total automated ship points* in fleet, your fleet has %s " + opStr,
255 "" + (
int)Math.round(op));
257 info.addPara(
indent +
"Maximum at %s or less total automated ship points* in fleet",
267 info.addPara(
indent +
"Maximum at %s or less total " +
RECOVERY_COST +
" for ships with Militarized Subsystems, your fleet's total is %s",
270 "" + (
int)Math.round(op));
272 info.addPara(
indent +
"Maximum at %s or less total " +
RECOVERY_COST +
" for ships with Militarized Subsystems for fleet",
280 String opStr =
"points";
281 if (op == 1) opStr =
"point";
282 info.addPara(
indent +
"Maximum at %s or less total ordnance points for ships with Militarized Subsystems, your fleet has %s " + opStr,
285 "" + (
int)Math.round(op));
287 info.addPara(
indent +
"Maximum at %s or less total ordnance points for ships with Militarized Subsystems",
295 String key,
float maxBonus, ThresholdBonusType type) {
301 String key,
float maxBonus, ThresholdBonusType type) {
305 if (data ==
null)
return maxBonus;
306 if (cStats.getFleet() ==
null)
return maxBonus;
308 Float bonus = (Float) data.getCacheClearedOnSync().get(key);
309 if (bonus !=
null)
return bonus;
311 float currValue = 0f;
312 float threshold = 1f;
314 if (type == ThresholdBonusType.FIGHTER_BAYS) {
317 }
else if (type == ThresholdBonusType.OP) {
320 }
else if (type == ThresholdBonusType.OP_LOW) {
323 }
else if (type == ThresholdBonusType.OP_ALL_LOW) {
326 }
else if (type == ThresholdBonusType.OP_ALL) {
329 }
else if (type == ThresholdBonusType.MILITARIZED_OP) {
332 }
else if (type == ThresholdBonusType.PHASE_OP) {
335 }
else if (type == ThresholdBonusType.AUTOMATED_POINTS) {
342 data.getCacheClearedOnSync().put(key, bonus);
353 final MutableCharacterStatsAPI stats =
Global.
getSector().getPlayerStats();
354 FleetTotalItem item =
new FleetTotalItem();
355 item.label =
"Total ordnance points";
357 item.label =
"All ships";
359 item.value =
"" + (int)
getTotalOP(fleet.getFleetData(), stats);
363 public void addDescription(TooltipMakerAPI tooltip,
boolean expanded, Object tooltipParam) {
365 tooltip.addPara(
"The total deployment points of all the ships in your fleet.", 0f);
367 public List<FleetMemberPointContrib> getContributors() {
377 final MutableCharacterStatsAPI stats =
Global.
getSector().getPlayerStats();
378 FleetTotalItem item =
new FleetTotalItem();
379 item.label =
"Combat ship ordnance points";
381 item.label =
"Combat ships";
384 item.sortOrder = 100;
387 public void addDescription(TooltipMakerAPI tooltip,
boolean expanded, Object tooltipParam) {
389 tooltip.addPara(
"The total deployment points of all the combat ships in your fleet.", 0f);
391 public List<FleetMemberPointContrib> getContributors() {
401 final MutableCharacterStatsAPI stats =
Global.
getSector().getPlayerStats();
402 FleetTotalItem item =
new FleetTotalItem();
403 item.label =
"Automated ships";
405 item.sortOrder = 350;
408 public void addDescription(TooltipMakerAPI tooltip,
boolean expanded, Object tooltipParam) {
410 tooltip.addPara(
"The total deployment points of all the automated ships in your fleet, "
411 +
"with additional points for ships controlled by AI cores.", 0f);
413 public List<FleetMemberPointContrib> getContributors() {
423 final MutableCharacterStatsAPI stats =
Global.
getSector().getPlayerStats();
424 FleetTotalItem item =
new FleetTotalItem();
425 item.label =
"Phase ship ordnance points";
427 item.label =
"Phase ships";
430 item.sortOrder = 200;
433 public void addDescription(TooltipMakerAPI tooltip,
boolean expanded, Object tooltipParam) {
435 tooltip.addPara(
"The total deployment points of all the non-civilian phase ships in your fleet.", 0f);
437 public List<FleetMemberPointContrib> getContributors() {
446 final MutableCharacterStatsAPI stats =
Global.
getSector().getPlayerStats();
447 FleetTotalItem item =
new FleetTotalItem();
448 item.label =
"Militarized ship ordnance points";
450 item.label =
"Militarized ships";
453 item.sortOrder = 300;
456 public void addDescription(TooltipMakerAPI tooltip,
boolean expanded, Object tooltipParam) {
458 tooltip.addPara(
"The total deployment points of all the ships in your fleet that have "
459 +
"the \"Militarized Subsystems\" hullmod.", 0f);
461 public List<FleetMemberPointContrib> getContributors() {
471 FleetTotalItem item =
new FleetTotalItem();
472 item.label =
"Fighter bays";
474 item.sortOrder = 400;
477 public void addDescription(TooltipMakerAPI tooltip,
boolean expanded, Object tooltipParam) {
479 tooltip.addPara(
"The total number of fighter bays in your fleet. Both empty and filled "
480 +
"fighter bays are counted. Built-in fighter bays can be removed from a ship by "
481 +
"installing the \"Converted Fighter Bay\" hullmod.", 0f);
483 public List<FleetMemberPointContrib> getContributors() {
492 void addDescription(TooltipMakerAPI tooltip,
boolean expanded, Object tooltipParam);
496 return new BaseTooltipCreator() {
497 public float getTooltipWidth(Object tooltipParam) {
500 @SuppressWarnings(
"unchecked")
501 public void createTooltip(TooltipMakerAPI tooltip,
boolean expanded, Object tooltipParam) {
507 tooltip.addPara(
"Certain skills will have reduced effects if this value exceeds a "
508 +
"skill-specific threshold; see the specific skill for details. Mothballed "
509 +
"ships are not counted towards the total.", opad);
511 tooltip.addPara(
"Skills using this value:", opad);
512 tooltip.setBulletedListMode(BaseIntelPlugin.INDENT);
513 List<SkillLevelAPI> skills = (List<SkillLevelAPI>) tooltipParam;
514 Set<SkillLevelAPI> seen =
new HashSet<MutableCharacterStatsAPI.SkillLevelAPI>();
516 float initPad = opad;
518 for (SkillLevelAPI skill : skills) {
519 if (seen.contains(skill))
continue;
521 String label = skill.getSkill().getName() +
" (" + skill.getSkill().getGoverningAptitudeName() +
")";
522 label = skill.getSkill().getGoverningAptitudeName() +
" - " + skill.getSkill().getName();
523 tooltip.addPara(label,
524 skill.getSkill().getGoverningAptitudeColor(), initPad);
527 tooltip.setBulletedListMode(
null);
530 Collections.sort(members,
new Comparator<FleetMemberPointContrib>() {
531 public int compare(FleetMemberPointContrib o1, FleetMemberPointContrib o2) {
532 return o2.points - o1.points;
536 tooltip.addPara(
"Ships contributing to this value:", opad);
539 if (members.isEmpty()) {
540 tooltip.setBulletedListMode(BaseIntelPlugin.INDENT);
541 tooltip.addPara(
"None", initPad);
542 tooltip.setBulletedListMode(
null);
544 float gridWidth = 450f;
546 tooltip.beginGridFlipped(gridWidth, 1, 40f, opad);
549 if (members.size() == max + 1) {
550 max = members.size();
552 for (FleetMemberPointContrib member : members) {
557 tooltip.addToGrid(0, i++, label,
"+" + member.points);
560 tooltip.addGrid(opad);
561 if (members.size() > max) {
562 tooltip.addPara(
"And %s other ships with a smaller contribution.", opad,
563 Misc.getHighlightColor(),
"" + (members.size() - max));
572 if (!member.isFighterWing()) {
573 str += member.getShipName() +
", ";
574 str += member.getHullSpec().getHullNameWithDashClass();
576 str += member.getVariant().getFullDesignationWithHullName();
578 if (member.isMothballed()) {
579 str +=
" (mothballed)";
586 float bonus = maxBonus * threshold / Math.max(value, threshold);
590 float bonus = maxBonus * threshold / Math.max(value, threshold);
591 if (bonus > 0 && bonus < 1) bonus = 1;
593 if (bonus < maxBonus) {
594 bonus = Math.min(bonus, maxBonus - 1f);
596 bonus = (float) Math.round(bonus);
602 if (stats ==
null || stats.getFleetMember() ==
null)
return false;
606 if (member ==
null)
return false;
607 MutableShipStatsAPI stats = member.getStats();
608 return stats !=
null && stats.getVariant() !=
null &&
609 stats.getVariant().hasHullMod(HullMods.MILITARIZED_SUBSYSTEMS);
612 public static boolean isCivilian(MutableShipStatsAPI stats) {
613 if (stats ==
null || stats.getFleetMember() ==
null)
return false;
618 if (member ==
null)
return false;
619 MutableShipStatsAPI stats = member.getStats();
620 return stats !=
null && stats.getVariant() !=
null &&
621 ((stats.getVariant().hasHullMod(HullMods.CIVGRADE) &&
622 !stats.getVariant().hasHullMod(HullMods.MILITARIZED_SUBSYSTEMS)) ||
623 (!stats.getVariant().hasHullMod(HullMods.CIVGRADE) &&
624 stats.getVariant().getHullSpec().getHints().contains(ShipTypeHints.CIVILIAN)));
629 if (stats ==
null || stats.getFleetMember() ==
null)
return false;
634 if (member ==
null)
return false;
635 MutableShipStatsAPI stats = member.getStats();
636 return stats !=
null && stats.getNumFighterBays().getModifiedInt() > 0;
646 protected static float getPoints(FleetMemberAPI member, MutableCharacterStatsAPI stats) {
648 return member.getDeploymentPointsCost();
650 return member.getHullSpec().getOrdnancePoints(stats);
653 public static class FleetMemberPointContrib {
654 public FleetMemberAPI member;
656 public FleetMemberPointContrib(FleetMemberAPI member,
int points) {
658 this.member = member;
659 this.points = points;
664 public static float getTotalOP(FleetDataAPI data, MutableCharacterStatsAPI stats) {
666 for (FleetMemberAPI curr : data.getMembersListCopy()) {
667 if (curr.isMothballed())
continue;
670 return Math.round(op);
673 public static List<FleetMemberPointContrib>
getTotalOPDetail(FleetDataAPI data, MutableCharacterStatsAPI stats) {
675 for (FleetMemberAPI curr : data.getMembersListCopy()) {
676 if (curr.isMothballed())
continue;
677 int pts = (int) Math.round(
getPoints(curr, stats));
678 result.add(
new FleetMemberPointContrib(curr, pts));
685 for (FleetMemberAPI curr : data.getMembersListCopy()) {
686 if (curr.isMothballed())
continue;
690 return Math.round(op);
695 for (FleetMemberAPI curr : data.getMembersListCopy()) {
696 if (curr.isMothballed())
continue;
698 int pts = (int) Math.round(
getPoints(curr, stats));
699 result.add(
new FleetMemberPointContrib(curr, pts));
704 public static float getPhaseOP(FleetDataAPI data, MutableCharacterStatsAPI stats) {
706 for (FleetMemberAPI curr : data.getMembersListCopy()) {
707 if (curr.isMothballed())
continue;
708 if (curr.isPhaseShip()) {
713 return Math.round(op);
716 public static List<FleetMemberPointContrib>
getPhaseOPDetail(FleetDataAPI data, MutableCharacterStatsAPI stats) {
718 for (FleetMemberAPI curr : data.getMembersListCopy()) {
719 if (curr.isMothballed())
continue;
720 if (curr.isPhaseShip()) {
722 int pts = (int) Math.round(
getPoints(curr, stats));
723 result.add(
new FleetMemberPointContrib(curr, pts));
731 for (FleetMemberAPI curr : data.getMembersListCopy()) {
732 if (curr.isMothballed())
continue;
736 return Math.round(op);
741 for (FleetMemberAPI curr : data.getMembersListCopy()) {
742 if (curr.isMothballed())
continue;
744 int pts = (int) Math.round(
getPoints(curr, stats));
745 result.add(
new FleetMemberPointContrib(curr, pts));
753 for (FleetMemberAPI curr : data.getMembersListCopy()) {
754 if (curr.isMothballed())
continue;
763 bays += member.getNumFlightDecks();
764 if (member.getVariant().getModuleSlots() !=
null) {
765 for (String slotId : member.getVariant().getModuleSlots()) {
766 if (slotId ==
null)
continue;
767 ShipVariantAPI variant = member.getVariant().getModuleVariant(slotId);
768 if (variant ==
null)
continue;
769 bays += variant.getHullSpec().getFighterBays();
777 for (FleetMemberAPI curr : data.getMembersListCopy()) {
778 if (curr.isMothballed())
continue;
781 if (pts <= 0)
continue;
782 result.add(
new FleetMemberPointContrib(curr, pts));
789 for (FleetMemberAPI curr : data.getMembersListCopy()) {
790 if (curr.isMothballed())
continue;
791 if (!Misc.isAutomated(curr))
continue;
792 if (Automated.isAutomatedNoPenalty(curr))
continue;
795 points += curr.getCaptain().getMemoryWithoutUpdate().getFloat(AICoreOfficerPlugin.AUTOMATED_POINTS_VALUE);
796 mult = curr.getCaptain().getMemoryWithoutUpdate().getFloat(AICoreOfficerPlugin.AUTOMATED_POINTS_MULT);
797 if (mult == 0) mult = 1;
799 points += Math.round(
getPoints(curr, stats) * mult);
801 return Math.round(points);
806 for (FleetMemberAPI curr : data.getMembersListCopy()) {
807 if (curr.isMothballed())
continue;
808 if (!Misc.isAutomated(curr))
continue;
809 if (Automated.isAutomatedNoPenalty(curr))
continue;
811 int pts = (int) Math.round(
getPoints(curr, stats));
813 pts += (int) Math.round(curr.getCaptain().getMemoryWithoutUpdate().getFloat(AICoreOfficerPlugin.AUTOMATED_POINTS_VALUE));
814 mult = curr.getCaptain().getMemoryWithoutUpdate().getFloat(AICoreOfficerPlugin.AUTOMATED_POINTS_MULT);
815 if (mult == 0) mult = 1;
817 result.add(
new FleetMemberPointContrib(curr, Math.round(pts * mult)));
836 FleetMemberAPI member = stats.getFleetMember();
837 if (member ==
null)
return null;
838 PersonAPI commander = member.getFleetCommanderForStats();
839 if (commander ==
null) {
840 boolean orig =
false;
841 if (member.getFleetData() !=
null) {
842 orig = member.getFleetData().isForceNoSync();
843 member.getFleetData().setForceNoSync(
true);
845 commander = member.getFleetCommander();
846 if (member.getFleetData() !=
null) {
847 member.getFleetData().setForceNoSync(orig);
850 if (commander !=
null) {
851 return commander.getStats();
863 FleetMemberAPI member = stats.getFleetMember();
864 if (member ==
null)
return null;
865 FleetDataAPI data = member.getFleetDataForStats();
866 if (data ==
null) data = member.getFleetData();
876 TooltipMakerAPI info,
float width) {
static GameState getCurrentState()
static SectorAPI getSector()
void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill, TooltipMakerAPI info, float width)
static FleetDataAPI getFleetData(MutableShipStatsAPI stats)
ScopeDescription getScopeDescription()
FleetTotalItem getCombatOPTotal()
static List< FleetMemberPointContrib > getAutomatedPointsDetail(FleetDataAPI data, MutableCharacterStatsAPI stats)
FleetTotalItem getFighterBaysTotal()
void addOPThresholdInfo(TooltipMakerAPI info, FleetDataAPI data, MutableCharacterStatsAPI cStats)
static MutableCharacterStatsAPI getCommanderStats(MutableShipStatsAPI stats)
static float AUTOMATED_POINTS_THRESHOLD
static String RECOVERY_COST
void addPhaseOPThresholdInfo(TooltipMakerAPI info, FleetDataAPI data, MutableCharacterStatsAPI cStats)
static float getTotalOP(FleetDataAPI data, MutableCharacterStatsAPI stats)
static float getPhaseOP(FleetDataAPI data, MutableCharacterStatsAPI stats)
static List< FleetMemberPointContrib > getPhaseOPDetail(FleetDataAPI data, MutableCharacterStatsAPI stats)
void addAutomatedThresholdInfo(TooltipMakerAPI info, FleetDataAPI data, MutableCharacterStatsAPI cStats)
static List< FleetMemberPointContrib > getMilitarizedOPDetail(FleetDataAPI data, MutableCharacterStatsAPI stats)
static boolean hasFighterBays(MutableShipStatsAPI stats)
static List< FleetMemberPointContrib > getTotalOPDetail(FleetDataAPI data, MutableCharacterStatsAPI stats)
static boolean isInCampaign()
static float getMilitarizedOP(FleetDataAPI data, MutableCharacterStatsAPI stats)
static String getValueLabelForMember(FleetMemberAPI member)
static float OP_LOW_THRESHOLD
static boolean isMilitarized(FleetMemberAPI member)
void init(MutableCharacterStatsAPI stats, SkillSpecAPI skill)
static float OP_ALL_LOW_THRESHOLD
static boolean isCivilian(MutableShipStatsAPI stats)
float computeAndCacheThresholdBonus(MutableShipStatsAPI stats, String key, float maxBonus, ThresholdBonusType type)
static float OP_ALL_THRESHOLD
TooltipCreator getTooltipCreator(final TooltipCreatorSkillEffectPlugin plugin)
float getThresholdBasedBonus(float maxBonus, float value, float threshold)
static float getNumFighterBays(FleetDataAPI data)
FleetTotalItem getOPTotal()
FleetTotalItem getPhaseOPTotal()
static List< FleetMemberPointContrib > getNumFighterBaysDetail(FleetDataAPI data)
static boolean USE_RECOVERY_COST
void addOPThresholdInfo(TooltipMakerAPI info, FleetDataAPI data, MutableCharacterStatsAPI cStats, float threshold)
float getThresholdBasedRoundedBonus(float maxBonus, float value, float threshold)
static float TOOLTIP_WIDTH
static boolean isCivilian(FleetMemberAPI member)
static boolean isMilitarized(MutableShipStatsAPI stats)
static float getTotalCombatOP(FleetDataAPI data, MutableCharacterStatsAPI stats)
FleetTotalItem getMilitarizedOPTotal()
static float OP_THRESHOLD
void addMilitarizedOPThresholdInfo(TooltipMakerAPI info, FleetDataAPI data, MutableCharacterStatsAPI cStats)
static float PHASE_OP_THRESHOLD
static float MILITARIZED_OP_THRESHOLD
static boolean hasFighterBays(FleetMemberAPI member)
static float getNumBaysIncludingModules(FleetMemberAPI member)
String getEffectPerLevelDescription()
void initElite(MutableCharacterStatsAPI stats, SkillSpecAPI skill)
boolean hasCustomDescription()
FleetTotalItem getAutomatedPointsTotal()
String getEffectDescription(float level)
void addOPThresholdAll(TooltipMakerAPI info, FleetDataAPI data, MutableCharacterStatsAPI cStats, float threshold)
float computeAndCacheThresholdBonus(FleetDataAPI data, MutableCharacterStatsAPI cStats, String key, float maxBonus, ThresholdBonusType type)
static float getPoints(FleetMemberAPI member, MutableCharacterStatsAPI stats)
static float getAutomatedPoints(FleetDataAPI data, MutableCharacterStatsAPI stats)
static float FIGHTER_BAYS_THRESHOLD
void addFighterBayThresholdInfo(TooltipMakerAPI info, FleetDataAPI data)
static List< FleetMemberPointContrib > getTotalCombatOPDetail(FleetDataAPI data, MutableCharacterStatsAPI stats)
void addDescription(TooltipMakerAPI tooltip, boolean expanded, Object tooltipParam)
List< FleetMemberPointContrib > getContributors()