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