001package com.fs.starfarer.api.impl.campaign.skills; 002 003import java.awt.Color; 004 005import com.fs.starfarer.api.campaign.FleetDataAPI; 006import com.fs.starfarer.api.characters.DescriptionSkillEffect; 007import com.fs.starfarer.api.characters.FleetTotalItem; 008import com.fs.starfarer.api.characters.FleetTotalSource; 009import com.fs.starfarer.api.characters.MutableCharacterStatsAPI; 010import com.fs.starfarer.api.characters.ShipSkillEffect; 011import com.fs.starfarer.api.characters.SkillSpecAPI; 012import com.fs.starfarer.api.combat.MutableShipStatsAPI; 013import com.fs.starfarer.api.combat.ShipAPI; 014import com.fs.starfarer.api.combat.ShipAPI.HullSize; 015import com.fs.starfarer.api.fleet.FleetMemberAPI; 016import com.fs.starfarer.api.impl.campaign.ids.Stats; 017import com.fs.starfarer.api.ui.TooltipMakerAPI; 018 019public class PhaseCorps { 020 021 //public static float PHASE_CLOAK_COOLDOWN_REDUCTION = 25f; 022 //public static float FLUX_UPKEEP_REDUCTION = 30f; 023 public static float PHASE_SPEED_BONUS = 50f; 024 025 public static float PEAK_TIME_BONUS = 180f; 026 027 //public static float PHASE_FIELD_BONUS_PERCENT = 50f; 028 public static float PHASE_SHIP_SENSOR_BONUS_PERCENT = 100f; 029 030 031 public static boolean isPhaseAndOfficer(MutableShipStatsAPI stats) { 032 if (stats.getEntity() instanceof ShipAPI) { 033 ShipAPI ship = (ShipAPI) stats.getEntity(); 034 if (!ship.getHullSpec().isPhase()) return false; 035 return !ship.getCaptain().isDefault(); 036 } else { 037 FleetMemberAPI member = stats.getFleetMember(); 038 if (member == null) return false; 039 if (!member.isPhaseShip()) return false; 040 return !member.getCaptain().isDefault(); 041 } 042 } 043 public static boolean isPhase(MutableShipStatsAPI stats) { 044 FleetMemberAPI member = stats.getFleetMember(); 045 if (member == null) return false; 046 return member.isPhaseShip(); 047 } 048 049 public static class Level0 implements DescriptionSkillEffect { 050 public String getString() { 051 return "\n*The sensor strength of phase ships also contributes to the fleetwide stealth bonus granted by the Phase Field hullmod."; 052 } 053 public Color[] getHighlightColors() { 054 return null; 055 } 056 public String[] getHighlights() { 057 return null; 058 } 059 public Color getTextColor() { 060 return null; 061 } 062 } 063 064// public static class Level1 implements ShipSkillEffect { 065// 066// public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) { 067// if (isPhaseAndOfficer(stats)) { 068// stats.getPhaseCloakUpkeepCostBonus().modifyMult(id, 1f - FLUX_UPKEEP_REDUCTION / 100f); 069// } 070// } 071// 072// public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) { 073// stats.getPhaseCloakUpkeepCostBonus().unmodifyMult(id); 074// } 075// 076// public String getEffectDescription(float level) { 077// return "+" + (int)(FLUX_UPKEEP_REDUCTION) + "% flux generated by active phase cloak"; 078// } 079// 080// public String getEffectPerLevelDescription() { 081// return null; 082// } 083// 084// public ScopeDescription getScopeDescription() { 085// return ScopeDescription.PILOTED_SHIP; 086// } 087// } 088// 089// public static class Level2 implements ShipSkillEffect { 090// public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) { 091// if (isPhaseAndOfficer(stats)) { 092// stats.getPeakCRDuration().modifyFlat(id, PEAK_TIME_BONUS); 093// } 094// } 095// 096// public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) { 097// stats.getPeakCRDuration().unmodifyFlat(id); 098// } 099// 100// public String getEffectDescription(float level) { 101// return "+" + (int) PEAK_TIME_BONUS + " seconds peak operating time"; 102// } 103// 104// public String getEffectPerLevelDescription() { 105// return null; 106// } 107// 108// public ScopeDescription getScopeDescription() { 109// return ScopeDescription.PILOTED_SHIP; 110// } 111// } 112 113 114 115 public static class Level3 extends BaseSkillEffectDescription implements ShipSkillEffect, FleetTotalSource { 116 117 public FleetTotalItem getFleetTotalItem() { 118 return getPhaseOPTotal(); 119 } 120 121 public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) { 122 //stats.getPhaseCloakUpkeepCostBonus().modifyMult(id, 1f - PHASE_CLOAK_COOLDOWN_REDUCTION / 100f); 123 if (isPhase(stats) && !isCivilian(stats)) { 124 //float upkeepBonus = computeAndCacheThresholdBonus(stats, "pc_upkeep", FLUX_UPKEEP_REDUCTION, ThresholdBonusType.PHASE_OP); 125 float peakBonus = computeAndCacheThresholdBonus(stats, "pc_peak", PEAK_TIME_BONUS, ThresholdBonusType.PHASE_OP); 126 //stats.getPhaseCloakUpkeepCostBonus().modifyMult(id, 1f - upkeepBonus / 100f); 127 stats.getPeakCRDuration().modifyFlat(id, peakBonus); 128 129 float sensorBonus = computeAndCacheThresholdBonus(stats, "pc_sensor", PHASE_SHIP_SENSOR_BONUS_PERCENT, ThresholdBonusType.PHASE_OP); 130 stats.getSensorStrength().modifyPercent(id, sensorBonus); 131 132 float speedBonus = computeAndCacheThresholdBonus(stats, "pc_speed", PHASE_SPEED_BONUS, ThresholdBonusType.PHASE_OP); 133 stats.getDynamic().getMod(Stats.PHASE_CLOAK_SPEED_MOD).modifyFlat(id, speedBonus); 134 stats.getDynamic().getMod(Stats.PHASE_CLOAK_ACCEL_MOD).modifyFlat(id, speedBonus); 135 } 136 } 137 138 public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) { 139 stats.getPeakCRDuration().unmodifyFlat(id); 140 stats.getSensorStrength().unmodifyPercent(id); 141 stats.getDynamic().getMod(Stats.PHASE_CLOAK_SPEED_MOD).unmodifyFlat(id); 142 stats.getDynamic().getMod(Stats.PHASE_CLOAK_ACCEL_MOD).unmodifyFlat(id); 143 } 144 145 public String getEffectDescription(float level) { 146 return null; 147 } 148 149// float op = getTotalOP(data, cStats); 150// bonus = getThresholdBasedRoundedBonus(DISSIPATION_PERCENT, op, OP_THRESHOLD); 151// 152// float op = getTotalOP(data, cStats); 153// bonus = getThresholdBasedRoundedBonus(CAPACITY_PERCENT, op, FIGHTER_BAYS_THRESHOLD); 154 155 156 public void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill, 157 TooltipMakerAPI info, float width) { 158 init(stats, skill); 159 160 FleetDataAPI data = getFleetData(null); 161 162 //float upkeepBonus = computeAndCacheThresholdBonus(data, stats, "pc_upkeep", FLUX_UPKEEP_REDUCTION, ThresholdBonusType.PHASE_OP); 163 float peakBonus = computeAndCacheThresholdBonus(data, stats, "pc_peak", PEAK_TIME_BONUS, ThresholdBonusType.PHASE_OP); 164 float sensorBonus = computeAndCacheThresholdBonus(data, stats, "pc_sensor", PHASE_SHIP_SENSOR_BONUS_PERCENT, ThresholdBonusType.PHASE_OP); 165 float speedBonus = computeAndCacheThresholdBonus(data, stats, "pc_speed", PHASE_SPEED_BONUS, ThresholdBonusType.PHASE_OP); 166// info.addPara("-%s flux generated by active phase cloak for combat phase ships (maximum: %s)", 0f, hc, hc, 167// "" + (int) upkeepBonus + "%", 168// "" + (int) FLUX_UPKEEP_REDUCTION + "%"); 169// info.addPara("-%s phase cloak cooldown", 0f, hc, hc, 170// "" + (int) PHASE_CLOAK_COOLDOWN_REDUCTION + "%"); 171 172// addFighterBayThresholdInfo(info, data); 173 info.addSpacer(5f); 174 175 info.addPara("+%s seconds peak operating time for combat phase ships (maximum: %s)", 0f, hc, hc, 176 "" + (int) peakBonus, 177 "" + (int) PEAK_TIME_BONUS); 178 info.addPara("+%s top speed and acceleration while phase cloak active (maximum: %s)", 0f, hc, hc, 179 "" + (int) speedBonus + "%", 180 "" + (int) PHASE_SPEED_BONUS + "%"); 181 info.addPara("+%s to sensor strength of combat phase ships* (maximum: %s)", 0f, hc, hc, 182 "" + (int) sensorBonus + "%", 183 "" + (int) PHASE_SHIP_SENSOR_BONUS_PERCENT + "%"); 184 addPhaseOPThresholdInfo(info, data, stats); 185 186 //info.addSpacer(5f); 187 } 188 189 public ScopeDescription getScopeDescription() { 190 return ScopeDescription.ALL_SHIPS; 191 } 192 } 193 194// public static class Level4 extends BaseSkillEffectDescription implements ShipSkillEffect, FleetTotalSource { 195// 196// public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) { 197// if (isPhase(stats)) { 198// stats.getSensorStrength().modifyPercent(id, PHASE_SHIP_SENSOR_BONUS_PERCENT); 199// } 200// } 201// 202// public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) { 203// stats.getSensorStrength().unmodifyPercent(id); 204// } 205// 206// public void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill, 207// TooltipMakerAPI info, float width) { 208// init(stats, skill); 209// float opad = 10f; 210// Color c = Misc.getBasePlayerColor(); 211// info.addPara("Affects: %s", opad + 5f, Misc.getGrayColor(), c, "all phase ships"); 212// info.addSpacer(opad); 213// info.addPara("+%s to sensor strength of phase ships", 0f, hc, hc, 214// "" + (int) PHASE_SHIP_SENSOR_BONUS_PERCENT + "%"); 215// } 216// 217// public ScopeDescription getScopeDescription() { 218// return ScopeDescription.CUSTOM; 219// } 220// 221// public FleetTotalItem getFleetTotalItem() { 222// return null; 223// } 224// } 225 226// public static class Level4 extends BaseSkillEffectDescription implements FleetStatsSkillEffect { 227// public void apply(MutableFleetStatsAPI stats, String id, float level) { 228// StatMod phaseFieldMod = stats.getDetectedRangeMod().getFlatBonus(PhaseField.MOD_KEY); 229// if (phaseFieldMod != null) { 230// int value = (int) Math.round(phaseFieldMod.value * PHASE_FIELD_BONUS_PERCENT / 100f); 231// if (value < 0) { 232// stats.getDetectedRangeMod().modifyFlat(id, value, "Phase corps"); 233// } 234// } 235// } 236// 237// public void unapply(MutableFleetStatsAPI stats, String id) { 238//// stats.getDetectedRangeMod().unmodifyFlat(id); 239// } 240// 241// public void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill, 242// TooltipMakerAPI info, float width) { 243// init(stats, skill); 244// float opad = 10f; 245// Color c = Misc.getBasePlayerColor(); 246// info.addPara("Affects: %s", opad + 5f, Misc.getGrayColor(), c, "fleet"); 247// info.addSpacer(opad); 248// info.addPara("+%s to fleetwide sensor profile reduction from phase field", 0f, hc, hc, 249// "" + (int) PHASE_FIELD_BONUS_PERCENT + "%"); 250// } 251// 252// public ScopeDescription getScopeDescription() { 253// return ScopeDescription.FLEET; 254// } 255// } 256 257}