001package com.fs.starfarer.api.impl.campaign.skills; 002 003import com.fs.starfarer.api.campaign.FleetDataAPI; 004import com.fs.starfarer.api.characters.MutableCharacterStatsAPI; 005import com.fs.starfarer.api.characters.ShipSkillEffect; 006import com.fs.starfarer.api.characters.SkillSpecAPI; 007import com.fs.starfarer.api.combat.MutableShipStatsAPI; 008import com.fs.starfarer.api.combat.MutableStat.StatMod; 009import com.fs.starfarer.api.combat.ShipAPI.HullSize; 010import com.fs.starfarer.api.combat.StatBonus; 011import com.fs.starfarer.api.fleet.FleetMemberAPI; 012import com.fs.starfarer.api.ui.TooltipMakerAPI; 013 014public class BulkTransport { 015 016 public static float CARGO_CAPACITY_MAX_PERCENT = 50; 017 public static float CARGO_CAPACITY_THRESHOLD = 2000; 018 019 public static float FUEL_CAPACITY_MAX_PERCENT = 50; 020 public static float FUEL_CAPACITY_THRESHOLD = 2000; 021 022 public static float PERSONNEL_CAPACITY_MAX_PERCENT = 50; 023 public static float PERSONNEL_CAPACITY_THRESHOLD = 5000; 024 025 public static float BURN_BONUS = 2; 026 027 public static class Level4 extends BaseSkillEffectDescription implements ShipSkillEffect { 028 public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) { 029 if (isCivilian(stats)) { 030 stats.getMaxBurnLevel().modifyFlat(id, BURN_BONUS); 031 } 032 } 033 034 public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) { 035 stats.getMaxBurnLevel().unmodifyFlat(id); 036 } 037 038 @Override 039 public boolean hasCustomDescription() { 040 return false; 041 } 042 043 public String getEffectDescription(float level) { 044 return "Increases the burn level of all non-militarized civilian-grade ships by " + (int) BURN_BONUS; 045 } 046 047 public ScopeDescription getScopeDescription() { 048 return ScopeDescription.ALL_SHIPS; 049 } 050 } 051 052 public abstract static class BaseCapacityModifierEffect extends BaseSkillEffectDescription implements ShipSkillEffect { 053 protected abstract String getModifierId(); 054 protected abstract String getCacheKey(); 055 protected abstract String getCapacityString(); 056 protected abstract float getCapacity(FleetMemberAPI member); 057 protected abstract float getMaxPercent(); 058 protected abstract float getThreshold(); 059 protected abstract StatBonus getShipStat(MutableShipStatsAPI stats); 060 protected abstract boolean withSpacerAfter(); 061 062 public void apply(MutableShipStatsAPI stats, HullSize hullSize, String id, float level) { 063 id = getModifierId(); 064 float capBonus = getCapacityBonus(id, getFleetData(stats)); 065 getShipStat(stats).modifyMult(id, 1f + (capBonus / 100f)); 066 } 067 068 public void unapply(MutableShipStatsAPI stats, HullSize hullSize, String id) { 069 id = getModifierId(); 070 getShipStat(stats).unmodifyMult(id); 071 } 072 073 public String getEffectDescription(float level) { 074 return null; 075 } 076 077 protected float getCapacityBase(String id, FleetDataAPI data) { 078 if (data == null) return 0f; 079 080 float cap = 0; 081 for (FleetMemberAPI curr : data.getMembersListCopy()) { 082 cap += getCapacityBase(id, curr); 083 } 084 return cap; 085 } 086 087 protected float getCapacityBase(String id, FleetMemberAPI curr) { 088 StatBonus stat = getShipStat(curr.getStats()); 089 StatMod mod = stat.getMultBonus(id); 090 if (mod != null) { 091 stat.unmodifyMult(mod.source); 092 } 093 float cap = getCapacity(curr); 094 if (mod != null) { 095 stat.modifyMult(mod.source, mod.value, mod.desc); 096 } 097 return cap; 098 } 099 100 protected float getCapacityBonus(String id, FleetDataAPI data) { 101 if (data == null) return getMaxPercent(); 102 103 String key = getCacheKey(); 104 Float bonus = (Float) data.getCacheClearedOnSync().get(key); 105 if (bonus != null) return bonus; 106 107 float base = getCapacityBase(id, data); 108 109 bonus = getThresholdBasedRoundedBonus(getMaxPercent(), base, getThreshold()); 110 //float capMult = 0f; 111// if (base > 0) { 112// float addCapacity = Math.min(base * (getMaxPercent() * 0.01f), getMaxUnits()); 113// capMult = 1f + addCapacity / base; 114// capMult = Math.round(capMult * 100f) / 100f; 115// } 116 117 data.getCacheClearedOnSync().put(key, bonus); 118 return bonus; 119 } 120 121 public void createCustomDescription(MutableCharacterStatsAPI stats, SkillSpecAPI skill, 122 TooltipMakerAPI info, float width) { 123 init(stats, skill); 124 125// //info.addSpacer(5f); 126// info.addPara(getCapacityString() + " increased by %s or %s units, whichever is lower", 127// 0f, hc, hc, 128// "" + (int) getMaxPercent() + "%", 129// "" + (int) getThreshold() 130// ); 131 132 FleetDataAPI data = getFleetData(null); 133 float capBonus = getCapacityBonus(getModifierId(), data);; 134 135 info.addPara("+%s " + getCapacityString().toLowerCase() + " (maximum: %s)", 0f, hc, hc, 136 "" + (int)(Math.round(capBonus)) + "%", 137 "" + (int) getMaxPercent() + "%"); 138 139 140 if (isInCampaign()) { 141 float baseCap = getCapacityBase(getModifierId(), data); 142 info.addPara(indent + "Maximum at %s or less base " + getCapacityString().toLowerCase() + 143 " in fleet, your fleet has %s base " + getCapacityString().toLowerCase(), 144 0f, tc, hc, 145 "" + (int) getThreshold(), 146 "" + (int)Math.round(baseCap)); 147 } else { 148 info.addPara(indent + "Maximum at %s or less base " + getCapacityString().toLowerCase() + 149 " in fleet", 150 0f, tc, hc, 151 "" + (int) getThreshold()); 152 } 153 154 if (withSpacerAfter()) { 155 info.addSpacer(5f); 156 } 157 158// if (isInCampaign()) { 159// FleetDataAPI data = Global.getSector().getPlayerFleet().getFleetData(); 160// String id = getModifierId(); 161// float baseCap = getCapacityBase(id, data); 162// float capMult = getCapacityMult(id, data); 163// 164// float increase = baseCap * (capMult - 1f); 165// float actual = increase; 166// boolean approximate = false; 167// 168//// if (this instanceof Level2) { 169//// System.out.println("wefwefwe"); 170//// } 171// if (data != null) { 172// actual = 0f; 173// 174// for (FleetMemberAPI curr : data.getMembersListCopy()) { 175// float base = getCapacityBase(id, curr); 176// float add = (int)(base * capMult - base); 177// actual += add; 178// } 179// if (actual != increase) { 180// approximate = true; 181// } 182// } 183// 184// boolean has = stats.getSkillLevel(skill.getId()) > 0; 185// String is = "is"; 186// if (!has) is = "would be"; 187// String by = "by"; 188// String units = "%s units"; 189// if (approximate) { 190// //units = "approximately %s units"; 191// by = "by approximately"; 192// increase = actual; 193// } 194// info.addPara(indent + "Your fleet has a base " + getCapacityString().toLowerCase() + 195// " of %s, which " + is + " increased " + by + " %s, or " + units, 196// 0f, tc, hc, 197// "" + Misc.getRoundedValueMaxOneAfterDecimal(baseCap), 198// "" + (int)(Math.round((capMult - 1f) * 100f)) + "%", 199// "" + (int)increase 200// ); 201// if (withSpacerAfter()) { 202// info.addSpacer(5f); 203// } 204// } 205 } 206 207 public ScopeDescription getScopeDescription() { 208 return ScopeDescription.FLEET; 209 } 210 } 211 212 213 214 public static class Level1 extends BaseCapacityModifierEffect { 215 public String getModifierId() { 216 return "bt_cargo_cap_mod"; 217 } 218 public String getCacheKey() { 219 return "bt_cargo_cap"; 220 } 221 public StatBonus getShipStat(MutableShipStatsAPI stats) { 222 return stats.getCargoMod(); 223 } 224 public float getCapacity(FleetMemberAPI member) { 225 return member.getCargoCapacity(); 226 } 227 @Override 228 public String getCapacityString() { 229 return "Cargo capacity"; 230 } 231 @Override 232 public float getMaxPercent() { 233 return CARGO_CAPACITY_MAX_PERCENT; 234 } 235 @Override 236 public float getThreshold() { 237 return CARGO_CAPACITY_THRESHOLD; 238 } 239 @Override 240 public boolean withSpacerAfter() { 241 return true; 242 } 243 } 244 245 public static class Level2 extends BaseCapacityModifierEffect { 246 public String getModifierId() { 247 return "bt_fuel_cap_mod"; 248 } 249 public String getCacheKey() { 250 return "bt_fuel_cap"; 251 } 252 public StatBonus getShipStat(MutableShipStatsAPI stats) { 253 return stats.getFuelMod(); 254 } 255 public float getCapacity(FleetMemberAPI member) { 256 return member.getFuelCapacity(); 257 } 258 @Override 259 public String getCapacityString() { 260 return "Fuel capacity"; 261 } 262 @Override 263 public float getMaxPercent() { 264 return FUEL_CAPACITY_MAX_PERCENT; 265 } 266 @Override 267 public float getThreshold() { 268 return FUEL_CAPACITY_THRESHOLD; 269 } 270 @Override 271 public boolean withSpacerAfter() { 272 return true; 273 } 274 } 275 276 public static class Level3 extends BaseCapacityModifierEffect { 277 public String getModifierId() { 278 return "bt_crew_cap_mod"; 279 } 280 public String getCacheKey() { 281 return "bt_crew_cap"; 282 } 283 public StatBonus getShipStat(MutableShipStatsAPI stats) { 284 return stats.getMaxCrewMod(); 285 } 286 public float getCapacity(FleetMemberAPI member) { 287 return member.getMaxCrew(); 288 } 289 @Override 290 public String getCapacityString() { 291 return "Personnel capacity"; 292 } 293 @Override 294 public float getMaxPercent() { 295 return PERSONNEL_CAPACITY_MAX_PERCENT; 296 } 297 @Override 298 public float getThreshold() { 299 return PERSONNEL_CAPACITY_THRESHOLD; 300 } 301 @Override 302 public boolean withSpacerAfter() { 303 return true; 304 } 305 } 306 307} 308 309 310