Starsector API
Loading...
Searching...
No Matches
EconomyFleetRouteManager.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.fleets;
2
3import java.util.ArrayList;
4import java.util.Collections;
5import java.util.Comparator;
6import java.util.HashMap;
7import java.util.List;
8import java.util.Map;
9import java.util.Random;
10
11import org.apache.log4j.Logger;
12
13import com.fs.starfarer.api.Global;
14import com.fs.starfarer.api.campaign.BattleAPI;
15import com.fs.starfarer.api.campaign.CampaignEventListener.FleetDespawnReason;
16import com.fs.starfarer.api.campaign.CampaignFleetAPI;
17import com.fs.starfarer.api.campaign.StarSystemAPI;
18import com.fs.starfarer.api.campaign.econ.CommodityOnMarketAPI;
19import com.fs.starfarer.api.campaign.econ.CommoditySpecAPI;
20import com.fs.starfarer.api.campaign.econ.MarketAPI;
21import com.fs.starfarer.api.campaign.listeners.FleetEventListener;
22import com.fs.starfarer.api.impl.campaign.command.WarSimScript;
23import com.fs.starfarer.api.impl.campaign.command.WarSimScript.LocationDanger;
24import com.fs.starfarer.api.impl.campaign.econ.ShippingDisruption;
25import com.fs.starfarer.api.impl.campaign.fleets.EconomyFleetAssignmentAI.CargoQuantityData;
26import com.fs.starfarer.api.impl.campaign.fleets.EconomyFleetAssignmentAI.EconomyRouteData;
27import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.OptionalFleetData;
28import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteData;
29import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteSegment;
30import com.fs.starfarer.api.impl.campaign.ids.Commodities;
31import com.fs.starfarer.api.impl.campaign.ids.Factions;
32import com.fs.starfarer.api.impl.campaign.ids.FleetTypes;
33import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
34import com.fs.starfarer.api.impl.campaign.intel.events.PiracyRespiteScript;
35import com.fs.starfarer.api.impl.campaign.intel.misc.TradeFleetDepartureIntel;
36import com.fs.starfarer.api.impl.campaign.rulecmd.KantaCMD;
37import com.fs.starfarer.api.impl.campaign.shared.SharedData;
38import com.fs.starfarer.api.util.Misc;
39import com.fs.starfarer.api.util.TimeoutTracker;
40import com.fs.starfarer.api.util.WeightedRandomPicker;
41
43
44 public static final Integer ROUTE_SRC_LOAD = 1;
45 public static final Integer ROUTE_TRAVEL_DST = 2;
46 public static final Integer ROUTE_TRAVEL_WS = 3;
47 public static final Integer ROUTE_RESUPPLY_WS = 4;
48 public static final Integer ROUTE_DST_UNLOAD = 5;
49 public static final Integer ROUTE_DST_LOAD = 6;
50 public static final Integer ROUTE_TRAVEL_BACK_WS = 7;
51 public static final Integer ROUTE_RESUPPLY_BACK_WS = 8;
52 public static final Integer ROUTE_TRAVEL_SRC = 9;
53 public static final Integer ROUTE_SRC_UNLOAD = 10;
54
55 public static final String SOURCE_ID = "econ";
56 public static Logger log = Global.getLogger(EconomyFleetRouteManager.class);
57
58 public static Map<LocationDanger, Float> DANGER_LOSS_PROB = new HashMap<LocationDanger, Float>();
59 static {
60 DANGER_LOSS_PROB.put(LocationDanger.NONE, 0.01f);
61 DANGER_LOSS_PROB.put(LocationDanger.MINIMAL, 0.03f);
62 DANGER_LOSS_PROB.put(LocationDanger.LOW, 0.07f);
63 DANGER_LOSS_PROB.put(LocationDanger.MEDIUM, 0.1f);
64 DANGER_LOSS_PROB.put(LocationDanger.HIGH, 0.15f);
65 DANGER_LOSS_PROB.put(LocationDanger.EXTREME, 0.2f);
66 }
67
68
70
72 //super(1f, 14f);
73 super(0.2f, 0.3f);
74 }
75
76 protected Object readResolve() {
77 if (recentlySentTradeFleet == null) {
79 }
80 return this;
81 }
82
83 @Override
84 public void advance(float amount) {
85 super.advance(amount);
86
87 float days = Global.getSector().getClock().convertToDays(amount);
88 recentlySentTradeFleet.advance(days);
89
90// MarketAPI from = pickSourceMarket();
91// MarketAPI to = pickDestMarket(from);
92 }
93
94 protected String getRouteSourceId() {
95 return SOURCE_ID;
96 }
97
98 protected int getMaxFleets() {
99 int numMarkets = Global.getSector().getEconomy().getNumMarkets();
100 int maxBasedOnMarkets = numMarkets * 2;
101 return Math.min(maxBasedOnMarkets, Global.getSettings().getInt("maxEconFleets"));
102 }
103
104 public static boolean ENEMY_STRENGTH_CHECK_EXCLUDE_PIRATES = false;
105
106 protected void addRouteFleetIfPossible() {
108 MarketAPI to = pickDestMarket(from);
109 if (from != null && to != null) {
110
111 EconomyRouteData data = createData(from, to);
112 if (data == null) return;
113
114 log.info("Added trade fleet route from " + from.getName() + " to " + to.getName());
115
116 Long seed = Misc.genRandomSeed();
117 String id = getRouteSourceId();
118
119 OptionalFleetData extra = new OptionalFleetData(from);
120 float tier = data.size;
121 float stability = from.getStabilityValue();
122 String factionId = from.getFactionId();
125 if ((float) Math.random() * 10f > stability + tier) {
126 factionId = Factions.INDEPENDENT;
127 }
128 }
129 if (data.smuggling) {
130 factionId = Factions.INDEPENDENT;
131 }
132 extra.factionId = factionId;
133
134 RouteData route = RouteManager.getInstance().addRoute(id, from, seed, extra, this);
135 route.setCustom(data);
136
137
138 StarSystemAPI sysFrom = data.from.getStarSystem();
139 StarSystemAPI sysTo = data.to.getStarSystem();
140
141// if (sysFrom.getName().startsWith("Rama") ||
142// sysTo.getName().startsWith("Rama")) {
143// System.out.println("32ff32f23");
144// }
145
147 if (from.getFaction().isPlayerFaction() || to.getFaction().isPlayerFaction()) {
149 }
150 }
151
152 LocationDanger dFrom = WarSimScript.getDangerFor(factionId, sysFrom);
153 LocationDanger dTo = WarSimScript.getDangerFor(factionId, sysTo);
154
156
157 LocationDanger danger = dFrom.ordinal() > dTo.ordinal() ? dFrom : dTo;
158
159 if (sysFrom != null && sysFrom.isCurrentLocation()) {
160 // the player is in the from location, don't auto-lose the trade fleet
161 // let it get destroyed by actual fleets, if it does
162 danger = LocationDanger.NONE;
163 }
164
165// if (danger != LocationDanger.NONE) {
166// System.out.println("efwe234523fwe " + danger.name());
167// dFrom = WarSimScript.getDangerFor(factionId, sysFrom);
168// dTo = WarSimScript.getDangerFor(factionId, sysTo);
169// }
170 float pLoss = DANGER_LOSS_PROB.get(danger);
171 if (data.smuggling) pLoss *= 0.5;
172 if ((float) Math.random() < pLoss) {
173 boolean returning = (float) Math.random() < 0.5f;
174 applyLostShipping(data, returning, true, true, true);
176 return;
177 }
178
179
180 //float distLY = Misc.getDistanceLY(from.getLocationInHyperspace(), to.getLocation());
181
182 float orbitDays = 2f + (float) Math.random() * 3f;
183 //float endDays = 8f + (float) Math.random() * 3f; // longer since includes time from jump-point to source
184
185 //orbitDays = 1f;
186 orbitDays = data.size * (0.75f + (float) Math.random() * 0.5f);
187
188// endDays = 0.5f;
189// float totalTravelTime = orbitDays + endDays + travelDays * 2f;
190
191 //boolean inSystem = from.getContainingLocation() == to.getContainingLocation();
192
193// WaystationBonus ws = Misc.getWaystation(from, to);
194// if (ws != null && !data.smuggling) {
195// route.addSegment(new RouteSegment(ROUTE_SRC_LOAD, orbitDays, from.getPrimaryEntity()));
196// route.addSegment(new RouteSegment(ROUTE_TRAVEL_WS, from.getPrimaryEntity(), ws.market.getPrimaryEntity()));
197// route.addSegment(new RouteSegment(ROUTE_RESUPPLY_WS, orbitDays, ws.market.getPrimaryEntity()));
198// route.addSegment(new RouteSegment(ROUTE_TRAVEL_DST, ws.market.getPrimaryEntity(), to.getPrimaryEntity()));
199// route.addSegment(new RouteSegment(ROUTE_DST_UNLOAD, orbitDays * 0.5f, to.getPrimaryEntity()));
200// route.addSegment(new RouteSegment(ROUTE_DST_LOAD, orbitDays * 0.5f, to.getPrimaryEntity()));
201// route.addSegment(new RouteSegment(ROUTE_TRAVEL_BACK_WS, to.getPrimaryEntity(), ws.market.getPrimaryEntity()));
202// route.addSegment(new RouteSegment(ROUTE_RESUPPLY_BACK_WS, orbitDays, ws.market.getPrimaryEntity()));
203// route.addSegment(new RouteSegment(ROUTE_TRAVEL_SRC, ws.market.getPrimaryEntity(), from.getPrimaryEntity()));
204// route.addSegment(new RouteSegment(ROUTE_SRC_UNLOAD, orbitDays, from.getPrimaryEntity()));
205// } else {
206 route.addSegment(new RouteSegment(ROUTE_SRC_LOAD, orbitDays, from.getPrimaryEntity()));
207 route.addSegment(new RouteSegment(ROUTE_TRAVEL_DST, from.getPrimaryEntity(), to.getPrimaryEntity()));
208 route.addSegment(new RouteSegment(ROUTE_DST_UNLOAD, orbitDays * 0.5f, to.getPrimaryEntity()));
209 route.addSegment(new RouteSegment(ROUTE_DST_LOAD, orbitDays * 0.5f, to.getPrimaryEntity()));
210 route.addSegment(new RouteSegment(ROUTE_TRAVEL_SRC, to.getPrimaryEntity(), from.getPrimaryEntity()));
211 route.addSegment(new RouteSegment(ROUTE_SRC_UNLOAD, orbitDays, from.getPrimaryEntity()));
212// }
213
215
216 recentlySentTradeFleet.add(from.getId(), Global.getSettings().getFloat("minEconSpawnIntervalPerMarket"));
217 }
218 }
219
220 protected void setDelayAndSendMessage(RouteData route) {
221 EconomyRouteData data = (EconomyRouteData) route.getCustom();
222
223 float delay = 0.1f;
224 delay = 10f;
225 if (data.size <= 4f) {
226 delay = 5f;
227 } else if (data.size <= 6f) {
228 delay = 10f;
229 } else {
230 delay = 15f;
231 }
232 delay *= 0.75f + (float) Math.random() * 0.5f;
233 delay = (int) delay;
234 route.setDelay(delay);
235
236 if (!Factions.PLAYER.equals(route.getFactionId())) {
237 // queues itself
238 new TradeFleetDepartureIntel(route);
239 }
240 }
241
242
243
244
246 //return Global.getSector().getEconomy().getMarket("jangala");
247 //return Global.getSector().getEconomy().getMarket("sindria");
248 //if (true) return Global.getSector().getEconomy().getMarket("chicomoztoc");
249
251 for (MarketAPI market : Global.getSector().getEconomy().getMarketsCopy()) {
252 if (market.isHidden()) continue;
253 //float distLY = Misc.getDistanceToPlayerLY(market.getPrimaryEntity());
254 if (!market.hasSpaceport()) continue; // markets w/o spaceports don't launch fleets
255 if (SharedData.getData().getMarketsWithoutTradeFleetSpawn().contains(market.getId())) continue;
256
257// if (market.getId().equals("volturn")) {
258// return market;
259// }
260
261 if (recentlySentTradeFleet.contains(market.getId())) continue;
262
263 markets.add(market, market.getSize());
264
265// if (market.getName().toLowerCase().equals("jannow")) {
266// markets.add(market, 100000f);
267// }
268 }
269 return markets.pick();
270 }
271
273 //return Global.getSector().getEconomy().getMarket("asharu");
274 //return Global.getSector().getEconomy().getMarket("chicomoztoc");
275 //if (true) return Global.getSector().getEconomy().getMarket("sindria");
276 if (from == null) return null;
277
279
280// com.getCommodityMarketData().getMarkets()
281// for (MarketAPI market : Global.getSector().getEconomy().getMarketsCopy()) {
282// if ((from.getEconGroup() == null && market.getEconGroup() != null) ||
283// (from.getEconGroup() != null && !from.getEconGroup().equals(market.getEconGroup()))) {
284// continue;
285// }
286// }
287
288 List<CommodityOnMarketAPI> relevant = new ArrayList<CommodityOnMarketAPI>();
289 for (CommodityOnMarketAPI com : from.getAllCommodities()) {
290 if (com.isNonEcon()) continue;
291
292 int exported = Math.min(com.getAvailable(), com.getMaxSupply());
293 int imported = Math.max(0, com.getMaxDemand() - exported);
294 if (imported > 0 || exported > 0) {
295 relevant.add(com);
296 }
297 }
298
300 if (market.isHidden()) continue;
301 if (!market.hasSpaceport()) continue; // markets w/o spaceports don't launch fleets
302 if (SharedData.getData().getMarketsWithoutTradeFleetSpawn().contains(market.getId())) continue;
303 if (market == from) continue;
304
305 int shipping = Misc.getShippingCapacity(market, market.getFaction() == from.getFaction());
306 if (shipping <= 0) continue;
307
308 float w = 0f;
309 for (CommodityOnMarketAPI com : relevant) {
310 int exported = Math.min(com.getAvailable(), com.getMaxSupply());
311 exported = Math.min(exported, shipping);
312 int imported = Math.max(0, com.getMaxDemand() - exported);
313 imported = Math.min(imported, shipping);
314
315 CommodityOnMarketAPI other = market.getCommodityData(com.getId());
316 exported = Math.min(exported, other.getMaxDemand() - other.getMaxSupply());
317 if (exported < 0) exported = 0;
318 imported = Math.min(imported, Math.min(other.getAvailable(), other.getMaxSupply()));
319
320 w += imported;
321 w += exported;
322 }
323
324 if (from.getFaction().isHostileTo(market.getFaction())) {
325 w *= 0.25f;
326 }
327 markets.add(market, w);
328 }
329
330 return markets.pick();
331
332// for (CommodityOnMarketAPI com : from.getCommoditiesCopy()) {
333//
334// SupplierData sd = com.getSupplier();
335// if (sd != null) {
336// if (sd.getMarket() == from) continue;
337// if (SharedData.getData().getMarketsWithoutTradeFleetSpawn().contains(sd.getMarket().getId())) continue;
338// markets.add(sd.getMarket(), sd.getQuantity());
339// }
340// for (SupplierData curr : com.getExports()) {
341// if (curr.getMarket() == from) continue;
342// if (SharedData.getData().getMarketsWithoutTradeFleetSpawn().contains(sd.getMarket().getId())) continue;
343// markets.add(curr.getMarket(), curr.getQuantity());
344// }
345// }
346// return markets.pick();
347
348 }
349
350 public static EconomyRouteData createData(MarketAPI from, MarketAPI to) {
351 EconomyRouteData smuggling = new EconomyRouteData();
352 smuggling.from = from;
353 smuggling.to = to;
354 smuggling.smuggling = true;
355
356 EconomyRouteData legal = new EconomyRouteData();
357 legal.from = from;
358 legal.to = to;
359 legal.smuggling = false;
360
361 float legalTotal = 0;
362 float smugglingTotal = 0;
363
364
365 List<CommodityOnMarketAPI> relevant = new ArrayList<CommodityOnMarketAPI>();
366 for (CommodityOnMarketAPI com : from.getAllCommodities()) {
367 if (com.isNonEcon()) continue;
368 CommodityOnMarketAPI orig = com;
369 int exported = Math.min(com.getAvailable(), com.getMaxSupply());
370 if (!com.getCommodity().isPrimary()) {
371 com = from.getCommodityData(com.getCommodity().getDemandClass());
372 }
373
374 int imported = Math.max(0, com.getMaxDemand() - exported);
375 if (imported > 0 || exported > 0) {
376 relevant.add(orig);
377 }
378 }
379
380 int shipping = Misc.getShippingCapacity(from, to.getFaction() == from.getFaction());
381 for (CommodityOnMarketAPI com : relevant) {
382 CommodityOnMarketAPI orig = com;
383 int exported = Math.min(com.getAvailable(), com.getMaxSupply());
384 exported = Math.min(exported, shipping);
385
386 if (!com.getCommodity().isPrimary()) {
387 com = from.getCommodityData(com.getCommodity().getDemandClass());
388 }
389
390 int imported = Math.max(0, com.getMaxDemand() - exported);
391 imported = Math.min(imported, shipping);
392 if (orig != com) imported = 0;
393
394 CommodityOnMarketAPI other = to.getCommodityData(com.getId());
395 exported = Math.min(exported, other.getMaxDemand() - other.getMaxSupply());
396 if (exported < 0) exported = 0;
397 imported = Math.min(imported, Math.min(other.getAvailable(), other.getMaxSupply()));
398
399 if (imported < 0) imported = 0;
400
401 if (imported <= 0 && exported <= 0) continue;
402
403 boolean illegal = com.getCommodityMarketData().getMarketShareData(from).isSourceIsIllegal() ||
404 com.getCommodityMarketData().getMarketShareData(to).isSourceIsIllegal() ||
405 from.getFaction().isHostileTo(to.getFaction());
406
407 if (imported > exported) {
408 if (illegal) {
409 smuggling.addReturn(orig.getId(), imported);
410 smugglingTotal += imported;
411 } else {
412 legal.addReturn(orig.getId(), imported);
413 legalTotal += imported;
414 }
415 } else {
416 if (illegal) {
417 smuggling.addDeliver(orig.getId(), exported);
418 smugglingTotal += exported;
419 } else {
420 legal.addDeliver(orig.getId(), exported);
421 legalTotal += exported;
422 }
423 }
424 }
425
426 Comparator<CargoQuantityData> comp = new Comparator<CargoQuantityData>() {
427 public int compare(CargoQuantityData o1, CargoQuantityData o2) {
428 if (o1.getCommodity().isPersonnel() && !o2.getCommodity().isPersonnel()) {
429 return 1;
430 }
431 if (o2.getCommodity().isPersonnel() && !o1.getCommodity().isPersonnel()) {
432 return -1;
433 }
434 return o2.units - o1.units;
435 }
436 };
437 Collections.sort(legal.cargoDeliver, comp);
438 Collections.sort(legal.cargoReturn, comp);
439 Collections.sort(smuggling.cargoDeliver, comp);
440 Collections.sort(smuggling.cargoReturn, comp);
441
442 if (smugglingTotal <= 0 && legalTotal <= 0) return null;
443
444 EconomyRouteData data = null;
445 if ((float) Math.random() * (smugglingTotal + legalTotal) < smugglingTotal) {
446 data = smuggling;
447 } else {
448 data = legal;
449 }
450
451 while (data.cargoDeliver.size() > 4) {
452 data.cargoDeliver.remove(4);
453 }
454 while (data.cargoReturn.size() > 4) {
455 data.cargoReturn.remove(4);
456 }
457
458// data.cargoDeliver = data.cargoDeliver.subList(0, Math.min(data.cargoDeliver.size(), 4));
459// data.cargoReturn = data.cargoReturn.subList(0, Math.min(data.cargoReturn.size(), 4));
460
461// data.cargoDeliver.clear();
462// data.cargoReturn.clear();
463// data.addDeliver(Commodities.SHIPS, 5);
464
465 float max = 0f;
466 for (CargoQuantityData curr : data.cargoDeliver) {
467 if (curr.units > max) max = curr.units;
468 }
469 for (CargoQuantityData curr : data.cargoReturn) {
470 if (curr.units > max) max = curr.units;
471 }
472
473 int types = Math.max(data.cargoDeliver.size(), data.cargoReturn.size());
474 if (types >= 3) {
475 data.size++;
476 }
477 if (types >= 4) {
478 data.size++;
479 }
480
481 data.size = max;
482
483
484 return data;
485 }
486
487
488
489 public boolean shouldCancelRouteAfterDelayCheck(RouteData route) {
490 String factionId = route.getFactionId();
491
492 boolean smuggling = false;
493 if (route.getCustom() instanceof EconomyRouteData) {
494 smuggling = ((EconomyRouteData) route.getCustom()).smuggling;
495 }
496
497 if (factionId != null && route.getMarket() != null && !smuggling &&
498 route.getMarket().getFaction().isHostileTo(factionId)) {
499 return true;
500 }
501 return false;
502 }
503
504
505 public CampaignFleetAPI spawnFleet(RouteData route) {
506 Random random = new Random();
507 if (route.getSeed() != null) {
508 random = new Random(route.getSeed());
509 }
510
511 CampaignFleetAPI fleet = createTradeRouteFleet(route, random);
512 if (fleet == null) return null;;
513
514 //fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_TRADE_FLEET, true);
515
516 if (KantaCMD.playerHasProtection() && route.custom instanceof EconomyRouteData) {
517 EconomyRouteData data = (EconomyRouteData) route.custom;
518 if (data.from != null && data.to != null) {
519 if (data.from.getFaction().isPlayerFaction() || data.to.getFaction().isPlayerFaction()) {
521 }
522 }
523 }
524
525 fleet.addEventListener(this);
526
527 fleet.addScript(new EconomyFleetAssignmentAI(fleet, route));
528 return fleet;
529 }
530
531
532 public static String getFleetTypeIdForTier(float tier, boolean smuggling) {
533 String type = FleetTypes.TRADE;
534 if (tier <= 3) type = FleetTypes.TRADE_SMALL;
535 if (smuggling) {
537 }
538 return type;
539 }
540
541 public static CampaignFleetAPI createTradeRouteFleet(RouteData route, Random random) {
542 EconomyRouteData data = (EconomyRouteData) route.getCustom();
543
544 MarketAPI from = data.from;
545 MarketAPI to = data.to;
546
547// if (from.getId().equals("umbra")) {
548// System.out.println("wefwefw");
549// }
550
551 float tier = data.size;
552
553 if (data.smuggling && tier > 4) {
554 tier = 4;
555 }
556
557// data.smuggling = false;
558// tier = 4;
559
560// float stability = from.getStabilityValue();
561// String factionId = from.getFactionId();
562// if (!from.getFaction().isHostileTo(Factions.INDEPENDENT) &&
563// !to.getFaction().isHostileTo(Factions.INDEPENDENT)) {
564// if ((float) Math.random() * 10f > stability + tier) {
565// factionId = Factions.INDEPENDENT;
566// }
567// }
568//
569// if (data.smuggling) {
570// factionId = Factions.INDEPENDENT;
571// }
572 String factionId = route.getFactionId();
573
574 float total = 0f;
575 float fuel = 0f;
576 float cargo = 0f;
577 float personnel = 0f;
578 //float ships = 0f;
579
580 List<CargoQuantityData> all = new ArrayList<CargoQuantityData>();
581 all.addAll(data.cargoDeliver);
582 all.addAll(data.cargoReturn);
583 for (CargoQuantityData curr : all) {
584 CommoditySpecAPI spec = curr.getCommodity();
585// if (spec.getId().equals(Commodities.SHIPS)) {
586// ships = Math.max(ships, curr.units);
587// }
588 if (spec.isMeta()) continue;
589
590 total += curr.units;
591 if (spec.hasTag(Commodities.TAG_PERSONNEL)) {
592 personnel += curr.units;
593 } else if (spec.getId().equals(Commodities.FUEL)) {
594 fuel += curr.units;
595 } else {
596 cargo += curr.units;
597 }
598 }
599
600// System.out.println("Ships: " + ships);
601 if (total < 1f) total = 1f;
602
603 float fuelFraction = fuel / total;
604 float personnelFraction = personnel / total;
605 float cargoFraction = cargo / total;
606
607// fuelFraction = 0.33f;
608// personnelFraction = 0.33f;
609// cargoFraction = 0.33f;
610
611 if (fuelFraction + personnelFraction + cargoFraction > 0) {
612 float mult = 1f / (fuelFraction + personnelFraction + cargoFraction);
613 fuelFraction *= mult;
614 personnelFraction *= mult;
615 cargoFraction *= mult;
616 }
617
618 log.info("Creating trade fleet of tier " + tier + " for market [" + from.getName() + "]");
619
620 float stabilityFactor = 1f + from.getStabilityValue() / 20f;
621
622 float combat = Math.max(1f, tier * stabilityFactor * 0.5f) * 10f;
623 float freighter = tier * 2f * cargoFraction * 3f;
624 float tanker = tier * 2f * fuelFraction * 3f;
625 float transport = tier * 2f * personnelFraction * 3f;
626 float liner = 0f;
627
628 //float utility = 1f + tier * 0.25f;
629 float utility = 0f;
630
631 String type = getFleetTypeIdForTier(tier, data.smuggling);
632 if (data.smuggling) {
633 //combat *= 2f;
634 freighter *= 0.5f;
635 tanker *= 0.5f;
636 transport *= 0.5f;
637 liner *= 0.5f;
638 }
639
640 FleetParamsV3 params = new FleetParamsV3(
641 from,
642 null, // locInHyper
643 factionId,
644 route.getQualityOverride(), // qualityOverride
645 type,
646 combat, // combatPts
647 freighter, // freighterPts
648 tanker, // tankerPts
649 transport, // transportPts
650 liner, // linerPts
651 utility, // utilityPts
652 0f //-0.5f // qualityBonus
653 );
654 params.timestamp = route.getTimestamp();
655 params.onlyApplyFleetSizeToCombatShips = true;
656 params.maxShipSize = 3;
657 params.officerLevelBonus = -2;
658 params.officerNumberMult = 0.5f;
659 params.random = random;
661
662 if (fleet == null || fleet.isEmpty()) return null;
663
664 if (Misc.isPirateFaction(fleet.getFaction())) {
666 }
667
668 if (data.smuggling) {
670 Misc.makeLowRepImpact(fleet, "smuggler");
671 } else {
673 }
674
675 //cargoCap, fuelCap, personnelCap;
676 data.cargoCap = fleet.getCargo().getMaxCapacity();
677 data.fuelCap = fleet.getCargo().getMaxFuel();
678 data.personnelCap = fleet.getCargo().getMaxPersonnel();
679
680 //ShippingDisruption.getShippingDisruption(from).getShippingPenalty().addTemporaryModFlat(1f, "fwefwe", 1f);
681
682 return fleet;
683
684 }
685
686 public void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle) {
687 // already reduced by losses taken
688 //System.out.println("Cargo: " + fleet.getCargo().getMaxCapacity());
689
690 RouteData route = RouteManager.getInstance().getRoute(getRouteSourceId(), fleet);
691 if (route == null || !(route.getCustom() instanceof EconomyRouteData)) return;
692
693 if (route.isExpired()) return;
694
695 EconomyRouteData data = (EconomyRouteData) route.getCustom();
696
697 float cargoCap = fleet.getCargo().getMaxCapacity();
698 float fuelCap = fleet.getCargo().getMaxFuel();
699 float personnelCap = fleet.getCargo().getMaxPersonnel();
700
701 float lossFraction = 0.34f;
702
703 //boolean returning = route.getCurrentIndex() >= 3;
704 boolean returning = false;
705 if (route.getCurrent() != null && route.getCurrentSegmentId() >= ROUTE_DST_LOAD) {
706 returning = true;
707 }
708
709 // whether it lost enough carrying capacity to count as an economic loss
710 // of that commodity at destination markets
711 boolean lostCargo = data.cargoCap * lossFraction > cargoCap;
712 boolean lostFuel = data.fuelCap * lossFraction > fuelCap;
713 boolean lostPersonnel = data.personnelCap * lossFraction > personnelCap;
714
715 // set to 0f so that the loss doesn't happen multiple times for a commodity
716 if (lostCargo) data.cargoCap = 0f;
717 if (lostFuel) data.fuelCap = 0f;
718 if (lostPersonnel) data.personnelCap = 0f;
719
720 applyLostShipping(data, returning, lostCargo, lostFuel, lostPersonnel);
721
722 // if it's lost all 3 capacities, also trigger a general shipping capacity loss at market
723 boolean allThreeLost = true;
724 allThreeLost &= data.cargoCap <= 0f || lostCargo;
725 allThreeLost &= data.fuelCap <= 0f || lostFuel;
726 allThreeLost &= data.personnelCap <= 0f || lostPersonnel;
727// if (fullyLost) {
728
729 boolean applyAccessLoss = allThreeLost;
730 if (applyAccessLoss) {
733 }
734
735 }
736
737
738 public static void applyLostShipping(EconomyRouteData data, boolean returning, boolean cargo, boolean fuel, boolean personnel) {
739 if (!cargo && !fuel && !personnel) return;
740
741 int penalty = 1;
742 int penalty2 = 2;
743 if (!returning) {
744 for (CargoQuantityData curr : data.cargoDeliver) {
745 CommodityOnMarketAPI com = data.to.getCommodityData(curr.cargo);
746 if (!fuel && com.isFuel()) continue;
747 if (!personnel && com.isPersonnel()) continue;
748 if (!cargo && !com.isFuel() && !com.isPersonnel()) continue;
749
752 ShippingDisruption.COMMODITY_LOSS_PREFIX + Misc.genUID(), "Recent incoming shipment lost", -penalty2);
753
755 }
756 }
757 for (CargoQuantityData curr : data.cargoReturn) {
758 CommodityOnMarketAPI com = data.from.getCommodityData(curr.cargo);
759 if (!fuel && com.isFuel()) continue;
760 if (!personnel && com.isPersonnel()) continue;
761 if (!cargo && !com.isFuel() && !com.isPersonnel()) continue;
762
765 ShippingDisruption.COMMODITY_LOSS_PREFIX + Misc.genUID(), "Recent incoming shipment lost", -penalty2);
766
768 }
769 }
770
771
772 public void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param) {
773
774 }
775
776 public boolean shouldRepeat(RouteData route) {
777 return false;
778 }
779
780 public void reportAboutToBeDespawnedByRouteManager(RouteData route) {
781
782 }
783
784
785}
786
787
788
789
790
791
792
static SettingsAPI getSettings()
Definition Global.java:57
static Logger getLogger(Class c)
Definition Global.java:32
static SectorAPI getSector()
Definition Global.java:65
void addTemporaryModFlat(float durInDays, String source, String desc, float value)
static LocationDanger getDangerFor(FactionAPI faction, StarSystemAPI system)
static ShippingDisruption getDisruption(MarketAPI market)
static CampaignFleetAPI createTradeRouteFleet(RouteData route, Random random)
static EconomyRouteData createData(MarketAPI from, MarketAPI to)
void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle)
void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param)
static void applyLostShipping(EconomyRouteData data, boolean returning, boolean cargo, boolean fuel, boolean personnel)
static CampaignFleetAPI createFleet(FleetParamsV3 params)
RouteData addRoute(String source, MarketAPI market, Long seed, OptionalFleetData extra, RouteFleetSpawner spawner)
RouteData getRoute(String source, CampaignFleetAPI fleet)
static int getShippingCapacity(MarketAPI market, boolean inFaction)
Definition Misc.java:5019
static boolean isPirateFaction(FactionAPI faction)
Definition Misc.java:6150
static void makeLowRepImpact(CampaignFleetAPI fleet, String reason)
Definition Misc.java:1465
boolean isHostileTo(FactionAPI other)
void addEventListener(FleetEventListener listener)
void addScript(EveryFrameScript script)
MarketShareDataAPI getMarketShareData(MarketAPI market)
List< MarketAPI > getMarketsInGroup(String group)
CommodityOnMarketAPI getCommodityData(String commodityId)
List< CommodityOnMarketAPI > getAllCommodities()
void set(String key, Object value)