Starsector API
Loading...
Searching...
No Matches
DefaultFleetInflater.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.fleets;
2
3import java.util.ArrayList;
4import java.util.LinkedHashMap;
5import java.util.LinkedHashSet;
6import java.util.List;
7import java.util.Map;
8import java.util.Random;
9import java.util.Set;
10
11import com.fs.starfarer.api.Global;
12import com.fs.starfarer.api.campaign.CampaignFleetAPI;
13import com.fs.starfarer.api.campaign.CargoAPI;
14import com.fs.starfarer.api.campaign.FactionAPI;
15import com.fs.starfarer.api.campaign.FleetInflater;
16import com.fs.starfarer.api.campaign.econ.SubmarketAPI;
17import com.fs.starfarer.api.characters.MutableCharacterStatsAPI;
18import com.fs.starfarer.api.combat.MutableShipStatsAPI;
19import com.fs.starfarer.api.combat.ShipAPI;
20import com.fs.starfarer.api.combat.ShipVariantAPI;
21import com.fs.starfarer.api.combat.WeaponAPI;
22import com.fs.starfarer.api.combat.WeaponAPI.WeaponSize;
23import com.fs.starfarer.api.fleet.FleetMemberAPI;
24import com.fs.starfarer.api.impl.campaign.DModManager;
25import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
26import com.fs.starfarer.api.impl.campaign.ids.Tags;
27import com.fs.starfarer.api.loading.FighterWingSpecAPI;
28import com.fs.starfarer.api.loading.VariantSource;
29import com.fs.starfarer.api.loading.WeaponSlotAPI;
30import com.fs.starfarer.api.loading.WeaponSpecAPI;
31import com.fs.starfarer.api.plugins.AutofitPlugin.AutofitPluginDelegate;
32import com.fs.starfarer.api.plugins.AutofitPlugin.AvailableFighter;
33import com.fs.starfarer.api.plugins.AutofitPlugin.AvailableWeapon;
34import com.fs.starfarer.api.plugins.impl.CoreAutofitPlugin;
35import com.fs.starfarer.api.util.ListMap;
36import com.fs.starfarer.api.util.Misc;
37import com.fs.starfarer.api.util.WeightedRandomPicker;
38
39public class DefaultFleetInflater implements FleetInflater, AutofitPluginDelegate {
40
41 public static float GOAL_VARIANT_PROBABILITY = 0.5f;
42
43
44 public static class SortedWeapons {
45 protected Map<Integer, WeaponsForTier> tierMap = new LinkedHashMap<Integer, WeaponsForTier>();
46
47 public WeaponsForTier getWeapons(int tier) {
48 WeaponsForTier data = tierMap.get(tier);
49 if (data == null) {
50 data = new WeaponsForTier();
51 tierMap.put(tier, data);
52 }
53 return data;
54 }
55 }
56
57 public static class WeaponsForTier {
58// protected Map<String, List<AvailableWeapon>> catMap = new LinkedHashMap<String, List<AvailableWeapon>>();
59//
60// public List<AvailableWeapon> getWeapons(String cat) {
61// List<AvailableWeapon> list = catMap.get(cat);
62// if (list == null) {
63// list = new ArrayList<AvailableWeapon>();
64// catMap.put(cat, list);
65// }
66// return list;
67// }
68 protected Map<String, WeaponsForSize> catMap = new LinkedHashMap<String, WeaponsForSize>();
69
70 public WeaponsForSize getWeapons(String cat) {
71 WeaponsForSize size = catMap.get(cat);
72 if (size == null) {
73 size = new WeaponsForSize();
74 catMap.put(cat, size);
75 }
76 return size;
77 }
78 }
79
80 public static class WeaponsForSize {
81 protected Map<WeaponSize, List<AvailableWeapon>> sizeMap = new LinkedHashMap<WeaponAPI.WeaponSize, List<AvailableWeapon>>();
82 public List<AvailableWeapon> getWeapons(WeaponSize size) {
83 List<AvailableWeapon> list = sizeMap.get(size);
84 if (list == null) {
85 list = new ArrayList<AvailableWeapon>();
86 sizeMap.put(size, list);
87 }
88 return list;
89 }
90 }
91
92 public static class AvailableFighterImpl implements AvailableFighter {
93 protected FighterWingSpecAPI spec;
94 protected int quantity = 0;
95
96 public AvailableFighterImpl(FighterWingSpecAPI spec, int quantity) {
97 this.spec = spec;
98 this.quantity = quantity;
99 }
100
101 public AvailableFighterImpl(String wingId, int quantity) {
102 spec = Global.getSettings().getFighterWingSpec(wingId);
103 this.quantity = quantity;
104 }
105
106 public String getId() {
107 return spec.getId();
108 }
109 public float getPrice() {
110 return 0;
111 }
112 public int getQuantity() {
113 return quantity;
114 }
115 public CargoAPI getSource() {
116 return null;
117 }
118 public SubmarketAPI getSubmarket() {
119 return null;
120 }
121 public FighterWingSpecAPI getWingSpec() {
122 return spec;
123 }
124 public void setQuantity(int quantity) {
125 this.quantity = quantity;
126 }
127 }
128
129 public static class AvailableWeaponImpl implements AvailableWeapon {
130 protected WeaponSpecAPI spec;
131 protected int quantity = 0;
132 public AvailableWeaponImpl(WeaponSpecAPI spec, int quantity) {
133 this.spec = spec;
134 this.quantity = quantity;
135 }
136
137 public String getId() {
138 return spec.getWeaponId();
139 }
140 public float getPrice() {
141 return 0;
142 }
143 public int getQuantity() {
144 return quantity;
145 }
146 public CargoAPI getSource() {
147 return null;
148 }
149 public SubmarketAPI getSubmarket() {
150 return null;
151 }
152 public WeaponSpecAPI getSpec() {
153 return spec;
154 }
155 public void setQuantity(int quantity) {
156 this.quantity = quantity;
157 }
158
159 protected MutableShipStatsAPI savedCostStats = null;
160 protected float cachedOPCost = -1;
161 public float getOPCost(MutableCharacterStatsAPI stats, MutableShipStatsAPI shipStats) {
162 if (savedCostStats == shipStats && cachedOPCost >= 0) return cachedOPCost;
163
164 cachedOPCost = spec.getOrdnancePointCost(stats, shipStats);
165 savedCostStats = shipStats;
166 return cachedOPCost;
167 }
168 }
169
170// protected float quality = 1f;
171// protected Long seed = null;
172// protected Long timestamp = null;
173// protected Boolean persistent = null;
174// protected ShipPickMode mode = null;
175
177
178 protected transient FleetMemberAPI currMember = null;
179 protected transient ShipVariantAPI currVariant = null;
180 protected transient List<AvailableFighter> fighters;
181 protected transient List<AvailableWeapon> weapons;
182 protected transient List<String> hullmods;
183 protected transient CampaignFleetAPI fleet;
184 protected transient FactionAPI faction;
185
186
188 //this(p.quality, p.seed, p.persistent, p.mode, p.timestamp);
189 this.p = p;
190 }
191// public DefaultFleetInflater(float quality, Long seed, Boolean persistent, ShipPickMode mode, Long timestamp) {
192// this.quality = quality;
193// this.seed = seed;
194// this.persistent = persistent;
195// this.mode = mode;
196// this.timestamp = timestamp;
197// }
198
199
200 public static float getTierProbability(int tier, float quality) {
201 //if (true) return 1f;
202
203// if (tier == 1) return 0.5f + quality;
204// if (tier == 2) return 0.25f + quality * 0.5f;
205// if (tier == 3) return 0.125f + quality * 0.25f;
206
207 //if (tier != 0) return 0f;
208
209// if (tier == 1) return Math.min(0.9f, 0.5f + quality);
210// if (tier == 2) return Math.min(0.9f, 0.25f + quality * 0.5f);
211// if (tier == 3) return Math.min(0.9f, 0.125f + quality * 0.25f);
212
213 // since whether to upgrade or not is now randomized, higher probability of
214 // better tier weapons being available (as they may still not end up being used)
215 if (tier == 1) return Math.min(0.9f, 0.75f + quality);
216 if (tier == 2) return Math.min(0.9f, 0.5f + quality * 0.5f);
217 if (tier == 3) return Math.min(0.9f, 0.25f + quality * 0.25f);
218
219 return 1f;
220 }
221
222
223 public void inflate(CampaignFleetAPI fleet) {
224 Random random = new Random();
225 //p.seed = null;
226 if (p.seed != null) random = new Random(p.seed);
227
228 //p.quality = 2f;
229
230 //random = new Random();
231
232
233 Random dmodRandom = new Random();
234 if (p.seed != null) dmodRandom = Misc.getRandom(p.seed, 5);
235
236 CoreAutofitPlugin auto = new CoreAutofitPlugin(fleet.getCommander());
237 auto.setRandom(random);
238
239 boolean upgrade = random.nextFloat() < Math.min(0.1f + p.quality * 0.5f, 0.5f);
240 auto.setChecked(CoreAutofitPlugin.UPGRADE, upgrade);
241
242 //auto.setChecked(CoreAutofitPlugin.RANDOMIZE, true);
243 //auto.getOptions().get(4).checked = true; // upgrade
244
245 this.fleet = fleet;
246 this.faction = fleet.getFaction();
247 if (p.factionId != null) {
248 this.faction = Global.getSector().getFaction(p.factionId);
249 }
250
251 //this.faction = Global.getSector().getFaction(Factions.HEGEMONY);
252
253 hullmods = new ArrayList<String>(faction.getKnownHullMods());
254
255// fighters = new ArrayList<AvailableFighter>();
256// for (String wingId : faction.getKnownFighters()) {
257// fighters.add(new AvailableFighterImpl(wingId, 1000));
258// }
259
260 SortedWeapons nonPriorityWeapons = new SortedWeapons();
261 SortedWeapons priorityWeapons = new SortedWeapons();
262
263
264 Set<String> weaponCategories = new LinkedHashSet<String>();
265 for (String weaponId : faction.getKnownWeapons()) {
266 if (!faction.isWeaponKnownAt(weaponId, p.timestamp)) continue;
267
268 WeaponSpecAPI spec = Global.getSettings().getWeaponSpec(weaponId);
269 //if (mode == ShipPickMode.IMPORTED && !spec.hasTag(Items.TAG_BASE_BP)) continue;
270
271 if (spec == null) {
272 throw new RuntimeException("Weapon with spec id [" + weaponId + "] not found");
273 }
274
275 int tier = spec.getTier();
276 String cat = spec.getAutofitCategory();
277
278 if (isPriority(spec)) {
279 List<AvailableWeapon> list = priorityWeapons.getWeapons(tier).getWeapons(cat).getWeapons(spec.getSize());
280 list.add(new AvailableWeaponImpl(spec, 1000));
281 } else {
282 List<AvailableWeapon> list = nonPriorityWeapons.getWeapons(tier).getWeapons(cat).getWeapons(spec.getSize());
283 list.add(new AvailableWeaponImpl(spec, 1000));
284 }
285 weaponCategories.add(cat);
286 }
287
288 ListMap<AvailableFighter> nonPriorityFighters = new ListMap<AvailableFighter>();
289 ListMap<AvailableFighter> priorityFighters = new ListMap<AvailableFighter>();
290 Set<String> fighterCategories = new LinkedHashSet<String>();
291 for (String wingId : faction.getKnownFighters()) {
292 if (!faction.isFighterKnownAt(wingId, p.timestamp)) continue;
293
294 FighterWingSpecAPI spec = Global.getSettings().getFighterWingSpec(wingId);
295 if (spec == null) {
296 throw new RuntimeException("Fighter wing with spec id [" + wingId + "] not found");
297 }
298
299 //if (mode == ShipPickMode.IMPORTED && !spec.hasTag(Items.TAG_BASE_BP)) continue;
300 //int tier = spec.getTier();
301 String cat = spec.getAutofitCategory();
302// if (cat == null) {
303// System.out.println("wfewfwe");
304// }
305 if (isPriority(spec)) {
306 priorityFighters.add(cat, new AvailableFighterImpl(spec, 1000));
307 } else {
308 nonPriorityFighters.add(cat, new AvailableFighterImpl(spec, 1000));
309 }
310 fighterCategories.add(cat);
311 }
312
313
314 //float averageDmods = (1f - quality) / Global.getSettings().getFloat("qualityPerDMod");
315 float averageDmods = getAverageDmodsForQuality(p.quality);
316
317 //System.out.println("Quality: " + quality + ", Average: " + averageDmods);
318
319 boolean forceAutofit = fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.MEMORY_KEY_FORCE_AUTOFIT_ON_NO_AUTOFIT_SHIPS);
320 int memberIndex = 0;
321 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
322
323 if (!forceAutofit && member.getHullSpec().hasTag(Tags.TAG_NO_AUTOFIT)) {
324 continue;
325 }
326 if (!forceAutofit && member.getVariant() != null && member.getVariant().hasTag(Tags.TAG_NO_AUTOFIT)) {
327 continue;
328 }
329
330 if (!faction.isPlayerFaction()) {
331 if (!forceAutofit && member.getHullSpec().hasTag(Tags.TAG_NO_AUTOFIT_UNLESS_PLAYER)) {
332 continue;
333 }
334 if (!forceAutofit && member.getVariant() != null && member.getVariant().hasTag(Tags.TAG_NO_AUTOFIT_UNLESS_PLAYER)) {
335 continue;
336 }
337 }
338
339 // need this so that when reinflating a fleet that lost members, the members reinflate consistently
340 if (p.seed != null) {
341 int extra = member.getShipName().hashCode();
342 random = new Random(p.seed * extra);
343 auto.setRandom(random);
344 dmodRandom = Misc.getRandom(p.seed * extra, 5);
345 }
346
347 List<WeaponSize> sizes = new ArrayList<WeaponAPI.WeaponSize>();
348 sizes.add(WeaponSize.SMALL);
349 sizes.add(WeaponSize.MEDIUM);
350 sizes.add(WeaponSize.LARGE);
351
352 weapons = new ArrayList<AvailableWeapon>();
353 for (String cat : weaponCategories) {
354 for (WeaponSize size : sizes) {
355 boolean foundSome = false;
356 for (int tier = 0; tier < 4; tier++) {
357 float p = getTierProbability(tier, this.p.quality);
358 if (this.p.allWeapons != null && this.p.allWeapons) {
359 p = 1f;
360 }
361
362 List<AvailableWeapon> priority = priorityWeapons.getWeapons(tier).getWeapons(cat).getWeapons(size);
363 List<AvailableWeapon> nonPriority = nonPriorityWeapons.getWeapons(tier).getWeapons(cat).getWeapons(size);
364
365 if (!foundSome) {
366 p = 1f;
367 }
368
369 boolean tierAvailable = random.nextFloat() < p;
370 if (!tierAvailable && foundSome) continue;
371 //if (random.nextFloat() >= p) continue;
372
373 int num = 2;
374 switch (size) {
375 case LARGE: num = 2; break;
376 case MEDIUM: num = 2; break;
377 case SMALL: num = 2; break;
378 }
379// if (!tierAvailable) {
380// num = 1;
381// }
382
383 if (this.p.allWeapons != null && this.p.allWeapons) {
384 num = 500;
385 }
386
387 Set<Integer> picks = makePicks(num, priority.size(), random);
388 for (Integer index : picks) {
389 AvailableWeapon w = priority.get(index);
390 weapons.add(w);
391 foundSome = true;
392 }
393
394 num -= picks.size();
395 if (num > 0) {
396 picks = makePicks(num, nonPriority.size(), random);
397 for (Integer index : picks) {
398 AvailableWeapon w = nonPriority.get(index);
399 weapons.add(w);
400 foundSome = true;
401 }
402 }
403 }
404 }
405 }
406
407 fighters = new ArrayList<AvailableFighter>();
408 for (String cat : fighterCategories) {
409 List<AvailableFighter> priority = priorityFighters.get(cat);
410
411 boolean madePriorityPicks = false;
412 if (priority != null) {
413 int num = random.nextInt(2) + 1;
414 if (this.p.allWeapons != null && this.p.allWeapons) {
415 num = 100;
416 }
417
418 Set<Integer> picks = makePicks(num, priority.size(), random);
419 for (Integer index : picks) {
420 AvailableFighter f = priority.get(index);
421 fighters.add(f);
422 madePriorityPicks = true;
423 }
424 }
425
426 if (!madePriorityPicks) {
427 int num = random.nextInt(2) + 1;
428 if (this.p.allWeapons != null && this.p.allWeapons) {
429 num = 100;
430 }
431
432 List<AvailableFighter> nonPriority = nonPriorityFighters.get(cat);
433 Set<Integer> picks = makePicks(num, nonPriority.size(), random);
434 for (Integer index : picks) {
435 AvailableFighter f = nonPriority.get(index);
436 fighters.add(f);
437 }
438 }
439 }
440
441
442 ShipVariantAPI target = member.getVariant();
443 if (target.getOriginalVariant() != null) {
444 // needed if inflating the same fleet repeatedly to pick up weapon availability changes etc
445 target = Global.getSettings().getVariant(target.getOriginalVariant());
446 }
447
448 if (faction.isPlayerFaction()) {
449 if (random.nextFloat() < GOAL_VARIANT_PROBABILITY) {
450 List<ShipVariantAPI> targets = Global.getSector().getAutofitVariants().getTargetVariants(member.getHullId());
451 WeightedRandomPicker<ShipVariantAPI> alts = new WeightedRandomPicker<ShipVariantAPI>(random);
452 for (ShipVariantAPI curr : targets) {
453 if (curr.getHullSpec().getHullId().equals(target.getHullSpec().getHullId())) {
454 alts.add(curr);
455 }
456 }
457 if (!alts.isEmpty()) {
458 target = alts.pick();
459 }
460 }
461 }
462
463
464 currVariant = Global.getSettings().createEmptyVariant(fleet.getId() + "_" + memberIndex, target.getHullSpec());
465 currMember = member;
466
467 if (target.isStockVariant()) {
468 currVariant.setOriginalVariant(target.getHullVariantId());
469 }
470
471 float rProb = faction.getDoctrine().getAutofitRandomizeProbability();
472 if (p.rProb != null) rProb = p.rProb;
473 boolean randomize = random.nextFloat() < rProb;
474 if (member.isStation()) randomize = false;
475 auto.setChecked(CoreAutofitPlugin.RANDOMIZE, randomize);
476
477 memberIndex++;
478
479 int maxSmods = 0;
480 if (p.averageSMods != null && !member.isCivilian()) {
481 maxSmods = getMaxSMods(currVariant, p.averageSMods, dmodRandom) - currVariant.getSMods().size();
482 }
483 auto.doFit(currVariant, target, maxSmods, this);
484 currVariant.setSource(VariantSource.REFIT);
485 member.setVariant(currVariant, false, false);
486
487 //int dmods = (int) Math.round(averageDmods + dmodRandom.nextFloat() * 2f - 1f);
488// int dmods = (int) Math.round(averageDmods + dmodRandom.nextFloat() * 3f - 2f);
489// if (dmods > 5) dmods = 5;
490// int dmodsAlready = DModManager.getNumDMods(currVariant);
491// dmods -= dmodsAlready;
492// if (dmods > 0) {
493// DModManager.setDHull(currVariant);
494// DModManager.addDMods(member, true, dmods, dmodRandom);
495// }
496
497 if (!currMember.isStation()) {
498 int addDmods = getNumDModsToAdd(currVariant, averageDmods, dmodRandom);
499 if (addDmods > 0) {
501 DModManager.addDMods(member, true, addDmods, dmodRandom);
502 }
503 }
504 }
505
506
507 fleet.getFleetData().setSyncNeeded();
508 fleet.getFleetData().syncIfNeeded();
509
510 // handled in the method that calls inflate()
511 //ListenerUtil.reportFleetInflated(fleet, this);
512 }
513
514 public static int getNumDModsToAdd(ShipVariantAPI variant, float averageDMods, Random random) {
515 int dmods = (int) Math.round(averageDMods + random.nextDouble() * 3f - 2f);
516 if (dmods > 5) dmods = 5;
517 int dmodsAlready = DModManager.getNumDMods(variant);
518 dmods -= dmodsAlready;
519
520 return Math.max(0, dmods);
521 }
522
523 public static int getMaxSMods(ShipVariantAPI variant, int averageSMods, Random random) {
524 float f = random.nextFloat();
525 int sMods = averageSMods;
526 if (f < 0.25f) {
527 sMods = averageSMods - 1;
528 } else if (f < 0.5f) {
529 sMods = averageSMods + 1;
530 }
531 if (sMods > 3) sMods = 3;
532 if (sMods < 0) sMods = 0;
533 return sMods;
534 }
535
536 public static float getAverageDmodsForQuality(float quality) {
537 float averageDmods = (1f - quality) / Global.getSettings().getFloat("qualityPerDMod");
538 return averageDmods;
539 }
540
541
542 public static Set<Integer> makePicks(int num, int max, Random random) {
543 if (num > max) num = max;
544 Set<Integer> result = new LinkedHashSet<Integer>();
545 if (num == 0) return result;
546
547 if (num == max) {
548 for (int i = 0; i < max; i++) {
549 result.add(i);
550 }
551 return result;
552 }
553
554 while (result.size() < num) {
555 int add = random.nextInt(max);
556 result.add(add);
557 }
558
559 return result;
560 }
561
562
563 public boolean removeAfterInflating() {
564 return p.persistent == null || !p.persistent;
565 }
566
568 p.persistent = !removeAfterInflating;
569 if (!p.persistent) p.persistent = null;
570 }
571
572 public void clearFighterSlot(int index, ShipVariantAPI variant) {
573 variant.setWingId(index, null);
574 for (AvailableFighter curr : fighters) {
575 if (curr.getId().equals(curr.getId())) {
576 curr.setQuantity(curr.getQuantity() + 1);
577 break;
578 }
579 }
580 }
581
582 public void clearWeaponSlot(WeaponSlotAPI slot, ShipVariantAPI variant) {
583 variant.clearSlot(slot.getId());
584 for (AvailableWeapon curr : weapons) {
585 if (curr.getId().equals(curr.getId())) {
586 curr.setQuantity(curr.getQuantity() + 1);
587 break;
588 }
589 }
590 }
591
592 public void fitFighterInSlot(int index, AvailableFighter fighter, ShipVariantAPI variant) {
593 fighter.setQuantity(fighter.getQuantity() - 1);
594 variant.setWingId(index, fighter.getId());
595 }
596
597 public void fitWeaponInSlot(WeaponSlotAPI slot, AvailableWeapon weapon, ShipVariantAPI variant) {
598 weapon.setQuantity(weapon.getQuantity() - 1);
599 variant.addWeapon(slot.getId(), weapon.getId());
600 }
601
602 public List<AvailableFighter> getAvailableFighters() {
603 return fighters;
604 }
605
606 public List<AvailableWeapon> getAvailableWeapons() {
607 return weapons;
608 }
609
610 public List<String> getAvailableHullmods() {
611 return hullmods;
612 }
613
614 public ShipAPI getShip() {
615 return null;
616 }
617
618
619// public void syncUIWithVariant() {
620// syncUIWithVariant(null);
621// }
622 public void syncUIWithVariant(ShipVariantAPI variant) {
623
624 }
625
626 public boolean isPriority(WeaponSpecAPI weapon) {
627 return faction.isWeaponPriority(weapon.getWeaponId());
628 }
629
630 public boolean isPriority(FighterWingSpecAPI wing) {
631 return faction.isFighterPriority(wing.getId());
632 }
633
634 public FleetMemberAPI getMember() {
635 return currMember;
636 }
637
638
639 public static void main(String[] args) {
640
641 Random random = new Random();
642
643
644 float total = 0f;
645 float num = 1000f;
646 int []counts = new int[10];
647 for (int i = 0; i < num; i++) {
648 int dmods = 1;
649 total += dmods;
650 counts[dmods]++;
651 }
652
653 System.out.println("Average dmods: " + total / num);
654 for (int i = 0; i <= 5; i++) {
655 System.out.println(i + ":" + counts[i]);
656 }
657 }
658 public FactionAPI getFaction() {
659 return faction;
660 }
661 public Long getSeed() {
662 return p.seed;
663 }
664 public void setSeed(Long seed) {
665 this.p.seed = seed;
666 }
667 public Boolean getPersistent() {
668 return p.persistent;
669 }
670 public void setPersistent(Boolean persistent) {
671 this.p.persistent = persistent;
672 }
673 public float getQuality() {
674 return p.quality;
675 }
676 public int getAverageNumSMods() {
677 return p.averageSMods == null ? 0 : p.averageSMods;
678 }
679 public void setQuality(float quality) {
680 this.p.quality = quality;
681 }
682 public Long getTimestamp() {
683 return p.timestamp;
684 }
685 public void setTimestamp(Long timestamp) {
686 this.p.timestamp = timestamp;
687 }
688 public Object getParams() {
689 return p;
690 }
691
692
693 public boolean canAddRemoveHullmodInPlayerCampaignRefit(String modId) {
694 return true;
695 }
696
697 public boolean isPlayerCampaignRefit() {
698 return false;
699 }
700
701
702 public boolean isAllowSlightRandomization() {
703 return true;
704 }
705}
static SettingsAPI getSettings()
Definition Global.java:51
static SectorAPI getSector()
Definition Global.java:59
static void addDMods(FleetMemberData data, boolean own, CampaignFleetAPI recoverer, Random random)
static boolean setDHull(ShipVariantAPI variant)
static int getNumDMods(ShipVariantAPI variant)
static int getNumDModsToAdd(ShipVariantAPI variant, float averageDMods, Random random)
void clearWeaponSlot(WeaponSlotAPI slot, ShipVariantAPI variant)
static int getMaxSMods(ShipVariantAPI variant, int averageSMods, Random random)
void fitFighterInSlot(int index, AvailableFighter fighter, ShipVariantAPI variant)
static Set< Integer > makePicks(int num, int max, Random random)
void fitWeaponInSlot(WeaponSlotAPI slot, AvailableWeapon weapon, ShipVariantAPI variant)
ShipVariantAPI getVariant(String variantId)
ShipVariantAPI createEmptyVariant(String hullVariantId, ShipHullSpecAPI hullSpec)
FighterWingSpecAPI getFighterWingSpec(String wingId)
WeaponSpecAPI getWeaponSpec(String weaponId)