1package com.fs.starfarer.api.impl.campaign.fleets;
3import java.util.ArrayList;
4import java.util.Collections;
5import java.util.Comparator;
6import java.util.LinkedHashMap;
9import java.util.Random;
11import com.fs.starfarer.api.Global;
12import com.fs.starfarer.api.campaign.CampaignFleetAPI;
13import com.fs.starfarer.api.campaign.CargoAPI;
14import com.fs.starfarer.api.campaign.FactionAPI.ShipPickParams;
15import com.fs.starfarer.api.campaign.econ.CommoditySpecAPI;
16import com.fs.starfarer.api.campaign.econ.MarketAPI;
17import com.fs.starfarer.api.fleet.FleetMemberAPI;
18import com.fs.starfarer.api.fleet.ShipRolePick;
19import com.fs.starfarer.api.impl.campaign.econ.impl.BaseIndustry;
20import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteData;
21import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteSegment;
22import com.fs.starfarer.api.impl.campaign.ids.Commodities;
23import com.fs.starfarer.api.impl.campaign.ids.Factions;
24import com.fs.starfarer.api.impl.campaign.ids.ShipRoles;
25import com.fs.starfarer.api.impl.campaign.procgen.themes.RouteFleetAssignmentAI;
26import com.fs.starfarer.api.util.IntervalUtil;
27import com.fs.starfarer.api.util.Misc;
28import com.fs.starfarer.api.util.WeightedRandomPicker;
32 public static class CargoQuantityData {
35 public CargoQuantityData(String cargo,
int units) {
40 public CommoditySpecAPI getCommodity() {
46 public static class EconomyRouteData {
47 public float cargoCap, fuelCap, personnelCap;
49 public boolean smuggling =
false;
50 public MarketAPI from;
53 public List<CargoQuantityData> cargoDeliver =
new ArrayList<CargoQuantityData>();
54 public List<CargoQuantityData> cargoReturn =
new ArrayList<CargoQuantityData>();
56 public void addDeliver(String
id,
int qty) {
57 cargoDeliver.add(
new CargoQuantityData(
id, qty));
59 public void addReturn(String
id,
int qty) {
60 cargoReturn.add(
new CargoQuantityData(
id, qty));
63 public static String getCargoList(List<CargoQuantityData> cargo) {
64 List<String> strings =
new ArrayList<String>();
66 List<CargoQuantityData> sorted =
new ArrayList<CargoQuantityData>(cargo);
67 Collections.sort(sorted,
new Comparator<CargoQuantityData>() {
68 public int compare(CargoQuantityData o1, CargoQuantityData o2) {
69 if (o1.getCommodity().isPersonnel() && !o2.getCommodity().isPersonnel()) {
72 if (o2.getCommodity().isPersonnel() && !o1.getCommodity().isPersonnel()) {
75 return o2.units - o1.units;
79 for (CargoQuantityData curr : sorted) {
80 CommoditySpecAPI spec = curr.getCommodity();
83 if (spec.getId().equals(Commodities.SHIPS)) {
84 strings.add(
"ship hulls");
89 if (spec.isMeta())
continue;
90 strings.add(spec.getName().toLowerCase());
92 if (strings.size() > 4) {
93 List<String> copy =
new ArrayList<String>();
94 copy.add(strings.get(0));
95 copy.add(strings.get(1));
96 copy.add(
"other commodities");
99 return Misc.getAndJoined(strings);
104 private String origFaction;
105 private IntervalUtil factionChangeTracker =
new IntervalUtil(0.1f, 0.3f);
109 origFaction = route.getFactionId();
112 factionChangeTracker =
null;
114 factionChangeTracker.forceIntervalElapsed();
125 public static String
getCargoList(RouteData route, RouteSegment segment) {
127 EconomyRouteData data = (EconomyRouteData) route.getCustom();
129 Integer
id = segment.getId();
132 return EconomyRouteData.getCargoList(data.cargoDeliver);
134 return EconomyRouteData.getCargoList(data.cargoReturn);
150 Integer
id = segment.getId();
154 fleet.getCargo().clear();
159 EconomyRouteData data =
getData();
160 MarketAPI cargoSource = data.from;
161 List<CargoQuantityData> list = data.cargoDeliver;
163 cargoSource = data.to;
164 list = data.cargoReturn;
167 CargoAPI cargo = fleet.getCargo();
171 Map<String, Float> target =
new LinkedHashMap<String, Float>();
173 for (CargoQuantityData curr : list) {
175 float qty = (int) (BaseIndustry.getSizeMult(curr.units) * spec.getEconUnit());
177 if (curr.cargo.equals(Commodities.SHIPS)) {
178 ships = Math.max(ships, curr.units);
182 if (curr.cargo.equals(Commodities.FUEL)) {
183 cargo.addFuel(Math.min(qty, cargo.getMaxFuel()));
187 if (curr.cargo.equals(Commodities.CREW))
continue;
188 if (curr.cargo.equals(Commodities.MARINES))
continue;
191 target.put(curr.cargo, qty);
196 if (total <= 0)
return;
198 float maxCargo = cargo.getMaxCapacity();
199 for (String cid : target.keySet()) {
200 float qty = target.get(cid);
202 cargo.addCommodity(cid, ((
int) qty * Math.min(1f, maxCargo / total)));
207 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
208 if (member.isMothballed()) {
209 fleet.getFleetData().removeFleetMember(member);
213 if (units <= 0)
return;
216 Random random =
new Random();
217 if (route.getSeed() !=
null) {
218 random =
new Random(route.getSeed());
221 float add = units * 1.5f + random.nextInt(3);
223 EconomyRouteData data =
getData();
224 boolean sameFaction = data.from.getFaction() == data.to.getFaction();
225 for (
int i = 0; i < add; i++) {
226 WeightedRandomPicker<String> roles =
new WeightedRandomPicker<String>(random);
227 roles.add(ShipRoles.COMBAT_FREIGHTER_SMALL, 20f);
228 roles.add(ShipRoles.FREIGHTER_SMALL, 20f);
229 roles.add(ShipRoles.TANKER_SMALL, 10f);
231 roles.add(ShipRoles.COMBAT_FREIGHTER_MEDIUM, 20f * (i - 1));
232 roles.add(ShipRoles.FREIGHTER_MEDIUM, 20f * (i - 1));
233 roles.add(ShipRoles.TANKER_MEDIUM, 10f * (i - 1));
236 roles.add(ShipRoles.COMBAT_FREIGHTER_LARGE, 20f * (i - 2));
237 roles.add(ShipRoles.FREIGHTER_LARGE, 20f * (i - 2));
238 roles.add(ShipRoles.TANKER_LARGE, 10f * (i - 2));
241 String role = roles.pick();
242 ShipPickParams params = ShipPickParams.priority();
243 if (!sameFaction) params = ShipPickParams.imported();
244 List<ShipRolePick> picks = market.pickShipsForRole(role, params, random,
null);
245 for (ShipRolePick pick : picks) {
246 FleetMemberAPI member = fleet.getFleetData().addFleetMember(pick.variantId);
247 member.getRepairTracker().setMothballed(
true);
250 fleet.getFleetData().sort();
257 if (list.isEmpty()) {
258 return "preparing for a voyage to " +
getData().to.getName();
260 return "loading " + list +
" at " +
getData().from.getName();
265 if (list.isEmpty()) {
266 return "orbiting " +
getData().from.getName();
268 return "unloading " + list +
" at " +
getData().from.getName();
276 Integer
id = segment.getId();
278 if (list.isEmpty()) {
279 return "traveling to " +
getData().to.getName();
281 return "delivering " + list +
" to " +
getData().to.getName();
283 if (list.isEmpty()) {
284 return "returning to " +
getData().from.getName();
286 return "returning to " +
getData().from.getName() +
" with " + list;
288 return super.getTravelActionText(segment);
295 Integer
id = segment.getId();
298 if (list.isEmpty()) {
299 return "orbiting " +
getData().to.getName();
301 return "unloading " + list +
" at " +
getData().to.getName();
303 if (list.isEmpty()) {
304 return "orbiting " +
getData().to.getName();
306 return "loading " + list +
" at " +
getData().to.getName();
308 return "resupplying";
311 return super.getInSystemActionText(segment);
317 super.addEndingAssignment(current, justSpawned);
323 super.addLocalAssignment(current, justSpawned);
329 super.addStartingAssignment(current, justSpawned);
335 super.addTravelAssignment(current, justSpawned);
341 EconomyRouteData data = (EconomyRouteData) route.getCustom();
348 super.advance(amount);
354 EconomyRouteData data =
getData();
355 if (!data.smuggling)
return;
363 factionChangeTracker.advance(days);
364 if (factionChangeTracker.intervalElapsed() && fleet.getAI() !=
null) {
365 MarketAPI align =
null;
366 if (data.from.getStarSystem() == fleet.getContainingLocation()) {
368 }
else if (data.to.getStarSystem() == fleet.getContainingLocation()) {
373 String targetFac = origFaction;
374 boolean hostile = align.getFaction().isHostileTo(targetFac);
376 targetFac = Factions.INDEPENDENT;
377 hostile = align.getFaction().isHostileTo(targetFac);
380 targetFac = align.getFactionId();
382 if (!fleet.getFaction().getId().equals(targetFac)) {
383 fleet.setFaction(targetFac,
true);
386 String targetFac = origFaction;
387 if (fleet.isInHyperspace()) {
388 targetFac = Factions.INDEPENDENT;
390 if (!fleet.getFaction().getId().equals(targetFac)) {
391 fleet.setFaction(targetFac,
true);
static SettingsAPI getSettings()
static SectorAPI getSector()
void syncMothballedShips(float units, MarketAPI market)
void addTravelAssignment(RouteSegment current, boolean justSpawned)
String getEndingActionText(RouteSegment segment)
String getCargoList(RouteSegment segment)
void updateCargo(RouteSegment segment)
void addEndingAssignment(RouteSegment current, boolean justSpawned)
String getInSystemActionText(RouteSegment segment)
void advance(float amount)
void addStartingAssignment(RouteSegment current, boolean justSpawned)
String getTravelActionText(RouteSegment segment)
void doSmugglingFactionChangeCheck(float amount)
String getStartingActionText(RouteSegment segment)
static String getCargoList(RouteData route, RouteSegment segment)
static String getCargoListReturn(RouteData route)
EconomyRouteData getData()
static String getCargoListDeliver(RouteData route)
void addLocalAssignment(RouteSegment current, boolean justSpawned)
EconomyFleetAssignmentAI(CampaignFleetAPI fleet, RouteData route)
static final Integer ROUTE_SRC_LOAD
static final Integer ROUTE_RESUPPLY_WS
static final Integer ROUTE_TRAVEL_DST
static final Integer ROUTE_TRAVEL_BACK_WS
static final Integer ROUTE_RESUPPLY_BACK_WS
static final Integer ROUTE_DST_UNLOAD
static final Integer ROUTE_DST_LOAD
static final Integer ROUTE_TRAVEL_SRC
static final Integer ROUTE_TRAVEL_WS
CommoditySpecAPI getCommoditySpec(String commodityId)