001package com.fs.starfarer.api.impl.campaign.skills; 002 003import com.fs.starfarer.api.Global; 004import com.fs.starfarer.api.campaign.FleetDataAPI; 005import com.fs.starfarer.api.characters.CharacterStatsSkillEffect; 006import com.fs.starfarer.api.characters.FleetStatsSkillEffect; 007import com.fs.starfarer.api.characters.MutableCharacterStatsAPI; 008import com.fs.starfarer.api.characters.ShipSkillEffect; 009import com.fs.starfarer.api.characters.SkillSpecAPI; 010import com.fs.starfarer.api.combat.MutableShipStatsAPI; 011import com.fs.starfarer.api.combat.StatBonus; 012import com.fs.starfarer.api.combat.MutableStat.StatMod; 013import com.fs.starfarer.api.combat.ShipAPI.HullSize; 014import com.fs.starfarer.api.fleet.FleetMemberAPI; 015import com.fs.starfarer.api.fleet.MutableFleetStatsAPI; 016import com.fs.starfarer.api.impl.campaign.ids.Stats; 017import com.fs.starfarer.api.ui.TooltipMakerAPI; 018import com.fs.starfarer.api.util.Misc; 019 020public class Navigation { 021 022 public static float TERRAIN_PENALTY_REDUCTION = 30f; 023 public static float FUEL_USE_REDUCTION = 25; 024 //public static final float SUSTAINED_BURN_BONUS = 5; 025 public static float FLEET_BURN_BONUS = 1; 026 public static float SB_BURN_BONUS = 1; 027 028 public static float FUEL_USE_REDUCTION_MAX_PERCENT = 50; 029 public static float FUEL_USE_REDUCTION_MAX_FUEL = 25; 030 031 public static String FUEL_EFFECT_ID = "nav_fuel_use_mod"; 032 033 public static class Level4 extends BaseSkillEffectDescription implements ShipSkillEffect { 034 public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) { 035 id = FUEL_EFFECT_ID; 036 float useMult = getFuelUseMult(id, getFleetData(stats)); 037 stats.getFuelUseMod().modifyMult(id, useMult); 038 } 039 040 public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) { 041 id = FUEL_EFFECT_ID; 042 stats.getFuelUseMod().unmodifyMult(id); 043 } 044 045 public String getEffectDescription(float level) { 046 return null; 047 } 048 049 protected float getFuelUseBase(String id, FleetDataAPI data) { 050 if (data == null) return 0f; 051 052 float fuelUse = 0; 053 for (FleetMemberAPI curr : data.getMembersListCopy()) { 054 StatBonus stat = curr.getStats().getFuelUseMod(); 055 StatMod mod = stat.getMultBonus(id); 056 if (mod != null) { 057 stat.unmodifyMult(mod.source); 058 } 059 fuelUse += curr.getFuelUse(); 060 if (mod != null) { 061 stat.modifyMult(mod.source, mod.value, mod.desc); 062 } 063 } 064 return fuelUse; 065 } 066 067 protected float getFuelUseMult(String id, FleetDataAPI data) { 068 if (data == null) return 0f; 069 070 String key = "nav1"; 071 Float bonus = (Float) data.getCacheClearedOnSync().get(key); 072 if (bonus != null) return bonus; 073 074 float fuelUse = getFuelUseBase(id, data); 075 076 float useMult = 0f; 077 078 if (fuelUse > 0) { 079 float maxReduced = Math.min(fuelUse * (FUEL_USE_REDUCTION_MAX_PERCENT * 0.01f), 080 FUEL_USE_REDUCTION_MAX_FUEL); 081 useMult = 1f - maxReduced / fuelUse; 082 useMult = Math.round(useMult * 100f) / 100f; 083 } 084 085 data.getCacheClearedOnSync().put(key, useMult); 086 return useMult; 087 } 088 089 public void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill, 090 TooltipMakerAPI info, float width) { 091 init(stats, skill); 092 093 info.addPara("Reduces fuel consumption by %s or %s units, whichever is lower", 094 0f, hc, hc, 095 "" + (int) FUEL_USE_REDUCTION_MAX_PERCENT + "%", 096 "" + (int) FUEL_USE_REDUCTION_MAX_FUEL 097 ); 098 099 if (isInCampaign()) { 100 FleetDataAPI data = Global.getSector().getPlayerFleet().getFleetData(); 101 String id = FUEL_EFFECT_ID; 102 float fuelUse = getFuelUseBase(id, data); 103 float useMult = getFuelUseMult(id, data); 104 105 float reduction = fuelUse * (1f - useMult); 106 107 boolean has = stats.getSkillLevel(skill.getId()) > 0; 108 String is = "is"; 109 if (!has) is = "would be"; 110 info.addPara(indent + "Your fleet has a base fuel consumption of %s, which " + is + " reduced by %s, or %s units", 111 0f, tc, hc, 112 "" + Misc.getRoundedValueMaxOneAfterDecimal(fuelUse), 113 "" + (int)(Math.round((1f - useMult) * 100f)) + "%", 114 "" + Misc.getRoundedValueMaxOneAfterDecimal(reduction) 115 ); 116 info.addSpacer(5f); 117 } 118 } 119 120 public ScopeDescription getScopeDescription() { 121 return ScopeDescription.FLEET; 122 } 123 } 124 125 126 public static class Level1 implements CharacterStatsSkillEffect { 127 public void apply(MutableCharacterStatsAPI stats, String id, float level) { 128 stats.getDynamic().getStat(Stats.NAVIGATION_PENALTY_MULT).modifyFlat(id, 129 -0.01f * TERRAIN_PENALTY_REDUCTION); 130 } 131 132 public void unapply(MutableCharacterStatsAPI stats, String id) { 133 stats.getDynamic().getStat(Stats.NAVIGATION_PENALTY_MULT).unmodify(id); 134 } 135 136 public String getEffectDescription(float level) { 137 return "-" + (int) (TERRAIN_PENALTY_REDUCTION) + "% terrain movement penalty from all applicable terrain"; 138 } 139 140 public String getEffectPerLevelDescription() { 141 return null; 142 } 143 144 public ScopeDescription getScopeDescription() { 145 return ScopeDescription.FLEET; 146 } 147 } 148 149 public static class Level1B implements FleetStatsSkillEffect { 150 public void apply(MutableFleetStatsAPI stats, String id, float level) { 151 stats.getDynamic().getMod(Stats.CAN_SEE_NASCENT_POINTS).modifyFlat(id, 1); 152 } 153 154 public void unapply(MutableFleetStatsAPI stats, String id) { 155 stats.getDynamic().getMod(Stats.CAN_SEE_NASCENT_POINTS).unmodify(id); 156 } 157 158 public String getEffectDescription(float level) { 159 return "Can detect nascent gravity wells in hyperspace around star systems"; 160 } 161 162 public String getEffectPerLevelDescription() { 163 return null; 164 } 165 166 public ScopeDescription getScopeDescription() { 167 return ScopeDescription.FLEET; 168 } 169 } 170 171// public static class Level1B implements FleetStatsSkillEffect { 172// public void apply(MutableFleetStatsAPI stats, String id, float level) { 173// stats.getDynamic().getMod(Stats.CAN_SEE_NASCENT_POINTS).modifyFlat(id, 1); 174// } 175// 176// public void unapply(MutableFleetStatsAPI stats, String id) { 177// stats.getDynamic().getMod(Stats.CAN_SEE_NASCENT_POINTS).unmodify(id); 178// } 179// 180// public String getEffectDescription(float level) { 181// return "Can detect nascent gravity wells around star systems"; 182// } 183// 184// public String getEffectPerLevelDescription() { 185// return null; 186// } 187// 188// public ScopeDescription getScopeDescription() { 189// return ScopeDescription.FLEET; 190// } 191// } 192 193// public static class Level2 implements FleetStatsSkillEffect { 194// public void apply(MutableFleetStatsAPI stats, String id, float level) { 195// stats.getFuelUseHyperMult().modifyMult(id, 1f - FUEL_USE_REDUCTION / 100f); 196// stats.getFuelUseNormalMult().modifyMult(id, 1f - FUEL_USE_REDUCTION / 100f); 197// } 198// 199// public void unapply(MutableFleetStatsAPI stats, String id) { 200// stats.getFuelUseHyperMult().unmodify(id); 201// stats.getFuelUseNormalMult().unmodify(id); 202// } 203// 204// public String getEffectDescription(float level) { 205// return "-" + (int) FUEL_USE_REDUCTION + "% fuel consumption"; 206// } 207// 208// public String getEffectPerLevelDescription() { 209// return null; 210// } 211// 212// public ScopeDescription getScopeDescription() { 213// return ScopeDescription.FLEET; 214// } 215// } 216 217 public static class Level2 implements ShipSkillEffect { 218 public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) { 219 stats.getFuelUseMod().modifyMult(id, 1f - FUEL_USE_REDUCTION / 100f); 220 } 221 222 public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) { 223 stats.getFuelUseMod().unmodify(id); 224 } 225 226 public String getEffectDescription(float level) { 227 return "-" + (int) FUEL_USE_REDUCTION + "% fuel consumption"; 228 } 229 230 public String getEffectPerLevelDescription() { 231 return null; 232 } 233 234 public ScopeDescription getScopeDescription() { 235 return ScopeDescription.ALL_SHIPS; 236 } 237 } 238 239 240 public static class Level3A implements FleetStatsSkillEffect { 241 public void apply(MutableFleetStatsAPI stats, String id, float level) { 242 stats.getFleetwideMaxBurnMod().modifyFlat(id, FLEET_BURN_BONUS, "Navigation"); 243 } 244 245 public void unapply(MutableFleetStatsAPI stats, String id) { 246 stats.getFleetwideMaxBurnMod().unmodifyFlat(id); 247 } 248 249 public String getEffectDescription(float level) { 250 return "+" + (int) FLEET_BURN_BONUS + " maximum burn level"; 251 } 252 253 public String getEffectPerLevelDescription() { 254 return null; 255 } 256 257 public ScopeDescription getScopeDescription() { 258 return ScopeDescription.FLEET; 259 } 260 } 261 262 public static class Level3B implements FleetStatsSkillEffect { 263 public void apply(MutableFleetStatsAPI stats, String id, float level) { 264 stats.getDynamic().getMod(Stats.SUSTAINED_BURN_BONUS).modifyFlat(id, SB_BURN_BONUS); 265 } 266 267 public void unapply(MutableFleetStatsAPI stats, String id) { 268 stats.getDynamic().getMod(Stats.SUSTAINED_BURN_BONUS).unmodifyFlat(id); 269 } 270 271 public String getEffectDescription(float level) { 272 return "Increases the burn bonus of the \"Sustained Burn\" ability by " + (int) SB_BURN_BONUS; 273 } 274 275 public String getEffectPerLevelDescription() { 276 return null; 277 } 278 279 public ScopeDescription getScopeDescription() { 280 return ScopeDescription.FLEET; 281 } 282 } 283} 284 285 286