001package com.fs.starfarer.api.impl.campaign.skills; 002 003import java.awt.Color; 004 005import com.fs.starfarer.api.Global; 006import com.fs.starfarer.api.campaign.FleetDataAPI; 007import com.fs.starfarer.api.characters.CharacterStatsSkillEffect; 008import com.fs.starfarer.api.characters.FleetStatsSkillEffect; 009import com.fs.starfarer.api.characters.FleetTotalItem; 010import com.fs.starfarer.api.characters.FleetTotalSource; 011import com.fs.starfarer.api.characters.MutableCharacterStatsAPI; 012import com.fs.starfarer.api.characters.ShipSkillEffect; 013import com.fs.starfarer.api.characters.SkillSpecAPI; 014import com.fs.starfarer.api.combat.MutableShipStatsAPI; 015import com.fs.starfarer.api.combat.MutableStat.StatMod; 016import com.fs.starfarer.api.combat.ShipAPI.HullSize; 017import com.fs.starfarer.api.combat.StatBonus; 018import com.fs.starfarer.api.fleet.FleetMemberAPI; 019import com.fs.starfarer.api.fleet.MutableFleetStatsAPI; 020import com.fs.starfarer.api.impl.campaign.ids.Stats; 021import com.fs.starfarer.api.ui.TooltipMakerAPI; 022import com.fs.starfarer.api.util.Misc; 023 024public class ContainmentProcedures { 025 026// public static final float CR_MALFUNCTION_RANGE_MULT = 0.5f; 027 //public static final float DMOD_EFFECT_MULT = 0.5f; 028 029 public static float FUEL_PROD_BONUS = 1f; 030 public static float CREW_LOSS_REDUCTION = 50f; 031 public static float FUEL_SALVAGE_BONUS = 25f; 032 public static float FUEL_USE_REDUCTION_MAX_PERCENT = 25; 033 public static float FUEL_USE_REDUCTION_MAX_FUEL = 25; 034 035 036 public static class Level1 extends BaseSkillEffectDescription implements ShipSkillEffect, FleetTotalSource { 037 038 public FleetTotalItem getFleetTotalItem() { 039 return getOPTotal(); 040 } 041 042 public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) { 043 float lossPercent = computeAndCacheThresholdBonus(stats, "sp_crewloss", CREW_LOSS_REDUCTION, ThresholdBonusType.OP_ALL); 044 stats.getCrewLossMult().modifyMult(id, 1f - (lossPercent * 0.01f)); 045 } 046 047 public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) { 048 stats.getCrewLossMult().unmodify(id); 049 } 050 051 public String getEffectDescription(float level) { 052 return null; 053 } 054 055 public void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill, 056 TooltipMakerAPI info, float width) { 057 init(stats, skill); 058 059 //info.addSpacer(5f); 060 FleetDataAPI data = getFleetData(null); 061 float damBonus = computeAndCacheThresholdBonus(data, stats, "sp_crewloss", CREW_LOSS_REDUCTION, ThresholdBonusType.OP_ALL); 062 063 info.addPara("-%s crew lost due to hull damage in combat (maximum: %s)", 0f, hc, hc, 064 "" + (int) damBonus + "%", 065 "" + (int) CREW_LOSS_REDUCTION + "%"); 066 addOPThresholdAll(info, data, stats, OP_ALL_THRESHOLD); 067 068 } 069 070 public ScopeDescription getScopeDescription() { 071 return ScopeDescription.ALL_SHIPS; 072 } 073 } 074 075 public static class Level2 implements FleetStatsSkillEffect { 076 public void apply(MutableFleetStatsAPI stats, String id, float level) { 077 stats.getDynamic().getStat(Stats.EMERGENCY_BURN_CR_MULT).modifyMult(id, 0f); 078 } 079 080 public void unapply(MutableFleetStatsAPI stats, String id) { 081 stats.getDynamic().getStat(Stats.EMERGENCY_BURN_CR_MULT).unmodify(id); 082 } 083 084 public String getEffectDescription(float level) { 085 return "The \"Emergency Burn\" ability no longer reduces combat readiness"; 086 } 087 088 public String getEffectPerLevelDescription() { 089 return null; 090 } 091 092 public ScopeDescription getScopeDescription() { 093 return ScopeDescription.FLEET; 094 } 095 } 096 097 public static class Level3 implements FleetStatsSkillEffect { 098 public void apply(MutableFleetStatsAPI stats, String id, float level) { 099 stats.getDynamic().getStat(Stats.FUEL_SALVAGE_VALUE_MULT_FLEET).modifyFlat(id, FUEL_SALVAGE_BONUS * 0.01f); 100 } 101 102 public void unapply(MutableFleetStatsAPI stats, String id) { 103 stats.getDynamic().getStat(Stats.FUEL_SALVAGE_VALUE_MULT_FLEET).unmodify(id); 104 } 105 106 public String getEffectDescription(float level) { 107 float max = 0f; 108 max += FUEL_SALVAGE_BONUS; 109 return "+" + (int) max + "% fuel salvaged"; 110 } 111 112 public String getEffectPerLevelDescription() { 113 return null; 114 } 115 116 public ScopeDescription getScopeDescription() { 117 return ScopeDescription.FLEET; 118 } 119 } 120 121 public static String FUEL_EFFECT_ID = "sp_fuel_use_mod"; 122 public static class Level4 extends BaseSkillEffectDescription implements ShipSkillEffect { 123 public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) { 124 id = FUEL_EFFECT_ID; 125 float useMult = getFuelUseMult(id, getFleetData(stats)); 126 stats.getFuelUseMod().modifyMult(id, useMult); 127 } 128 129 public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) { 130 id = FUEL_EFFECT_ID; 131 stats.getFuelUseMod().unmodifyMult(id); 132 } 133 134 public String getEffectDescription(float level) { 135 return null; 136 } 137 138 protected float getFuelUseBase(String id, FleetDataAPI data) { 139 if (data == null) return 0f; 140 141 float fuelUse = 0; 142 for (FleetMemberAPI curr : data.getMembersListCopy()) { 143 StatBonus stat = curr.getStats().getFuelUseMod(); 144 StatMod mod = stat.getMultBonus(id); 145 if (mod != null) { 146 stat.unmodifyMult(mod.source); 147 } 148 fuelUse += curr.getFuelUse(); 149 if (mod != null) { 150 stat.modifyMult(mod.source, mod.value, mod.desc); 151 } 152 } 153 return fuelUse; 154 } 155 156 protected float getFuelUseMult(String id, FleetDataAPI data) { 157 if (data == null) return 0f; 158 159 String key = "conproc1"; 160 Float bonus = (Float) data.getCacheClearedOnSync().get(key); 161 if (bonus != null) return bonus; 162 163 float fuelUse = getFuelUseBase(id, data); 164 165 float useMult = 0f; 166 167 if (fuelUse > 0) { 168 float maxReduced = Math.min(fuelUse * (FUEL_USE_REDUCTION_MAX_PERCENT * 0.01f), 169 FUEL_USE_REDUCTION_MAX_FUEL); 170 useMult = 1f - maxReduced / fuelUse; 171 //useMult = Math.round(useMult * 100f) / 100f; 172 } 173 174 data.getCacheClearedOnSync().put(key, useMult); 175 return useMult; 176 } 177 178 public void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill, 179 TooltipMakerAPI info, float width) { 180 init(stats, skill); 181// FUEL_USE_REDUCTION_MAX_PERCENT = 25; 182// FUEL_USE_REDUCTION_MAX_FUEL = 20; 183 184 info.addSpacer(5f); 185 info.addPara("Reduces fuel consumption by %s or %s units, whichever is lower", 186 0f, hc, hc, 187 "" + (int) FUEL_USE_REDUCTION_MAX_PERCENT + "%", 188 "" + (int) FUEL_USE_REDUCTION_MAX_FUEL 189 ); 190 191 if (isInCampaign()) { 192 FleetDataAPI data = Global.getSector().getPlayerFleet().getFleetData(); 193 String id = FUEL_EFFECT_ID; 194 float fuelUse = getFuelUseBase(id, data); 195 float useMult = getFuelUseMult(id, data); 196 197 float reduction = fuelUse * (1f - useMult); 198 199 boolean has = stats.getSkillLevel(skill.getId()) > 0; 200 String is = "is"; 201 if (!has) is = "would be"; 202 info.addPara(indent + "Your fleet has a base fuel consumption of %s, which " + is + " reduced by %s, or %s units", 203 0f, tc, hc, 204 "" + Misc.getRoundedValueMaxOneAfterDecimal(fuelUse), 205 "" + (int)(Math.round((1f - useMult) * 100f)) + "%", 206 "" + Misc.getRoundedValueMaxOneAfterDecimal(reduction) 207 ); 208 info.addSpacer(5f); 209 } 210// float opad = 10f; 211// Color c = Misc.getBasePlayerColor(); 212// info.addPara("Affects: %s", opad + 5f, Misc.getGrayColor(), c, "governed colony"); 213// info.addSpacer(opad); 214// info.addPara("+%s fuel production", 0f, hc, hc, 215// "" + (int) 1f); 216 } 217 218 public ScopeDescription getScopeDescription() { 219 return ScopeDescription.FLEET; 220 } 221 } 222 223 public static class Level5 extends BaseSkillEffectDescription implements CharacterStatsSkillEffect { 224 225 public void apply(MutableCharacterStatsAPI stats, String id, float level) { 226 stats.getDynamic().getMod(Stats.FUEL_SUPPLY_BONUS_MOD).modifyFlat(id, FUEL_PROD_BONUS); 227 } 228 229 public void unapply(MutableCharacterStatsAPI stats, String id) { 230 stats.getDynamic().getMod(Stats.FUEL_SUPPLY_BONUS_MOD).unmodifyFlat(id); 231 } 232 233 public void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill, 234 TooltipMakerAPI info, float width) { 235 init(stats, skill); 236 237 float opad = 10f; 238 Color c = Misc.getBasePlayerColor(); 239 info.addPara("Affects: %s", opad + 5f, Misc.getGrayColor(), c, "governed colony"); 240 info.addSpacer(opad); 241 info.addPara("+%s fuel production", 0f, hc, hc, 242 "" + (int) FUEL_PROD_BONUS); 243 } 244 245 public ScopeDescription getScopeDescription() { 246 return ScopeDescription.GOVERNED_OUTPOST; 247 } 248 } 249 250// public static class Level1 implements ShipSkillEffect { 251// public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) { 252// stats.getCrewLossMult().modifyMult(id, 1f - CREW_LOSS_REDUCTION / 100f); 253// } 254// 255// public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) { 256// stats.getCrewLossMult().unmodify(id); 257// } 258// 259// public String getEffectDescription(float level) { 260// //return "-" + (int)(CREW_LOSS_REDUCTION) + "% crew lost due to hull damage in combat"; 261// return "-" + (int)(CREW_LOSS_REDUCTION) + "% crew lost in combat and non-combat operations"; 262// } 263// 264// public String getEffectPerLevelDescription() { 265// return null; 266// } 267// 268// public ScopeDescription getScopeDescription() { 269// return ScopeDescription.ALL_SHIPS; 270// } 271// } 272// 273// public static class Level2 implements FleetStatsSkillEffect { 274// public void apply(MutableFleetStatsAPI stats, String id, float level) { 275// stats.getDynamic().getStat(Stats.NON_COMBAT_CREW_LOSS_MULT).modifyMult(id, 1f - CREW_LOSS_REDUCTION / 100f); 276// } 277// 278// public void unapply(MutableFleetStatsAPI stats, String id) { 279// stats.getDynamic().getStat(Stats.NON_COMBAT_CREW_LOSS_MULT).unmodify(id); 280// } 281// 282// public String getEffectDescription(float level) { 283// //return "-" + (int)(CREW_LOSS_REDUCTION) + "% crew lost in non-combat operations"; 284// return null; 285// } 286// 287// public String getEffectPerLevelDescription() { 288// return null; 289// } 290// 291// public ScopeDescription getScopeDescription() { 292// return ScopeDescription.FLEET; 293// } 294// } 295// 296// public static class Level3 implements ShipSkillEffect { 297// public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) { 298// //stats.getDynamic().getStat(Stats.HULL_DAMAGE_CR_LOSS).modifyMult(id, HULL_DAMAGE_CR_MULT); 299// stats.getDynamic().getStat(Stats.CORONA_EFFECT_MULT).modifyMult(id, CORONA_EFFECT_MULT); 300// } 301// 302// public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) { 303// //stats.getDynamic().getStat(Stats.HULL_DAMAGE_CR_LOSS).unmodify(id); 304// stats.getDynamic().getStat(Stats.CORONA_EFFECT_MULT).unmodify(id); 305// } 306// 307// public String getEffectDescription(float level) { 308// return "-" + (int) Math.round((1f - CORONA_EFFECT_MULT) * 100f) + "% combat readiness lost from being in star corona or similar terrain"; 309// } 310// 311// public String getEffectPerLevelDescription() { 312// return null; 313// } 314// 315// public ScopeDescription getScopeDescription() { 316// return ScopeDescription.ALL_SHIPS; 317// } 318// } 319 320// public static class Level2B implements ShipSkillEffect { 321// public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) { 322// stats.getDynamic().getStat(Stats.DMOD_EFFECT_MULT).modifyMult(id, DMOD_EFFECT_MULT); 323// } 324// 325// public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) { 326// stats.getDynamic().getStat(Stats.DMOD_EFFECT_MULT).unmodify(id); 327// } 328// 329// public String getEffectDescription(float level) { 330// return "Negative effects of \"lasting damage\" hullmods (d-mods) reduced by 50%"; 331// } 332// 333// public String getEffectPerLevelDescription() { 334// return null; 335// } 336// 337// public ScopeDescription getScopeDescription() { 338// return ScopeDescription.ALL_SHIPS; 339// } 340// } 341// 342// 343// public static class Level3 implements ShipSkillEffect { 344// 345// public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) { 346// stats.getDynamic().getStat(Stats.CR_MALFUNCION_RANGE).modifyMult(id, CR_MALFUNCTION_RANGE_MULT); 347// } 348// 349// public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) { 350// stats.getDynamic().getStat(Stats.CR_MALFUNCION_RANGE).unmodify(id); 351// } 352// 353// public String getEffectDescription(float level) { 354// return "" + (int) (100f * (1f - CR_MALFUNCTION_RANGE_MULT)) + "% reduced combat readiness range in which malfunctions and other negative effects occur"; 355// } 356// 357// public String getEffectPerLevelDescription() { 358// return null; 359// } 360// 361// public ScopeDescription getScopeDescription() { 362// return ScopeDescription.ALL_SHIPS; 363// } 364// } 365 366 367}