Starsector API
Loading...
Searching...
No Matches
BaseSubmarketPlugin.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.submarkets;
2
3import java.util.ArrayList;
4import java.util.List;
5import java.util.Random;
6
7import com.fs.starfarer.api.Global;
8import com.fs.starfarer.api.campaign.CampaignFleetAPI;
9import com.fs.starfarer.api.campaign.CampaignUIAPI.CoreUITradeMode;
10import com.fs.starfarer.api.campaign.CargoAPI;
11import com.fs.starfarer.api.campaign.CargoAPI.CargoItemType;
12import com.fs.starfarer.api.campaign.CargoStackAPI;
13import com.fs.starfarer.api.campaign.CoreUIAPI;
14import com.fs.starfarer.api.campaign.FactionAPI;
15import com.fs.starfarer.api.campaign.FactionAPI.ShipPickMode;
16import com.fs.starfarer.api.campaign.FactionDoctrineAPI;
17import com.fs.starfarer.api.campaign.FleetDataAPI;
18import com.fs.starfarer.api.campaign.PlayerMarketTransaction;
19import com.fs.starfarer.api.campaign.SpecialItemData;
20import com.fs.starfarer.api.campaign.SubmarketPlugin;
21import com.fs.starfarer.api.campaign.econ.CommodityOnMarketAPI;
22import com.fs.starfarer.api.campaign.econ.MarketAPI;
23import com.fs.starfarer.api.campaign.econ.SubmarketAPI;
24import com.fs.starfarer.api.combat.WeaponAPI.AIHints;
25import com.fs.starfarer.api.combat.WeaponAPI.WeaponSize;
26import com.fs.starfarer.api.fleet.FleetMemberAPI;
27import com.fs.starfarer.api.fleet.FleetMemberType;
28import com.fs.starfarer.api.impl.campaign.DModManager;
29import com.fs.starfarer.api.impl.campaign.fleets.DefaultFleetInflater;
30import com.fs.starfarer.api.impl.campaign.fleets.FleetFactoryV3;
31import com.fs.starfarer.api.impl.campaign.fleets.FleetParamsV3;
32import com.fs.starfarer.api.impl.campaign.ids.FleetTypes;
33import com.fs.starfarer.api.impl.campaign.ids.Items;
34import com.fs.starfarer.api.impl.campaign.ids.Tags;
35import com.fs.starfarer.api.impl.campaign.shared.SharedData;
36import com.fs.starfarer.api.loading.FighterWingSpecAPI;
37import com.fs.starfarer.api.loading.HullModSpecAPI;
38import com.fs.starfarer.api.loading.WeaponSpecAPI;
39import com.fs.starfarer.api.plugins.impl.CoreAutofitPlugin;
40import com.fs.starfarer.api.ui.LabelAPI;
41import com.fs.starfarer.api.ui.TooltipMakerAPI;
42import com.fs.starfarer.api.util.Highlights;
43import com.fs.starfarer.api.util.Misc;
44import com.fs.starfarer.api.util.WeightedRandomPicker;
45
46public class BaseSubmarketPlugin implements SubmarketPlugin {
47
48 //public static float TRADE_IMPACT_DAYS = 30f;
49 public static float TRADE_IMPACT_DAYS = 120f;
50
51 public static class ShipSalesData {
52 private String variantId;
53 private float numShips;
54 private float totalValue;
55 public String getVariantId() {
56 return variantId;
57 }
58 public void setVariantId(String variantId) {
59 this.variantId = variantId;
60 }
61 public float getNumShips() {
62 return numShips;
63 }
64 public void setNumShips(float numShips) {
65 this.numShips = numShips;
66 }
67 public float getTotalValue() {
68 return totalValue;
69 }
70 public void setTotalValue(float totalValue) {
71 this.totalValue = totalValue;
72 }
73 }
74
75 protected MarketAPI market;
77
78 protected CargoAPI cargo;
79 protected float minSWUpdateInterval = 30; // campaign days
80 protected float sinceSWUpdate = 30f + 1;
81 protected float sinceLastCargoUpdate = 30f + 1;
82
83 protected Random itemGenRandom = new Random();
84
85
87 this.submarket = submarket;
88 this.market = submarket.getMarket();
89 }
90
91 protected Object readResolve() {
92 return this;
93 }
94
95 public String getName() {
96 return null;
97 }
98
99 public CargoAPI getCargo() {
100 if (cargo == null) {
101 this.cargo = Global.getFactory().createCargo(true);
103 }
104 return cargo;
105 }
106
108 return cargo;
109 }
110
111 public void setCargo(CargoAPI cargo) {
112 this.cargo = cargo;
113 }
114
116
117 }
118
119 public void advance(float amount) {
120 float days = Global.getSector().getClock().convertToDays(amount);
121 sinceLastCargoUpdate += days;
122 sinceSWUpdate += days;
123 }
124
125 public boolean okToUpdateShipsAndWeapons() {
126 //if (true) return true;
128 }
129
130 public void addAllCargo(CargoAPI otherCargo) {
131 for (CargoStackAPI stack : otherCargo.getStacksCopy()) {
132 if (stack.isNull()) continue;
133 getCargo().addItems(stack.getType(), stack.getData(), stack.getSize());
134 }
135 }
136
137
138 public float getTariff() {
140 }
141
142 public String getBuyVerb() {
143 return "Buy";
144 }
145
146 public String getSellVerb() {
147 return "Sell";
148 }
149
150 public boolean isFreeTransfer() {
151 return false;
152 }
153
154 public boolean isEnabled(CoreUIAPI ui) {
155 return ui.getTradeMode() == CoreUITradeMode.OPEN || isBlackMarket();
156 //return true;
157 }
158 public OnClickAction getOnClickAction(CoreUIAPI ui) {
159 return OnClickAction.OPEN_SUBMARKET;
160 }
161 public String getDialogText(CoreUIAPI ui) {
162 return null;
163 }
165 return null;
166 }
167 public DialogOption [] getDialogOptions(CoreUIAPI ui) {
168 return null;
169 }
170 public String getTooltipAppendix(CoreUIAPI ui) {
171 return null;
172 }
174 return null;
175 }
176
177
178 public PlayerEconomyImpactMode getPlayerEconomyImpactMode() {
179 return PlayerEconomyImpactMode.NONE;
180 }
181
183 return 1f;
184 }
185
187 if (!isParticipatesInEconomy()) return;
188
189 PlayerEconomyImpactMode mode = getPlayerEconomyImpactMode();
190 //if (mode == PlayerEconomyImpactMode.NONE) return;
191
192 //mode = PlayerEconomyImpactMode.NONE;
193
195
196
197 for (CargoStackAPI stack : transaction.getSold().getStacksCopy()) {
198 if (stack.isCommodityStack()) {
199 float qty = stack.getSize() * getPlayerTradeImpactMult();
200 if (qty <= 0) continue;
201 CommodityOnMarketAPI com = market.getCommodityData(stack.getCommodityId());
202
203 if (mode == PlayerEconomyImpactMode.BOTH) {
204 com.addTradeMod("sell_" + Misc.genUID(), qty, TRADE_IMPACT_DAYS);
205 } else if (mode == PlayerEconomyImpactMode.PLAYER_SELL_ONLY) {
206 com.addTradeModPlus("sell_" + Misc.genUID(), qty, TRADE_IMPACT_DAYS);
207 } else if (mode == PlayerEconomyImpactMode.PLAYER_BUY_ONLY || mode == PlayerEconomyImpactMode.NONE) {
208 com.addTradeModMinus("sell_" + Misc.genUID(), qty, TRADE_IMPACT_DAYS);
209 }
210 }
211 }
212 for (CargoStackAPI stack : transaction.getBought().getStacksCopy()) {
213 if (stack.isCommodityStack()) {
214 float qty = stack.getSize() * getPlayerTradeImpactMult();
215 if (qty <= 0) continue;
216 CommodityOnMarketAPI com = market.getCommodityData(stack.getCommodityId());
217
218 if (mode == PlayerEconomyImpactMode.BOTH) {
219 com.addTradeMod("buy_" + Misc.genUID(), -qty, TRADE_IMPACT_DAYS);
220 } else if (mode == PlayerEconomyImpactMode.PLAYER_SELL_ONLY || mode == PlayerEconomyImpactMode.NONE) {
221 com.addTradeModPlus("buy_" + Misc.genUID(), -qty, TRADE_IMPACT_DAYS);
222 } else if (mode == PlayerEconomyImpactMode.PLAYER_BUY_ONLY) {
223 com.addTradeModMinus("buy_" + Misc.genUID(), -qty, TRADE_IMPACT_DAYS);
224 }
225 }
226 }
227 }
228
229 public boolean isMilitaryMarket() {
230 return false;
231 }
232
233 public boolean isBlackMarket() {
234 //return false;
236 }
237
238 public boolean isOpenMarket() {
239 return false;
240 }
241
242 public boolean isParticipatesInEconomy() {
243 return true;
244 }
245
246
247 public boolean isIllegalOnSubmarket(String commodityId, TransferAction action) {
248// if (market.hasCondition(Conditions.FREE_PORT)) return false;
249// //return market.isIllegal(commodityId);
250// return submarket.getFaction().isIllegal(commodityId);
251 return market.isIllegal(commodityId);
252 }
253
254 public boolean isIllegalOnSubmarket(CargoStackAPI stack, TransferAction action) {
255 if (!stack.isCommodityStack()) return false;
256 return isIllegalOnSubmarket((String) stack.getData(), action);
257 }
258
259 public String getIllegalTransferText(CargoStackAPI stack, TransferAction action) {
260 return "Illegal to trade on the " + submarket.getNameOneLine().toLowerCase() + " here";
261 }
262
263 public boolean isIllegalOnSubmarket(FleetMemberAPI member, TransferAction action) {
264 if (action == TransferAction.PLAYER_SELL && !isBlackMarket() && Misc.isAutomated(member)) {
265 return true;
266 }
267 return false;
268 }
269
270 public String getIllegalTransferText(FleetMemberAPI member, TransferAction action) {
271 //return "Illegal to trade on the " + submarket.getNameOneLine().toLowerCase() + " here";
272 if (action == TransferAction.PLAYER_BUY) {
273 return "Illegal to buy"; // this shouldn't happen
274 } else {
275 if (isFreeTransfer()) {
276 return "Illegal to store";
277 }
278 return "Illegal to sell";
279 }
280 }
281
282
283// protected void addWeapons(int min, int max, int maxTier, WeightedRandomPicker<String> factionPicker) {
284// int num = min + itemGenRandom.nextInt(max - min + 1);
285// for (int i = 0; i < num; i++) {
286// String factionId = factionPicker.pick();
287// addWeapons(1, 1, maxTier, factionId);
288// }
289// }
290
291 protected void addFighters(int min, int max, int maxTier, WeightedRandomPicker<String> factionPicker) {
292 int num = min + itemGenRandom.nextInt(max - min + 1);
293 for (int i = 0; i < num; i++) {
294 String factionId = factionPicker.pick();
295 addFighters(1, 1, maxTier, factionId);
296 }
297 }
298
299 protected void addWeapons(int min, int max, int maxTier, String factionId) {
300 addWeapons(min, max, maxTier, factionId, true);
301 }
302 protected void addWeapons(int min, int max, int maxTier, String factionId, boolean withCategories) {
304 picker.add(factionId);
305 addWeapons(min, max, maxTier, picker, withCategories);
306 }
307
308 protected void addWeapons(int min, int max, int maxTier, WeightedRandomPicker<String> factionPicker) {
309 addWeapons(min, max, maxTier, factionPicker, true);
310 }
311 protected void addWeapons(int min, int max, int maxTier, WeightedRandomPicker<String> factionPicker, boolean withCategories) {
313
319
320 for (int i = 0; i < factionPicker.getItems().size(); i++) {
321 String factionId = factionPicker.getItems().get(i);
322 float w = factionPicker.getWeight(i);
323 if (factionId == null) factionId = market.getFactionId();
324
325 float quality = Misc.getShipQuality(market, factionId);
326 FactionAPI faction = Global.getSector().getFaction(factionId);
327
328 for (String id : faction.getKnownWeapons()) {
330 if (spec.getTier() > maxTier) continue;
331 if (spec.getAIHints().contains(AIHints.SYSTEM)) continue;
332 if (spec.hasTag(Tags.WEAPON_NO_SELL)) continue;
333
334 float p = DefaultFleetInflater.getTierProbability(spec.getTier(), quality);
335 p = 1f; //
336 p *= w;
337 if (faction.getWeaponSellFrequency().containsKey(id)) {
338 p *= faction.getWeaponSellFrequency().get(id);
339 }
340 picker.add(spec, p);
341
342 String cat = spec.getAutofitCategory();
343 if (cat != null && spec.getSize() != WeaponSize.LARGE) {
344 if (CoreAutofitPlugin.PD.equals(cat)) {
345 pd.add(spec, p);
346 } else if (CoreAutofitPlugin.STRIKE.equals(cat)) {
347 strike.add(spec, p);
348 } else if (CoreAutofitPlugin.KINETIC.equals(cat)) {
349 kinetic.add(spec, p);
350 } else if (CoreAutofitPlugin.MISSILE.equals(cat) || CoreAutofitPlugin.ROCKET.equals(cat)) {
351 missile.add(spec, p);
352 } else if (CoreAutofitPlugin.HE.equals(cat) || CoreAutofitPlugin.ENERGY.equals(cat)) {
353 nonKinetic.add(spec, p);
354 }
355 }
356 }
357 }
358
359 int num = min + itemGenRandom.nextInt(max - min + 1);
360
361 if (withCategories) {
362 if (num > 0 && !pd.isEmpty()) {
364 num--;
365 }
366 if (num > 0 && !kinetic.isEmpty()) {
367 pickAndAddWeapons(kinetic);
368 num--;
369 }
370 if (num > 0 && !missile.isEmpty()) {
371 pickAndAddWeapons(missile);
372 num--;
373 }
374 if (num > 0 && !nonKinetic.isEmpty()) {
375 pickAndAddWeapons(nonKinetic);
376 num--;
377 }
378 if (num > 0 && !strike.isEmpty()) {
379 pickAndAddWeapons(strike);
380 num--;
381 }
382 }
383
384
385 for (int i = 0; i < num && !picker.isEmpty(); i++) {
386 pickAndAddWeapons(picker);
387 }
388 }
389
391 WeaponSpecAPI spec = picker.pick();
392 if (spec == null) return;
393
394// int count = 2;
395// switch (spec.getSize()) {
396// case LARGE: count = 2; break;
397// case MEDIUM: count = 4; break;
398// case SMALL: count = 8; break;
399// }
400// count = count + itemGenRandom.nextInt(count + 1) - count/2;
401
402 int count = 1;
403 switch (spec.getSize()) {
404 case LARGE: count = 1; break;
405 case MEDIUM: count = 2; break;
406 case SMALL: count = 3; break;
407 }
408 count = count + itemGenRandom.nextInt(count + 2) - itemGenRandom.nextInt(count + 1);
409 if (count < 1) count = 1;
410 cargo.addWeapons(spec.getWeaponId(), count);
411 }
412
413
414 protected void addFighters(int min, int max, int maxTier, String factionId) {
415 if (factionId == null) factionId = market.getFactionId();
416
417 int num = min + itemGenRandom.nextInt(max - min + 1);
418 float quality = Misc.getShipQuality(market, factionId);
419
420 FactionAPI faction = Global.getSector().getFaction(factionId);
421
423 for (String id : faction.getKnownFighters()) {
425 if (spec == null) {
426 throw new RuntimeException("Fighter wing spec with id [" + id + "] not found");
427 }
428 if (spec.getTier() > maxTier) continue;
429 if (spec.hasTag(Tags.WING_NO_SELL)) continue;
430
431 float p = DefaultFleetInflater.getTierProbability(spec.getTier(), quality);
432 p = 1f;
433 if (faction.getFighterSellFrequency().containsKey(id)) {
434 p *= faction.getFighterSellFrequency().get(id);
435 }
436 picker.add(spec, p);
437 }
438
439 for (int i = 0; i < num && !picker.isEmpty(); i++) {
440 FighterWingSpecAPI spec = picker.pick();
441
442 int count = 2;
443 switch (spec.getRole()) {
444 case ASSAULT: count = 2; break;
445 case BOMBER: count = 2; break;
446 case INTERCEPTOR: count = 4; break;
447 case FIGHTER: count = 3; break;
448 case SUPPORT: count = 2; break;
449 }
450
451 count = count + itemGenRandom.nextInt(count + 1) - count/2;
452
453 cargo.addItems(CargoItemType.FIGHTER_CHIP, spec.getId(), count);
454 }
455 }
456 protected void pruneWeapons(float keepFraction) {
458 for (CargoStackAPI stack : cargo.getStacksCopy()) {
459 if (stack.isWeaponStack() || stack.isFighterWingStack()) {
460 float qty = stack.getSize();
461 if (qty <= 1) {
462 if (itemGenRandom.nextFloat() > keepFraction) {
463 cargo.removeItems(stack.getType(), stack.getData(), 1);
464 }
465 } else {
466 cargo.removeItems(stack.getType(), stack.getData(), Math.round(qty * (1f - keepFraction)));
467 }
468 }
469 }
470 }
471
472 public void addShips(String factionId,
473 float combat,
474 float freighter,
475 float tanker,
476 float transport,
477 float liner,
478 float utility,
479 Float qualityOverride,
480 float qualityMod,
481 ShipPickMode modeOverride,
482 FactionDoctrineAPI doctrineOverride) {
483 addShips(factionId, combat, freighter, tanker, transport, liner, utility, qualityOverride, qualityMod, modeOverride, doctrineOverride, 1000);
484
485 }
486 public void addShips(String factionId,
487 float combat,
488 float freighter,
489 float tanker,
490 float transport,
491 float liner,
492 float utility,
493 Float qualityOverride,
494 float qualityMod,
495 ShipPickMode modeOverride,
496 FactionDoctrineAPI doctrineOverride,
497 int maxShipSize) {
498 FleetParamsV3 params = new FleetParamsV3(
499 market,
501 factionId,
502 null, // qualityOverride
504 combat, // combatPts
505 freighter, // freighterPts
506 tanker, // tankerPts
507 transport, // transportPts
508 liner, // linerPts
509 utility, // utilityPts
510 0f // qualityMod
511 );
512 params.maxShipSize = maxShipSize;
513 params.random = new Random(itemGenRandom.nextLong());
514 params.qualityOverride = Misc.getShipQuality(market, factionId) + qualityMod;
515 if (qualityOverride != null) {
516 params.qualityOverride = qualityOverride + qualityMod;
517 }
518 //params.qualityMod = qualityMod;
519
520 params.withOfficers = false;
521
522 params.forceAllowPhaseShipsEtc = true;
523 params.treatCombatFreighterSettingAsFraction = true;
524
525 params.modeOverride = Misc.getShipPickMode(market, factionId);
526 if (modeOverride != null) {
527 params.modeOverride = modeOverride;
528 }
529
530 params.doctrineOverride = doctrineOverride;
531
533 if (fleet != null) {
534 //float p = 0.5f;
535 //p = 1f;
536
538 FactionAPI faction = Global.getSector().getFaction(factionId);
539 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
540 float f = 1f;
541 if (faction != null) {
542 Float mult = faction.getFactionSpec().getShipSellFrequency().get(member.getHullId());
543 if (mult != null) {
544 f *= mult;
545 }
546 }
547 if (itemGenRandom.nextFloat() > f * 0.5f) continue;
548 if (member.getHullSpec().hasTag(Tags.NO_SELL)) continue;
549 if (!isMilitaryMarket() && member.getHullSpec().hasTag(Tags.MILITARY_MARKET_ONLY)) continue;
550
551 picker.add(member, f);
552 }
553
554 List<FleetMemberAPI> members = new ArrayList<>();
555 while (!picker.isEmpty()) {
556 members.add(picker.pickAndRemove());
557 }
558
559 for (FleetMemberAPI member : members) {
560 //if (itemGenRandom.nextFloat() > p) continue;
561// if (member.getHullSpec().hasTag(Tags.NO_SELL)) continue;
562// if (!isMilitaryMarket() && member.getHullSpec().hasTag(Tags.MILITARY_MARKET_ONLY)) continue;
563 String emptyVariantId = member.getHullId() + "_Hull";
564 addShip(emptyVariantId, true, params.qualityOverride);
565 }
566 }
567 }
568
569 protected FleetMemberAPI addShip(String variantOrWingId, boolean withDmods, float quality) {
570 FleetMemberAPI member = null;
571 if (variantOrWingId.endsWith("_wing")) {
573 } else {
574 member = Global.getFactory().createFleetMember(FleetMemberType.SHIP, variantOrWingId);
575 }
576
577 if (withDmods) {
578 float averageDmods = DefaultFleetInflater.getAverageDmodsForQuality(quality);
579 int addDmods = DefaultFleetInflater.getNumDModsToAdd(member.getVariant(), averageDmods, itemGenRandom);
580 if (addDmods > 0) {
582 DModManager.addDMods(member, true, addDmods, itemGenRandom);
583 }
584 }
585
586 member.getRepairTracker().setMothballed(true);
587 member.getRepairTracker().setCR(0.5f);
588// assignShipName(member, submarket.getFaction().getId());
590 return member;
591 }
592
593// TODO not 100% sure about performance implications, maybe look at this later
594// public void assignShipName(FleetMemberAPI member, String factionId) {
595// CampaignFleetAPI fleet = Global.getFactory().createEmptyFleet(factionId, null, true);
596// fleet.getFleetData().setShipNameRandom(itemGenRandom);
597// fleet.getFleetData().addFleetMember(member);
598// fleet.getFleetData().removeFleetMember(member);
599// }
600
601 protected void pruneShips(float mult) {
604 for (FleetMemberAPI member : data.getMembersListCopy()) {
605 if (itemGenRandom.nextFloat() > mult) {
606 data.removeFleetMember(member);
607 }
608 }
609 }
610
611 protected void addHullMods(int maxTier, int num) {
612 addHullMods(maxTier, num, null);
613 }
614 protected void addHullMods(int maxTier, int num, String factionId) {
615 //float p = Global.getSettings().getFloat("sellHullmodProb");
616
618 for (CargoStackAPI stack : cargo.getStacksCopy()) {
619 if (stack.isModSpecStack()) {
620 cargo.removeStack(stack);
621 }
622 }
623
624 FactionAPI faction = null;
625 if (factionId != null) {
626 faction = Global.getSector().getFaction(factionId);
627 }
628
630 for (String id : submarket.getFaction().getKnownHullMods()) {
631 //if (Global.getSector().getCharacterData().knowsHullMod(id)) continue;
633 if (spec.isHidden()) continue;
634 if (spec.isAlwaysUnlocked()) continue;
635 if (spec.getTier() > maxTier) continue;
636 float p = spec.getRarity();
637 if (faction != null && faction.getHullmodSellFrequency().containsKey(id) &&
639 p *= faction.getHullmodSellFrequency().get(id);
640 }
641// if (Global.getSector().getPlayerFaction().knowsHullMod(id)) {
642// p *= 0.25f;
643// }
644
645 picker.add(spec, p);
646 }
647 //picker.getItems().contains("missile_autoloader");
648 for (int i = 0; i < num; i++) {
649 HullModSpecAPI pick = picker.pickAndRemove();
650 if (pick == null) continue;
651
652 String id = pick.getId();
653 if (cargoAlreadyHasMod(id)) continue;
654
655 if (Global.getSector().getPlayerFaction().knowsHullMod(id)) continue;
656
657 //cargo.addItems(CargoItemType.MOD_SPEC, id, 1);
658
659 cargo.addItems(CargoItemType.SPECIAL, new SpecialItemData(Items.TAG_MODSPEC, id), 1);
660 }
661
662 }
663
664 protected boolean removeModFromCargo(String id) {
666 for (CargoStackAPI stack : cargo.getStacksCopy()) {
667 if (stack.isModSpecStack() && stack.getData().equals(id)) {
668 cargo.removeStack(stack);
669 }
670 }
671 return false;
672 }
673
674 protected boolean cargoAlreadyHasMod(String id) {
676 for (CargoStackAPI stack : cargo.getStacksCopy()) {
677 //if (stack.isModSpecStack() && stack.getData().equals(id)) return true;
678 if (stack.isSpecialStack() && stack.getSpecialDataIfSpecial().getId().equals(Items.TAG_MODSPEC) &&
679 stack.getSpecialDataIfSpecial().getData().equals(id)) return true;
680 }
681 return false;
682 }
683
684
685 public Highlights getIllegalTransferTextHighlights(CargoStackAPI stack, TransferAction action) {
686 return null;
687 }
688
689 public Highlights getIllegalTransferTextHighlights(FleetMemberAPI member, TransferAction action) {
690 return null;
691 }
692
693 public float getMinSWUpdateInterval() {
694 return minSWUpdateInterval;
695 }
696
697 public void setMinSWUpdateInterval(float minCargoUpdateInterval) {
698 this.minSWUpdateInterval = minCargoUpdateInterval;
699 }
700
701 public float getSinceLastCargoUpdate() {
703 }
704
706 this.sinceLastCargoUpdate = sinceLastCargoUpdate;
707 }
708
709 public float getSinceSWUpdate() {
710 return sinceSWUpdate;
711 }
712
713 public void setSinceSWUpdate(float sinceSWUpdate) {
714 this.sinceSWUpdate = sinceSWUpdate;
715 }
716
717 public boolean hasCustomTooltip() {
718 return true;
719 }
720
721 public void createTooltip(CoreUIAPI ui, TooltipMakerAPI tooltip, boolean expanded) {
722 float opad = 10f;
723
724// tooltip.setTitleSmallOrbitron();
725// tooltip.setParaSmallInsignia();
726
728 String desc = submarket.getSpec().getDesc();
729
731
732 String appendix = submarket.getPlugin().getTooltipAppendix(ui);
733 if (appendix != null) desc = desc + "\n\n" + appendix;
734
735 if (desc != null && !desc.isEmpty()) {
736 LabelAPI body = tooltip.addPara(desc, opad);
737
738 if (getTooltipAppendixHighlights(ui) != null) {
740 if (h != null) {
742 body.setHighlight(h.getText());
743 }
744 }
745 }
746
747 createTooltipAfterDescription(tooltip, expanded);
748 }
749
750
751 protected void createTooltipAfterDescription(TooltipMakerAPI tooltip, boolean expanded) {
752
753 }
754
755 public boolean isTooltipExpandable() {
756 return false;
757 }
758
759 public float getTooltipWidth() {
760 return 400f;
761 }
762
763 public boolean isHidden() {
764 return false;
765 }
766
767 public boolean showInFleetScreen() {
768 return true;
769 }
770
771 public boolean showInCargoScreen() {
772 return true;
773 }
774
776 return market;
777 }
778
780 return submarket;
781 }
782
783
785 return 0;
786 }
787
789 return 1f;
790 }
791
793 return true;
794 }
795
796 public void addAndRemoveStockpiledResources(float amount,
797 boolean withShortageCountering,
798 boolean withDecreaseToLimit,
799 boolean withCargoUpdate) {
801 if (com.isNonEcon()) continue;
802 if (com.getCommodity().isMeta()) continue;
803
804 //if (com.getMaxSupply() <= 0 && com.getMaxDemand() <= 0) continue;
805
806// if (market.getId().equals("mazalot") && com.getId().equals("ore")) {
807// System.out.println("wefwefew");
808// }
809// if (com.isIllegal() && com.getMarket().isPlayerOwned()) {
810// System.out.println("wefwefew");
811// }
812 addAndRemoveStockpiledResources(com, amount, withShortageCountering, withDecreaseToLimit, withCargoUpdate);
813 }
814 }
815
816 protected boolean doShortageCountering(CommodityOnMarketAPI com, float amount, boolean withShortageCountering) {
817 return false;
818 }
819
821 boolean withShortageCountering,
822 boolean withDecreaseToLimit,
823 boolean withCargoUpdate) {
824
825// if (com.isIllegal() && com.getMarket().isPlayerOwned()) {
826// System.out.println("wefwefew");
827// }
828
829 float days = Global.getSector().getClock().convertToDays(amount);
830 //if (days <= 0) return;
831
832 if (com.isNonEcon()) return;
833 if (com.getCommodity().isMeta()) return;
834 //if (com.getMaxSupply() <= 0 && com.getMaxDemand() <= 0) return;
835
837 //String modId = "localRes";
838// String modId = submarket.getSpecId();
839//
840// com.getAvailableStat().unmodifyFlat(modId);
841//
842// int demand = com.getMaxDemand();
843// int available = com.getAvailable();
844
845
846 if (withShortageCountering) {
847 withShortageCountering = market.isUseStockpilesForShortages();
848 }
849
850 //if (demand > available && withShortageCountering) {
851 if (doShortageCountering(com, amount, withShortageCountering)) {
852 return;
853 }
854
855 if (!shouldHaveCommodity(com)) {
856 if (withDecreaseToLimit) {
857 //float days = Global.getSector().getClock().convertToDays(amount);
858 float limit = getStockpileLimit(com);
859 float curr = cargo.getCommodityQuantity(com.getId());
860 if (curr > limit && withDecreaseToLimit) {
861 float removeRate = (curr - limit) * 2f / 30f;
862 float removeAmount = removeRate * days;
863
864 if (curr - removeAmount < limit) {
865 removeAmount = curr - limit;
866 }
867 if (removeAmount > 0 && curr <= 1) {
868 removeAmount = 1f;
869 }
870
871 if (removeAmount > 0) {
872 cargo.removeCommodity(com.getId(), removeAmount);
873 }
874 }
875 }
876 return;
877 }
878
879 // add stockpile, up to limit
880 float limit = getStockpileLimit(com);
881 float curr = cargo.getCommodityQuantity(com.getId());
882
883 if (curr < limit && withCargoUpdate) {
884 if (limit <= 0) return;
885
886// if (market.isPlayerOwned() && market.getName().startsWith("Dark")) {
887// System.out.println("wefwef" + market.getName());
888// }
889
890 float addRate = limit / 30f * getStockpilingAddRateMult(com);
891
892 // make it so the player constantly re-checking doesn't keep adding cargo more quickly than it should,
893 // due to having to add at least 1 unit if there's nothing
894 if (sinceLastCargoUpdate * addRate + curr < 1) {
895 return;
896 }
897
898 float addAmount = addRate * days;
899
900
901 if (curr + addAmount > limit) {
902 addAmount = limit - curr;
903 }
904
905 if (addAmount > 0) {
906 float q = cargo.getCommodityQuantity(com.getId()) + addAmount;
907 if (q < 1) {
908 addAmount = 1f; // add at least 1 unit or it won't do anything
909 }
910
911 cargo.addCommodity(com.getId(), addAmount);
912
913// if (market.isPlayerOwned()) {
914// MonthlyReport report = SharedData.getData().getCurrentReport();
915// FDNode node = report.getStockpilingNode(market);
916//
917// CargoAPI tooltipCargo = (CargoAPI) node.custom2;
918// float addToTooltipCargo = addAmount;
919// q = tooltipCargo.getCommodityQuantity(com.getId()) + addToTooltipCargo;
920// if (q < 1) {
921// addToTooltipCargo = 1f; // add at least 1 unit or it won't do anything
922// }
923// tooltipCargo.addCommodity(com.getId(), addToTooltipCargo);
924//
925// float unitPrice = (int) getStockpilingUnitPrice(com);
926// //node.upkeep += unitPrice * addAmount;
927//
928// FDNode comNode = report.getNode(node, com.getId());
929//
930// CommoditySpecAPI spec = com.getCommodity();
931// comNode.icon = spec.getIconName();
932// comNode.upkeep += unitPrice * addAmount;
933// comNode.custom = com;
934//
935// if (comNode.custom2 == null) {
936// comNode.custom2 = 0f;
937// }
938// comNode.custom2 = (Float)comNode.custom2 + addAmount;
939//
940// int qty = (int) Math.max(1, (Float) comNode.custom2);
941// comNode.name = spec.getName() + " " + Strings.X + Misc.getWithDGS(qty);
942// comNode.tooltipCreator = report.getMonthlyReportTooltip();
943//
944// // use price market buys at, i.e. without a markup
945// }
946 }
947
948 return;
949 }
950
951 if (curr > limit && withDecreaseToLimit) {
952 float removeRate = (curr - limit) * 2f / 30f;
953 float removeAmount = removeRate * days;
954
955
956 if (curr - removeAmount < limit) {
957 removeAmount = curr - limit;
958 }
959 if (removeAmount > 0 && curr <= 1) {
960 removeAmount = 1f;
961 }
962
963 if (removeAmount > 0) {
964 cargo.removeCommodity(com.getId(), removeAmount);
965 }
966 return;
967 }
968 }
969
970 public String getTariffTextOverride() {
971 return null;
972 }
973 public String getTariffValueOverride() {
974 return null;
975 }
976 public String getTotalTextOverride() {
977 return null;
978 }
979 public String getTotalValueOverride() {
980 return null;
981 }
982}
983
984
985
986
987
988
989
static SettingsAPI getSettings()
Definition Global.java:57
static FactoryAPI getFactory()
Definition Global.java:41
static SectorAPI getSector()
Definition Global.java:65
static void addDMods(FleetMemberData data, boolean own, CampaignFleetAPI recoverer, Random random)
static boolean setDHull(ShipVariantAPI variant)
static int getNumDModsToAdd(ShipVariantAPI variant, float averageDMods, Random random)
static CampaignFleetAPI createFleet(FleetParamsV3 params)
PlayerTradeDataForSubmarket getPlayerTradeData(SubmarketAPI submarket)
String getIllegalTransferText(CargoStackAPI stack, TransferAction action)
void addShips(String factionId, float combat, float freighter, float tanker, float transport, float liner, float utility, Float qualityOverride, float qualityMod, ShipPickMode modeOverride, FactionDoctrineAPI doctrineOverride)
boolean isIllegalOnSubmarket(FleetMemberAPI member, TransferAction action)
boolean isIllegalOnSubmarket(CargoStackAPI stack, TransferAction action)
void pickAndAddWeapons(WeightedRandomPicker< WeaponSpecAPI > picker)
void createTooltipAfterDescription(TooltipMakerAPI tooltip, boolean expanded)
boolean doShortageCountering(CommodityOnMarketAPI com, float amount, boolean withShortageCountering)
void addWeapons(int min, int max, int maxTier, String factionId, boolean withCategories)
String getIllegalTransferText(FleetMemberAPI member, TransferAction action)
void createTooltip(CoreUIAPI ui, TooltipMakerAPI tooltip, boolean expanded)
void reportPlayerMarketTransaction(PlayerMarketTransaction transaction)
void addFighters(int min, int max, int maxTier, String factionId)
void addAndRemoveStockpiledResources(CommodityOnMarketAPI com, float amount, boolean withShortageCountering, boolean withDecreaseToLimit, boolean withCargoUpdate)
Highlights getIllegalTransferTextHighlights(CargoStackAPI stack, TransferAction action)
void addFighters(int min, int max, int maxTier, WeightedRandomPicker< String > factionPicker)
Highlights getIllegalTransferTextHighlights(FleetMemberAPI member, TransferAction action)
void addShips(String factionId, float combat, float freighter, float tanker, float transport, float liner, float utility, Float qualityOverride, float qualityMod, ShipPickMode modeOverride, FactionDoctrineAPI doctrineOverride, int maxShipSize)
FleetMemberAPI addShip(String variantOrWingId, boolean withDmods, float quality)
void addWeapons(int min, int max, int maxTier, WeightedRandomPicker< String > factionPicker, boolean withCategories)
void addWeapons(int min, int max, int maxTier, WeightedRandomPicker< String > factionPicker)
boolean isIllegalOnSubmarket(String commodityId, TransferAction action)
void addAndRemoveStockpiledResources(float amount, boolean withShortageCountering, boolean withDecreaseToLimit, boolean withCargoUpdate)
void addWeapons(int min, int max, int maxTier, String factionId)
static boolean isAutomated(MutableShipStatsAPI stats)
Definition Misc.java:5491
static float getShipQuality(MarketAPI market)
Definition Misc.java:4505
static ShipPickMode getShipPickMode(MarketAPI market)
Definition Misc.java:4542
CargoAPI createCargo(boolean unlimitedStacks)
FleetMemberAPI createFleetMember(FleetMemberType type, String variantOrWingId)
HullModSpecAPI getHullModSpec(String modId)
FighterWingSpecAPI getFighterWingSpec(String wingId)
WeaponSpecAPI getWeaponSpec(String weaponId)
void removeStack(CargoStackAPI stack)
void addWeapons(String id, int count)
boolean removeItems(CargoAPI.CargoItemType itemType, Object data, float quantity)
void removeCommodity(String id, float quantity)
void initMothballedShips(String factionId)
List< CargoStackAPI > getStacksCopy()
void addItems(CargoAPI.CargoItemType itemType, Object data, float quantity)
void addCommodity(String commodityId, float quantity)
Map< String, Float > getWeaponSellFrequency()
Map< String, Float > getHullmodSellFrequency()
boolean isHostileTo(FactionAPI other)
Map< String, Float > getFighterSellFrequency()
void addFleetMember(FleetMemberAPI member)
void removeFleetMember(FleetMemberAPI member)
List< FleetMemberAPI > getMembersListCopy()
FactionAPI getFaction(String factionId)
Highlights getTooltipAppendixHighlights(CoreUIAPI ui)
void addTradeMod(String source, float quantity, float days)
void addTradeModMinus(String source, float quantity, float days)
void addTradeModPlus(String source, float quantity, float days)
CommodityOnMarketAPI getCommodityData(String commodityId)
List< CommodityOnMarketAPI > getCommoditiesCopy()
boolean isIllegal(String commodityId)
String performTokenReplacement(String ruleId, String text, SectorEntityToken entity, Map< String, MemoryAPI > memoryMap)
void setMothballed(boolean mothballed)
EnumSet< WeaponAPI.AIHints > getAIHints()
void setHighlight(int start, int end)
void setHighlightColors(Color ... colors)
LabelAPI addPara(String format, float pad, Color hl, String... highlights)