Starsector API
Loading...
Searching...
No Matches
MiscellaneousThemeGenerator.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.procgen.themes;
2
3import java.util.ArrayList;
4import java.util.Arrays;
5import java.util.Collections;
6import java.util.Comparator;
7import java.util.HashSet;
8import java.util.List;
9import java.util.Set;
10
11import org.lwjgl.util.vector.Vector2f;
12
13import com.fs.starfarer.api.EveryFrameScript;
14import com.fs.starfarer.api.Global;
15import com.fs.starfarer.api.campaign.CampaignFleetAPI;
16import com.fs.starfarer.api.campaign.CargoAPI;
17import com.fs.starfarer.api.campaign.CustomEntitySpecAPI;
18import com.fs.starfarer.api.campaign.JumpPointAPI;
19import com.fs.starfarer.api.campaign.PlanetAPI;
20import com.fs.starfarer.api.campaign.SectorEntityToken;
21import com.fs.starfarer.api.campaign.StarSystemAPI;
22import com.fs.starfarer.api.fleet.FleetMemberAPI;
23import com.fs.starfarer.api.impl.campaign.CoronalTapParticleScript;
24import com.fs.starfarer.api.impl.campaign.DerelictShipEntityPlugin;
25import com.fs.starfarer.api.impl.campaign.DerelictShipEntityPlugin.DerelictShipData;
26import com.fs.starfarer.api.impl.campaign.econ.impl.PlanetaryShield;
27import com.fs.starfarer.api.impl.campaign.fleets.DefaultFleetInflater;
28import com.fs.starfarer.api.impl.campaign.fleets.DefaultFleetInflaterParams;
29import com.fs.starfarer.api.impl.campaign.ids.Commodities;
30import com.fs.starfarer.api.impl.campaign.ids.Conditions;
31import com.fs.starfarer.api.impl.campaign.ids.Entities;
32import com.fs.starfarer.api.impl.campaign.ids.Factions;
33import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
34import com.fs.starfarer.api.impl.campaign.ids.Planets;
35import com.fs.starfarer.api.impl.campaign.ids.StarTypes;
36import com.fs.starfarer.api.impl.campaign.ids.Submarkets;
37import com.fs.starfarer.api.impl.campaign.ids.Tags;
38import com.fs.starfarer.api.impl.campaign.ids.Terrain;
39import com.fs.starfarer.api.impl.campaign.procgen.Constellation;
40import com.fs.starfarer.api.impl.campaign.procgen.DefenderDataOverride;
41import com.fs.starfarer.api.impl.campaign.procgen.NameGenData;
42import com.fs.starfarer.api.impl.campaign.procgen.PlanetConditionGenerator;
43import com.fs.starfarer.api.impl.campaign.procgen.PlanetGenDataSpec;
44import com.fs.starfarer.api.impl.campaign.procgen.ProcgenUsedNames;
45import com.fs.starfarer.api.impl.campaign.procgen.ProcgenUsedNames.NamePick;
46import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator;
47import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator.StarSystemType;
48import com.fs.starfarer.api.impl.campaign.procgen.themes.SalvageSpecialAssigner.ShipRecoverySpecialCreator;
49import com.fs.starfarer.api.impl.campaign.procgen.themes.SalvageSpecialAssigner.SpecialCreationContext;
50import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.ShipRecoverySpecial.PerShipData;
51import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.ShipRecoverySpecial.ShipCondition;
52import com.fs.starfarer.api.impl.campaign.terrain.AsteroidFieldTerrainPlugin.AsteroidFieldParams;
53import com.fs.starfarer.api.util.Misc;
54import com.fs.starfarer.api.util.WeightedRandomPicker;
55
56
58
59 public static String PK_SYSTEM_KEY = "$core_pkSystem";
60 public static String PK_PLANET_KEY = "$core_pkPlanet";
61 public static String PK_CACHE_KEY = "$core_pkCache";
62 public static String PK_NEXUS_KEY = "$core_pkNexus";
63
64 public static String PLANETARY_SHIELD_PLANET_KEY = "$core_planetaryShieldPlanet";
65 public static String PLANETARY_SHIELD_PLANET = "$psi_planet";
66
67 public static String LOCR_BLOCK_FIRST_SURVEY = "$locr_blockFirstSurvey";
68 public static String LOCR_LUDDIC_PLANET_KEY = "$locr_luddicPlanet";
69 public static String LOCR_LUDDIC_TRANSPORT_KEY = "$locr_luddicTransport";
70 public static String LOCR_LUDDIC = "$locr_luddic";
71 public static String LOCR_MINERS_PLANET_KEY = "$locr_minersPlanet";
72 public static String LOCR_MINERS = "$locr_miners";
73 //public static String LOCR_UTOPIA_PLANET_KEY = "$locr_utopiaPlanet";
74 //public static String LOCR_UTOPIA = "$locr_utopia";
75 public static String LOCR_PIRATE_PLANET_KEY = "$locr_piratePlanet";
76 public static String LOCR_PIRATE = "$locr_pirate";
77
78 public static float PROB_TO_ADD_SOMETHING = 0.5f;
79
80 public static int MIN_GATES = Global.getSettings().getInt("minNonCoreGatesInSector");
81 public static int MAX_GATES = Global.getSettings().getInt("maxNonCoreGatesInSector");
82 public static int MIN_GATES_TO_ADD = Global.getSettings().getInt("minGatesToAddOnSecondPass");
83
84
85 public String getThemeId() {
86 return Themes.MISC;
87 }
88
89 @Override
90 public float getWeight() {
91 return 0f;
92 }
93
94 @Override
95 public int getOrder() {
96 return 1000000;
97 }
98
99 @Override
100 public void generateForSector(ThemeGenContext context, float allowedUnusedFraction) {
101
102 if (DEBUG) System.out.println("\n\n\n");
103 if (DEBUG) System.out.println("Generating misc derelicts etc in all systems");
104 //getSortedAvailableConstellations(context, true, new Vector2f(), null).size()
105 List<StarSystemData> all = new ArrayList<StarSystemData>();
106
107 /* this adds misc stuff to systems that are:
108 1) Not tagged with some other theme
109 2) But does add misc stuff to derelict-tagged systems
110 So, basicallly it covers:
111 derelict theme + whatever few constellations didn't get anything from any theme
112 */
113 for (Constellation c : context.constellations) {
114 String theme = context.majorThemes.get(c);
115
116 List<StarSystemData> systems = new ArrayList<StarSystemData>();
117 for (StarSystemAPI system : c.getSystems()) {
118 StarSystemData data = computeSystemData(system);
119 systems.add(data);
120 }
121
122 for (StarSystemData data : systems) {
123 //if (data.system.getName().toLowerCase().contains("alpha mok morred")) {
124// if (data.system.getName().toLowerCase().contains("vasuki")) {
125// System.out.println("efwefwef");
126// }
127 boolean derelict = data.system.hasTag(Tags.THEME_DERELICT);
128 if (!derelict && theme != null && !data.system.getTags().isEmpty()) continue;
129// if (!derelict && theme != null && !theme.equals(Themes.DERELICTS) &&
130// !theme.equals(Themes.NO_THEME)) continue;
131
132 if (random.nextFloat() > PROB_TO_ADD_SOMETHING || (derelict && theme != null)) {
133 data.system.addTag(Tags.THEME_MISC_SKIP);
134 continue;
135 }
136
137 populateNonMain(data);
138 all.add(data);
139 data.system.addTag(Tags.THEME_MISC);
140 data.system.addTag(Tags.THEME_INTERESTING_MINOR);
141 }
142 }
143
144
145 SpecialCreationContext specialContext = new SpecialCreationContext();
146 specialContext.themeId = getThemeId();
147 SalvageSpecialAssigner.assignSpecials(all, specialContext);
148
149 if (DEBUG) System.out.println("Finished generating misc derelicts\n\n\n\n\n");
150
151
152 addDerelicts(context, "legion_xiv_Elite", 2, 3, 1, 2, Tags.THEME_REMNANT);
153 addDerelicts(context, "phantom_Elite", 1, 2, 0, 1, Tags.THEME_REMNANT, Tags.THEME_RUINS, Tags.THEME_DERELICT, Tags.THEME_UNSAFE);
154 addDerelicts(context, "revenant_Elite", 1, 2, 0, 1, Tags.THEME_REMNANT, Tags.THEME_RUINS, Tags.THEME_DERELICT, Tags.THEME_UNSAFE);
155
156
157 addRedPlanet(context);
158 addPKSystem(context);
160
161 addCoronalTaps(context);
162
163 addExtraGates(context);
164
165 addLOCRPiratePlanet(context);
166 addLOCRLuddicPlanet(context);
167 //addLOCRUtopiaPlanet(context);
168 addLOCRMinersPlanet(context);
169 }
170
171 protected void addRedPlanet(ThemeGenContext context) {
172 if (DEBUG) System.out.println("Looking for planetary shield planet");
173
174 PlanetAPI bestHab = null;
175 PlanetAPI bestNonHab = null;
176// OrbitGap gapHab = null;
177// OrbitGap gapNonHab = null;
178 float habDist = 0;
179 float nonHabDist = 0;
180
181 // looking for a habitable planet furthest from the Sector's center, with a bit of
182 // a random factor
183 int systemsChecked = 0;
184 for (Constellation c : context.constellations) {
185 for (StarSystemAPI system : c.getSystems()) {
186 if (system.hasTag(Tags.THEME_SPECIAL)) continue;
187
188 if (!system.hasTag(Tags.THEME_MISC_SKIP) &&
189 !system.hasTag(Tags.THEME_MISC)) {
190 continue;
191 }
192 //[theme_derelict, theme_derelict_probes, theme_misc_skip, theme_derelict_survey_ship]
193 if (system.hasTag(Tags.THEME_DERELICT)) {
194 continue;
195 }
196
197 systemsChecked++;
198
199 for (PlanetAPI curr : system.getPlanets()) {
200 if (curr.isStar()) continue;
201 if (curr.isMoon()) continue;
202 if (!curr.getMarket().isPlanetConditionMarketOnly()) continue;
203
204 if (curr.hasTag(Tags.NOT_RANDOM_MISSION_TARGET)) continue;
205
206 float dist = system.getLocation().length() + random.nextFloat() * 6000;
207 if (curr.getMarket().hasCondition(Conditions.HABITABLE)) {
208 if (dist > habDist) {
209// List<OrbitGap> gaps = findGaps(curr, 50f, 500f, 100f);
210// if (!gaps.isEmpty()) {
211 habDist = dist;
212 bestHab = curr;
213// gapHab = gaps.get(0);
214// }
215 }
216 } else {
217 if (dist > nonHabDist) {
218// List<OrbitGap> gaps = findGaps(curr, 50f, 500f, 100f);
219// if (!gaps.isEmpty()) {
220 nonHabDist = dist;
221 bestNonHab = curr;
222// gapNonHab = gaps.get(0);
223// }
224 }
225 }
226 }
227 }
228 }
229
230 PlanetAPI planet = bestHab;
231 //OrbitGap gap = gapHab;
232 if (planet == null) {
233 planet = bestNonHab;
234 //gap = gapNonHab;
235 }
236
237 if (planet != null) {
238 if (DEBUG) System.out.println("Adding Planetary Shield to [" + planet.getName() + "] in [" + planet.getContainingLocation().getNameWithLowercaseType() + "]");
243
244 long seed = StarSystemGenerator.random.nextLong();
248 //planet.addTag(Tags.SALVAGEABLE);
249
250// SectorEntityToken beacon = Misc.addWarningBeacon(planet, gap, Tags.BEACON_HIGH);
251// beacon.getMemoryWithoutUpdate().set(PLANETARY_SHIELD_BEACON, true);
252// beacon.getMemoryWithoutUpdate().set(MemFlags.SALVAGE_SEED, seed);
253
254 } else {
255 if (DEBUG) System.out.println("Failed to find a planet in remnant systems");
256 }
257 if (DEBUG) System.out.println("Finished adding Planetary Shield planet\n\n\n\n\n");
258 }
259
260 protected void addDerelicts(ThemeGenContext context, String variant,
261 int minNonSalvageable, int maxNonSalvageable,
262 int minSalvageable, int maxSalvageable,
263 String ... allowedThemes) {
264 if (Global.getSettings().getVariant(variant) != null) {
265 if (DEBUG) System.out.println("Adding " + variant + " to star systems");
266
267 Set<String> tags = new HashSet<String>(Arrays.asList(allowedThemes));
268
269 int numSalvageable = minSalvageable + random.nextInt(maxSalvageable - minSalvageable + 1);
270 int numNonSalvageable = minNonSalvageable + random.nextInt(maxNonSalvageable - minNonSalvageable + 1);
271
272 List<Constellation> list = new ArrayList<Constellation>(context.constellations);
273 Collections.shuffle(list, random);
274
275 List<StarSystemData> systems = new ArrayList<StarSystemData>();
276 for (Constellation c : list) {
277 for (StarSystemAPI system : c.getSystems()) {
278 StarSystemData data = computeSystemData(system);
279 systems.add(data);
280 }
281 }
282
283 Collections.shuffle(systems, random);
284 for (StarSystemData data : systems) {
285 boolean matches = false;
286 for (String tag : data.system.getTags()) {
287 if (tags.contains(tag)) {
288 matches = true;
289 break;
290 }
291 }
292 if (!matches) continue;
293
294 EntityLocation loc = pickAnyLocation(random, data.system, 70f, null);
295 AddedEntity ae = addDerelictShip(data, loc, variant);
296 if (ae != null) {
297 if (numSalvageable > 0) {
298 numSalvageable--;
299 ShipRecoverySpecialCreator creator = new ShipRecoverySpecialCreator(random, 0, 0, false, null, null);
300 Object specialData = creator.createSpecial(ae.entity, new SpecialCreationContext());
301 if (specialData != null) {
302 Misc.setSalvageSpecial(ae.entity, specialData);
303 }
304 } else {
305 numNonSalvageable--;
306 SalvageSpecialAssigner.assignSpecials(ae.entity, true);
307 }
308 if (DEBUG) System.out.println(" Added " + variant + " to " + data.system + "\n");
309 }
310 if (numSalvageable + numNonSalvageable <= 0) break;
311 }
312 //if (numSalvageable + numNonSalvageable <= 0) break;
313
314 if (DEBUG) System.out.println("Finished adding " + variant + " to star systems\n\n\n\n\n");
315 }
316 }
317
318
320
321 int num = 2 + random.nextInt(3);
322
323 //System.out.println("RANDOM CHECK: " + random.nextLong());
324
325 if (DEBUG) System.out.println("Adding up to " + num + " solar shades and mirrors");
326 List<Constellation> list = new ArrayList<Constellation>(context.constellations);
328 for (Constellation c : list) {
329 for (StarSystemAPI system : c.getSystems()) {
330 if (system.hasTag(Tags.THEME_CORE)) continue;
331 if (system.isNebula()) continue;
332
333 for (PlanetAPI planet : system.getPlanets()) {
334 if (planet.isStar()) continue;
335
336 SectorEntityToken focus = planet.getOrbitFocus();
337 if (!(focus instanceof PlanetAPI)) continue;
338 if (!((PlanetAPI) focus).isNormalStar()) continue;
339
340
342 Global.getSettings().getSpec(PlanetGenDataSpec.class, planet.getSpec().getPlanetType(), true);
343 if (spec == null) continue;
344
345 String cat = spec.getCategory();
346 if (cat == null) continue;
347
348 float weight = 0f;
349 if (Planets.CAT_HAB1.equals(cat)) {
350 weight = 1f;
351 } else if (Planets.CAT_HAB2.equals(cat)) {
352 weight = 1f;
353 } else if (Planets.CAT_HAB3.equals(cat)) {
354 weight = 1f;
355 }
356
357 if (weight <= 0) continue;
358
359 weight = 0;
360
361 if (planet.hasCondition(Conditions.HOT)) {
362 weight += 5f;
363 }
364 if (planet.hasCondition(Conditions.POOR_LIGHT)) {
365 weight += 5f;
366 }
367 if (planet.hasCondition(Conditions.WATER_SURFACE)) {
368 weight += 5f;
369 }
370 if (Misc.hasFarmland(planet.getMarket())) {
371 weight += 10f;
372 }
373
374 if (weight <= 0) continue;
375
376 // +250 beyond normal radius
377 boolean enoughRoom = true;
378 for (PlanetAPI other : system.getPlanets()) {
379 if (other.getOrbitFocus() == planet) {
380 if (other.getCircularOrbitRadius() < planet.getRadius() + other.getRadius() + 320) {
381 enoughRoom = false;
382 break;
383 }
384 }
385 }
386 if (!enoughRoom) continue;
387
388
389 picker.add(planet, weight);
390 }
391 }
392 }
393
394 if (DEBUG) System.out.println("Found " + picker.getItems().size() + " candidates");
395 for (int i = 0; i < num && !picker.isEmpty(); i++) {
396 PlanetAPI planet = picker.pickAndRemove();
397 if (DEBUG) System.out.println("Adding solar shades and mirrors to [" + planet.getName() + "] in [" +
398 planet.getStarSystem() + " located at " + planet.getLocationInHyperspace());
399
401
402 StarSystemAPI system = planet.getStarSystem();
403 PlanetAPI star = (PlanetAPI) planet.getOrbitFocus();
404
405 boolean shade = planet.hasCondition(Conditions.HOT) ||
406 planet.getTypeId().equals(Planets.DESERT) ||
407 planet.getTypeId().equals(Planets.DESERT1) ||
408 planet.getTypeId().equals(Planets.ARID) ||
409 star.getTypeId().equals(StarTypes.BLUE_GIANT) ||
410 star.getTypeId().equals(StarTypes.BLUE_SUPERGIANT);
411 boolean mirror = planet.hasCondition(Conditions.POOR_LIGHT) ||
412 planet.getTypeId().equals(Planets.PLANET_TERRAN_ECCENTRIC) ||
413// star.getTypeId().equals(StarTypes.RED_SUPERGIANT) ||
414// star.getTypeId().equals(StarTypes.RED_GIANT) ||
415 star.getTypeId().equals(StarTypes.RED_DWARF) ||
416 star.getTypeId().equals(StarTypes.BROWN_DWARF);
417
418 boolean forceFew = false;
419 if (!shade && !mirror) {
420 mirror = true;
421 shade = true;
422 forceFew = true;
423 }
424
425 String faction = Factions.NEUTRAL;
426 float period = planet.getCircularOrbitPeriod();
427 float angle = planet.getCircularOrbitAngle();
428 float radius = 270f + planet.getRadius();
429 //String name = planet.getName();
430
431 float xp = 300f;
432 float profile = 2000f;
433
434 if (mirror) {
435 boolean manyMirrors = random.nextBoolean();
436
437 SectorEntityToken mirror2 = system.addCustomEntity(null, "Stellar Mirror Beta", Entities.STELLAR_MIRROR, faction);
438 SectorEntityToken mirror3 = system.addCustomEntity(null, "Stellar Mirror Gamma", Entities.STELLAR_MIRROR, faction);
439 SectorEntityToken mirror4 = system.addCustomEntity(null, "Stellar Mirror Delta", Entities.STELLAR_MIRROR, faction);
440 mirror2.setCircularOrbitPointingDown(planet, angle - 30, radius, period);
441 mirror3.setCircularOrbitPointingDown(planet, angle + 0, radius, period);
442 mirror4.setCircularOrbitPointingDown(planet, angle + 30, radius, period);
443 makeDiscoverable(mirror2, xp, profile);
444 makeDiscoverable(mirror3, xp, profile);
445 makeDiscoverable(mirror4, xp, profile);
446
447 if (manyMirrors && !forceFew) {
448 SectorEntityToken mirror1 = system.addCustomEntity(null, "Stellar Mirror Alpha", Entities.STELLAR_MIRROR, faction);
449 SectorEntityToken mirror5 = system.addCustomEntity(null, "Stellar Mirror Epsilon", Entities.STELLAR_MIRROR, faction);
450 mirror1.setCircularOrbitPointingDown(planet, angle - 60, radius, period);
451 mirror5.setCircularOrbitPointingDown(planet, angle + 60, radius, period);
452 makeDiscoverable(mirror1, xp, profile);
453 makeDiscoverable(mirror5, xp, profile);
454 }
455 }
456
457 if (shade) {
458 boolean manyShades = random.nextBoolean();
459 SectorEntityToken shade2 = system.addCustomEntity(null, "Stellar Shade Psi", Entities.STELLAR_SHADE, faction);
460 shade2.setCircularOrbitPointingDown(planet, angle + 180 + 0, radius + 25, period);
461 makeDiscoverable(shade2, xp, profile);
462
463 if (manyShades && !forceFew) {
464 SectorEntityToken shade1 = system.addCustomEntity(null, "Stellar Shade Omega", Entities.STELLAR_SHADE, faction);
465 SectorEntityToken shade3 = system.addCustomEntity(null, "Stellar Shade Chi", Entities.STELLAR_SHADE, faction);
466 shade1.setCircularOrbitPointingDown(planet, angle + 180 - 26, radius - 10, period);
467 shade3.setCircularOrbitPointingDown(planet, angle + 180 + 26, radius - 10, period);
468 makeDiscoverable(shade1, xp, profile);
469 makeDiscoverable(shade3, xp, profile);
470 }
471 }
472
473 }
474
475 if (DEBUG) System.out.println("Done adding solar shades and mirrors");
476 }
477
478 public static void makeDiscoverable(SectorEntityToken entity, float xp, float sensorProfile) {
479 entity.setDiscoverable(true);
480 entity.setDiscoveryXP(xp);
481 entity.setSensorProfile(sensorProfile);
482 }
483
484
485 public void populateNonMain(StarSystemData data) {
486 if (DEBUG) System.out.println(" Generating misc derelicts in system " + data.system.getName());
487 boolean special = data.isBlackHole() || data.isNebula() || data.isPulsar();
488 if (special) {
490 }
491
492 if (random.nextFloat() < 0.5f) return;
493
495 15f, 10f, 10f);
496
497 addShipGraveyard(data, 0.05f, 1, 1, factions);
498
499 addDebrisFields(data, 0.25f, 1, 2);
500
501 addDerelictShips(data, 0.5f, 0, 3, factions);
502
503 addCaches(data, 0.25f, 0, 2, createStringPicker(
514 ));
515
516 }
517
518
519 protected void addExtraGates(ThemeGenContext context) {
520// List<SectorEntityToken> gates = new ArrayList<SectorEntityToken>();
521// List<StarSystemAPI> systems = new ArrayList<StarSystemAPI>();
522// List<Constellation> list = new ArrayList<Constellation>(context.constellations);
523// for (Constellation c : list) {
524// for (StarSystemAPI system : c.getSystems()) {
525// gates.addAll(system.getEntitiesWithTag(Tags.GATE));
526// systems.add(system);
527// }
528// }
529
530 List<StarSystemAPI> systems = new ArrayList<StarSystemAPI>(Global.getSector().getStarSystems());
531 List<SectorEntityToken> gates = new ArrayList<SectorEntityToken>();
532
533 for (StarSystemAPI system : new ArrayList<StarSystemAPI>(systems)) {
534 //if (system.hasTag(Tags.THEME_CORE)) continue; // this isn't set yet
535 boolean galatia = system.getBaseName().toLowerCase().equals("galatia");
536 if (system.getTags().isEmpty() || galatia) {
537 systems.remove(system);
538 continue;
539 }
540 gates.addAll(system.getEntitiesWithTag(Tags.GATE));
541 }
542
543
544 int addGates = MIN_GATES + random.nextInt(MAX_GATES - MIN_GATES + 1) - gates.size();
545 if (addGates < MIN_GATES_TO_ADD) addGates = MIN_GATES_TO_ADD;
546 if (addGates <= 0) {
547 if (DEBUG) System.out.println(" Already have " + gates.size() + " gates, not adding any");
548 return;
549 }
550
551 List<StarSystemData> all = new ArrayList<BaseThemeGenerator.StarSystemData>();
552
553 if (DEBUG) System.out.println("");
554 if (DEBUG) System.out.println("");
555 if (DEBUG) System.out.println("");
556 if (DEBUG) System.out.println(" Adding " + addGates + " extra gates, for a total of " + (addGates + gates.size()));
557
558 for (int i = 0; i < addGates; i++) {
559 float maxDist = 0;
560 StarSystemAPI farthest = null;
561 for (StarSystemAPI system : systems) {
562 if (system.getPlanets().size() < 3) continue; // skip empty systems
563
564 float minDist = Float.MAX_VALUE;
565 for (SectorEntityToken gate : gates) {
566 float dist = Misc.getDistanceLY(gate, system.getCenter());
567 if (dist < minDist) minDist = dist;
568 }
569 if (minDist > maxDist) {
570 maxDist = minDist;
571 farthest = system;
572 }
573 }
574 if (farthest != null) {
575 StarSystemData data = new StarSystemData();
576 data.system = farthest;
578 15f, 5f, 5f);
579 AddedEntity gate = addInactiveGate(data, 1f, 0.5f, 0.5f, factions);
580 if (gate != null && gate.entity != null) gates.add(gate.entity);
581 }
582 }
583 if (DEBUG) System.out.println(" Done adding extra gates");
584 if (DEBUG) System.out.println("");
585 if (DEBUG) System.out.println("");
586 if (DEBUG) System.out.println("");
587
588 SpecialCreationContext specialContext = new SpecialCreationContext();
589 specialContext.themeId = getThemeId();
590 SalvageSpecialAssigner.assignSpecials(all, specialContext);
591
592
593
594 }
595
596
597 protected void addCoronalTaps(ThemeGenContext context) {
598 if (DEBUG) System.out.println("Adding coronal taps...");
599
600 List<Constellation> list = new ArrayList<Constellation>(context.constellations);
601
604 for (Constellation c : list) {
605 for (StarSystemAPI system : c.getSystems()) {
606 if (system.hasTag(Tags.THEME_SPECIAL)) continue;
607
608 float w = 0f;
609 if (system.hasTag(Tags.THEME_REMNANT)) {
610 w = 10f;
611 } else if (system.hasTag(Tags.THEME_DERELICT)) {
612 w = 10f;
613 } else if (system.hasTag(Tags.THEME_RUINS)) {
614 w = 10f;
615 } else if (system.hasTag(Tags.THEME_MISC)) {
616 w = 5f;
617 }
618
619 if (w <= 0) continue;
620
621 if (system.getType() == StarSystemType.TRINARY_2CLOSE) {
622 w *= 5f;
623 }
624
625 boolean hasBlueStar = false;
626 boolean hasNormalStar = false;
627 for (PlanetAPI planet : system.getPlanets()) {
628 if (!planet.isNormalStar()) continue;
629 if (planet.getTypeId().equals(StarTypes.BLUE_GIANT) ||
630 planet.getTypeId().equals(StarTypes.BLUE_SUPERGIANT)) {
631 hasBlueStar = true;
632 }
633 hasNormalStar = true;
634 }
635
636 if (!hasNormalStar) continue;
637
639 if (!hasBlueStar) {
640 use = backup;
641 }
642 use.add(system, w);
643 }
644 }
645
646
647 if (tapSystems.isEmpty()) {
648 tapSystems.addAll(backup);
649 }
650
651 int numTaps = 2 + random.nextInt(2);
652 numTaps = 2;
653 int added = 0;
654 while (added < numTaps && !tapSystems.isEmpty()) {
655 StarSystemAPI pick = tapSystems.pickAndRemove();
656 AddedEntity tap = addCoronalTap(pick);
657 if (tap != null) {
658 added++;
659 }
660 }
661
662 if (DEBUG) System.out.println("Done adding coronal taps\n\n\n");
663 }
664
665 public static class MakeCoronalTapFaceNearestStar implements EveryFrameScript {
666 protected SectorEntityToken tap;
667 public MakeCoronalTapFaceNearestStar(SectorEntityToken tap) {
668 this.tap = tap;
669 }
670 public void advance(float amount) {
671 if (!tap.isInCurrentLocation()) return;
672
673 float minDist = Float.MAX_VALUE;
674 PlanetAPI closest = null;
675 for (PlanetAPI star : tap.getContainingLocation().getPlanets()) {
676 if (!star.isStar()) continue;
677 float dist = Misc.getDistance(tap.getLocation(), star.getLocation());
678 if (dist < minDist) {
679 minDist = dist;
680 closest = star;
681 }
682 }
683 if (closest != null) {
684 tap.setFacing(Misc.getAngleInDegrees(tap.getLocation(), closest.getLocation()) + 180f);
685 }
686 }
687 public boolean isDone() {
688 return false;
689 }
690 public boolean runWhilePaused() {
691 return false;
692 }
693 }
694
695 protected AddedEntity addCoronalTap(StarSystemAPI system) {
696
697 if (DEBUG) System.out.println("Adding coronal tap to [" + system.getNameWithLowercaseType() + ", " + system.getLocation());
698
699 String factionId = Factions.NEUTRAL;
700
701 AddedEntity entity = null;
702 if (system.getType() == StarSystemType.TRINARY_2CLOSE) {
703 EntityLocation loc = new EntityLocation();
704 loc.location = new Vector2f();
705 entity = addEntity(random, system, loc, Entities.CORONAL_TAP, factionId);
706 if (entity != null) {
707 system.addScript(new MakeCoronalTapFaceNearestStar(entity.entity));
708 }
709 } else {
712 for (PlanetAPI planet : system.getPlanets()) {
713 if (!planet.isNormalStar()) continue;
714 if (planet.getTypeId().equals(StarTypes.BLUE_GIANT) ||
715 planet.getTypeId().equals(StarTypes.BLUE_SUPERGIANT)) {
716 picker.add(planet);
717 } else {
718 fallback.add(planet);
719 }
720 }
721 if (picker.isEmpty()) {
722 picker.addAll(fallback);
723 }
724
725 PlanetAPI star = picker.pick();
726 if (star != null) {
728 EntityLocation loc = new EntityLocation();
729 float orbitRadius = star.getRadius() + spec.getDefaultRadius() + 100f;
730 float orbitDays = orbitRadius / 20f;
731 loc.orbit = Global.getFactory().createCircularOrbitPointingDown(star, random.nextFloat() * 360f, orbitRadius, orbitDays);
732 entity = addEntity(random, system, loc, Entities.CORONAL_TAP, factionId);
733 }
734 }
735
736
737 if (entity != null) {
738 system.addScript(new CoronalTapParticleScript(entity.entity));
739// system.addCorona(entity.entity, Terrain.CORONA_JET,
740// 500f, // radius outside planet
741// 15f, // burn level of "wind"
742// 0f, // flare probability
743// 1f // CR loss mult while in it
744// );
745
746// system.addTag(Tags.THEME_DERELICT);
748 }
749
750 if (DEBUG) {
751 if (entity != null) {
752 System.out.println(String.format(" Added coronal tap to %s", system.getNameWithLowercaseType()));
753 } else {
754 System.out.println(String.format(" Failed to add coronal tap to %s", system.getNameWithLowercaseType()));
755 }
756 }
757 return entity;
758 }
759
760
761 protected void addPKSystem(ThemeGenContext context) {
762 if (DEBUG) System.out.println("Looking for system to hide PK in");
763
764 List<StarSystemAPI> preferred = new ArrayList<StarSystemAPI>();
765 List<StarSystemAPI> other = new ArrayList<StarSystemAPI>();
766
767 for (Constellation c : context.constellations) {
768 for (StarSystemAPI system : c.getSystems()) {
769 if (system.hasTag(Tags.THEME_SPECIAL)) continue;
770
771 if (system.isNebula()) continue;
772 if (system.hasPulsar()) continue;
773 if (system.hasBlackHole()) continue;
774
775 boolean misc = system.hasTag(Tags.THEME_MISC_SKIP) || system.hasTag(Tags.THEME_MISC);
776 if (system.hasTag(Tags.THEME_DERELICT)) misc = false;
777
778 boolean nonLargeDerelict = system.hasTag(Tags.THEME_DERELICT) &&
779 !system.hasTag(Tags.THEME_DERELICT_MOTHERSHIP) &&
780 !system.hasTag(Tags.THEME_DERELICT_CRYOSLEEPER) &&
781 !system.hasTag(Tags.THEME_DERELICT_SURVEY_SHIP);
782
783 boolean secondaryRuins = system.hasTag(Tags.THEME_RUINS_SECONDARY);
784 boolean remnantNoFleets = system.hasTag(Tags.THEME_REMNANT_NO_FLEETS);
785 boolean unsafe = system.hasTag(Tags.THEME_UNSAFE);
786
787 if (unsafe || !(misc || nonLargeDerelict || secondaryRuins || remnantNoFleets)) {
788 continue;
789 }
790
791 int count = 0;
792 for (PlanetAPI curr : system.getPlanets()) {
793 if (curr.isStar()) continue;
794 if (curr.isMoon()) continue;
795 if (curr.isGasGiant()) continue;
796 if (!curr.getMarket().isPlanetConditionMarketOnly()) continue;
797 if (curr.getCircularOrbitRadius() < 6000) continue;
798 if (curr.hasTag(Tags.NOT_RANDOM_MISSION_TARGET)) continue;
799 count++;
800 }
801
802 if (count > 0) {
803 preferred.add(system);
804 } else {
805 other.add(system);
806 }
807 }
808 }
809
810 Comparator<StarSystemAPI> comp = new Comparator<StarSystemAPI>() {
811 public int compare(StarSystemAPI o1, StarSystemAPI o2) {
812 return (int) Math.signum(o2.getLocation().length() - o1.getLocation().length());
813 }
814 };
815
816 List<StarSystemAPI> sorted = new ArrayList<StarSystemAPI>();
817 if (!preferred.isEmpty()) {
818 sorted.addAll(preferred);
819 } else {
820 sorted.addAll(other);
821 }
822 if (sorted.isEmpty()) {
823 if (DEBUG) System.out.println("FAILED TO FIND SUITABLE SYSTEM FOR PK");
824 return;
825 }
826 Collections.sort(sorted, comp);
827
828
829 // pick from some of the matching systems furthest from core
831 for (int i = 0; i < 20 && i < sorted.size(); i++) {
832 //sorted.get(i).addTag(Tags.PK_SYSTEM);
833 picker.add(sorted.get(i), 1f);
834 }
835
836 StarSystemAPI system = picker.pick();
837
838 if (DEBUG) System.out.println("Adding PK to [" + system.getName() + "] at [" + system.getLocation() + "]");
839 setUpPKSystem(system);
840
841
842 if (DEBUG) System.out.println("Finished adding PK system\n\n\n\n\n");
843 }
844
845 protected void setUpPKSystem(StarSystemAPI system) {
846 system.addTag(Tags.THEME_SPECIAL);
847 system.addTag(Tags.PK_SYSTEM);
848
851
852 // - pick a planet at 6k range or higher to make into a tundra world
853 // - turn any planets with a lower hazard rating into barren and reassign their conditions
854
855 PlanetAPI tundra = null;
856 for (PlanetAPI curr : system.getPlanets()) {
857 if (curr.isStar()) continue;
858 //if (curr.isMoon()) continue;
859 if (curr.isGasGiant()) continue;
860 if (curr.getMarket() == null) continue;
861 if (!curr.getMarket().isPlanetConditionMarketOnly()) continue;
862 if (curr.getCircularOrbitRadius() < 6000) continue;
863
864 tundra = curr;
865 break;
866 }
867
868 //pick = null;
869
870 // if there's no planet in a suitable range, create one
871 // could end up with a tundra world really far out if the system is full of stuff
872 // but has no planets, but it's unlikely
873 if (tundra == null) {
874 List<OrbitGap> gaps = BaseThemeGenerator.findGaps(system.getCenter(), 6000, 20000, 800);
875 float orbitRadius = 7000;
876 if (!gaps.isEmpty()) {
877 orbitRadius = (gaps.get(0).start + gaps.get(0).end) * 0.5f;
878 }
879 float orbitDays = orbitRadius / (20f + random.nextFloat() * 5f);
880 float radius = 100f + random.nextFloat() * 50f;
881 float angle = random.nextFloat() * 360f;
882 String type = Planets.BARREN;
883 NamePick namePick = ProcgenUsedNames.pickName(NameGenData.TAG_PLANET, null, null);
884 String name = namePick.nameWithRomanSuffixIfAny;
885 tundra = system.addPlanet(Misc.genUID(), system.getStar(), name, type, angle, radius, orbitRadius, orbitDays);
886
887 if (tundra == null) {
888 if (DEBUG) System.out.println("FAILED TO CREATE PLANET IN PK SYSTEM");
889 return;
890 }
891 }
892
893 tundra.setName("Sentinel");
894 tundra.getMarket().setName("Sentinel");
898
899 if (DEBUG) System.out.println("Setting planet [" + tundra.getName() + "] to tundra");
901 tundra.getMarket().getConditions().clear();
910
916
917
918 // make sure the tundra world is the best habitable world in-system so there's no questions
919 // as to why it was chosen by the survivors
920 float pickHazard = tundra.getMarket().getHazardValue();
921
922 for (PlanetAPI curr : system.getPlanets()) {
923 if (curr.isStar()) continue;
924 if (curr.isGasGiant()) continue;
925 if (curr.getMarket() == null) continue;
926 if (!curr.getMarket().isPlanetConditionMarketOnly()) continue;
927 if (curr == tundra) continue;
928
929 float h = curr.getMarket().getHazardValue();
930 if (curr.hasCondition(Conditions.HABITABLE) && h <= pickHazard) {
931 curr.changeType(Planets.BARREN_VENUSLIKE, random);
932 curr.getMarket().getConditions().clear();
934 }
935 }
936
938 system.removeEntity(curr);
939 }
941 system.removeEntity(curr);
942 }
943
944
945 List<OrbitGap> gaps = BaseThemeGenerator.findGaps(system.getCenter(), 2000, 20000, 800);
946 float orbitRadius = 7000;
947 if (!gaps.isEmpty()) {
948 orbitRadius = (gaps.get(0).start + gaps.get(0).end) * 0.5f;
949 }
950 float radius = 500f + 200f * random.nextFloat();
951 float area = radius * radius * 3.14f;
952 int count = (int) (area / 80000f);
953 count *= 2;
954 if (count < 10) count = 10;
955 if (count > 100) count = 100;
956 float angle = random.nextFloat() * 360f;
957 float orbitDays = orbitRadius / (20f + random.nextFloat() * 5f);
958
960 new AsteroidFieldParams(
961 radius, // min radius
962 radius + 100f, // max radius
963 count, // min asteroid count
964 count, // max asteroid count
965 4f, // min asteroid radius
966 16f, // max asteroid radius
967 null)); // null for default name
968
969 field.setCircularOrbit(system.getCenter(), angle, orbitRadius, orbitDays);
970
974 //cache.getLocation().set(10000, 10000);
975 cache.setCircularOrbit(field, 0, 0, 100f);
977
978 // Misc.addDefeatTrigger(fleet, trigger);
979
980 // add a ship graveyard around the cache - Luddic Path ships, presumably from another
981 // Path operative that got farther along but never reported back
982 StarSystemData data = new StarSystemData();
984 derelictShipFactions.add(Factions.LUDDIC_PATH);
986 hulls.add("prometheus2", 1f);
987 hulls.add("colossus2", 1f);
988 hulls.add("colossus2", 1f);
989 hulls.add("colossus2", 1f);
990 hulls.add("eradicator", 1f);
991 hulls.add("enforcer", 1f);
992 hulls.add("sunder", 1f);
993 hulls.add("venture_pather", 1f);
994 hulls.add("manticore_luddic_path", 1f);
995 hulls.add("cerberus_luddic_path", 1f);
996 hulls.add("hound_luddic_path", 1f);
997 hulls.add("buffalo2", 1f);
998 addShipGraveyard(data, field, derelictShipFactions, hulls);
999 for (AddedEntity ae : data.generated) {
1000 SalvageSpecialAssigner.assignSpecials(ae.entity, true);
1001 }
1002
1003 // add some remnant derelicts around a fringe jump-point
1004 // where the fight was
1005 float max = 0f;
1006 JumpPointAPI fringePoint = null;
1007 List<JumpPointAPI> points = system.getEntities(JumpPointAPI.class);
1008 for (JumpPointAPI curr : points) {
1009 float dist = curr.getCircularOrbitRadius();
1010 if (dist > max) {
1011 max = dist;
1012 fringePoint = curr;
1013 }
1014 }
1015
1016 if (fringePoint != null) {
1017 data = new StarSystemData();
1019 remnantShipFactions.add(Factions.REMNANTS);
1021 hulls.add("radiant", 0.25f);
1022 hulls.add("nova", 0.5f);
1023 hulls.add("brilliant", 1f);
1024 hulls.add("apex", 1f);
1025 hulls.add("scintilla", 1f);
1026 hulls.add("scintilla", 1f);
1027 hulls.add("fulgent", 1f);
1028 hulls.add("fulgent", 1f);
1029 hulls.add("glimmer", 1f);
1030 hulls.add("glimmer", 1f);
1031 hulls.add("lumen", 1f);
1032 hulls.add("lumen", 1f);
1033 addShipGraveyard(data, fringePoint, remnantShipFactions, hulls);
1034 addDebrisField(data, fringePoint, 400f);
1035
1036 for (AddedEntity ae : data.generated) {
1037 SalvageSpecialAssigner.assignSpecials(ae.entity, true);
1038 if (ae.entity.getCustomPlugin() instanceof DerelictShipEntityPlugin) {
1040 plugin.getData().ship.condition = ShipCondition.WRECKED;
1041 }
1042 }
1043 }
1044
1045 // Improvised dockyard where presumably the ship conversion took place
1046 SectorEntityToken dockyard = system.addCustomEntity("pk_dockyard",
1047 "Sentinel Gantries", Entities.ORBITAL_DOCKYARD, "neutral");
1048
1049 dockyard.setCircularOrbitPointingDown(tundra, 45, 300, 30);
1050 dockyard.setCustomDescriptionId("pk_orbital_dockyard");
1051 dockyard.getMemoryWithoutUpdate().set("$pkDockyard", true);
1052
1053 //neutralStation.setInteractionImage("illustrations", "abandoned_station2");
1054 Misc.setAbandonedStationMarket("pk_dockyard", dockyard);
1055
1056
1057 // add some unused stuff to the dockyard
1060
1062 temp.getFleetData().addFleetMember("enforcer_XIV_Elite");
1063 temp.getFleetData().addFleetMember("enforcer_XIV_Elite");
1064 temp.getFleetData().addFleetMember("eagle_xiv_Elite");
1065 temp.getFleetData().addFleetMember("dominator_XIV_Elite");
1067 p.quality = -1;
1068 temp.setInflater(new DefaultFleetInflater(p));
1069 temp.inflateIfNeeded();
1070 temp.setInflater(null);
1071
1072 int index = 0;
1073 for (FleetMemberAPI member : temp.getFleetData().getMembersListCopy()) {
1074 for (String slotId : member.getVariant().getFittedWeaponSlots()) {
1075 String weaponId = member.getVariant().getWeaponId(slotId);
1076 if (random.nextFloat() < 0.5f) {
1077 member.getVariant().clearSlot(slotId);
1078 }
1079 if (random.nextFloat() < 0.25f) {
1080 cargo.addWeapons(weaponId, 1);
1081 }
1082 }
1083 if (index == 0 || index == 2) {
1084 cargo.getMothballedShips().addFleetMember(member);
1085 }
1086 index++;
1087 }
1088 cargo.addCommodity(Commodities.METALS, 50f + random.nextInt(51));
1089
1090 List<CampaignFleetAPI> stations = getRemnantStations(true, false);
1091 float minDist = Float.MAX_VALUE;
1092 CampaignFleetAPI nexus = null;
1093 for (CampaignFleetAPI curr : stations) {
1094 float dist = Misc.getDistanceLY(tundra, curr);
1095 if (dist < minDist) {
1096 minDist = dist;
1097 nexus = curr;
1098 }
1099 }
1100 if (nexus != null) {
1101 if (DEBUG) System.out.println("Found Remnant nexus in [" + nexus.getContainingLocation().getName() + "]");
1105
1106 Misc.addDefeatTrigger(nexus, "PKNexusDefeated");
1107 }
1108 }
1109
1110 protected void addLOCRLuddicPlanet(ThemeGenContext context) {
1111 if (DEBUG) System.out.println("Looking for LOCR_LUDDIC planet");
1112
1115
1116 // looking for a habitable planet in the fringe WITH good farming
1117 for (Constellation c : context.constellations) {
1118 for (StarSystemAPI system : c.getSystems()) {
1119
1120 if (system.hasTag(Tags.THEME_SPECIAL)) continue;
1121 if (system.isNebula()) continue;
1122 if (system.hasPulsar()) continue;
1123 if (system.hasBlackHole()) continue;
1124 if (!system.hasTag(Tags.THEME_MISC_SKIP) && !system.hasTag(Tags.THEME_MISC)) continue;
1125 if (system.hasTag(Tags.THEME_DERELICT)) continue;
1126
1127 for (PlanetAPI curr : system.getPlanets()) {
1128 if (curr.isStar()) continue;
1129 if (!curr.getMarket().isPlanetConditionMarketOnly()) continue;
1130
1131 if (curr.hasTag(Tags.NOT_RANDOM_MISSION_TARGET)) continue;
1132 if (curr.getMarket().hasCondition(Conditions.WATER_SURFACE)) continue; // Ludd gets seasick, I guess.
1133 if (curr.isGasGiant()) continue; // I mean, let's just be sure, right?
1134 if (curr.getMarket().hasCondition(Conditions.DECIVILIZED_SUBPOP)) continue;
1135
1136 // must have good farmland! Or at least OK farmland.
1137 if (curr.getMarket().hasCondition("farmland_rich") || curr.getMarket().hasCondition("farmland_bountiful"))
1138 {
1139 picker.add(curr);
1140 }
1141 else if ( curr.getMarket().hasCondition("farmland_adequate"))
1142 {
1143 picker_fallback.add(curr);
1144 }
1145 }
1146 }
1147 }
1148
1149 PlanetAPI planet = picker.pick();
1150 if (planet == null)
1151 {
1152 planet = picker_fallback.pick();
1153 }
1154
1155 if (planet != null) {
1156
1157 // add the ship they came in on
1158
1159 DerelictShipData params = new DerelictShipData(new PerShipData("nebula_Standard", ShipCondition.BATTERED, 0f), false);
1160 params.ship.shipName = "CGR Light of Exultation";
1161 params.ship.nameAlwaysKnown = true;
1162 //params.ship.fleetMemberId = id;
1163
1165 ship.setDiscoverable(true);
1166 float orbitDays = 200f / (10f + (float) Math.random() * 5f);
1167 ship.setCircularOrbit(planet, (float) Math.random() * 360f, planet.getRadius() + 100f, orbitDays);
1168 ShipRecoverySpecialCreator creator = new ShipRecoverySpecialCreator(null, 0, 0, false, null, null);
1169 Misc.setSalvageSpecial(ship, creator.createSpecial(ship, null));
1170
1172 //ship.getMemoryWithoutUpdate().set(LOCR_LUDDIC, true);
1173
1174
1175 if (DEBUG) System.out.println("Adding LOCR_LUDDIC flag to [" + planet.getName() + "] in [" + planet.getContainingLocation().getNameWithLowercaseType() + "]");
1177 planet.getMemoryWithoutUpdate().set(LOCR_LUDDIC, true);
1179
1180 long seed = StarSystemGenerator.random.nextLong();
1182
1183 } else {
1184 if (DEBUG) System.out.println("Failed to find a LOCR_LUDDIC planet, may Ludd forgive you.");
1185 }
1186 if (DEBUG) System.out.println("Finished adding LOCR_LUDDIC planet\n\n\n");
1187 }
1188
1189/* Maybe later. -dgb
1190 protected void addLOCRUtopiaPlanet(ThemeGenContext context) {
1191 if (DEBUG) System.out.println("Looking for LOCR_UTOPIA planet");
1192
1193 WeightedRandomPicker<PlanetAPI> picker = new WeightedRandomPicker<PlanetAPI>(random);
1194
1195 // looking for a habitable planet in the fringe
1196 for (Constellation c : context.constellations) {
1197 for (StarSystemAPI system : c.getSystems()) {
1198
1199 if (system.hasTag(Tags.THEME_SPECIAL)) continue;
1200 if (system.isNebula()) continue;
1201 if (system.hasPulsar()) continue;
1202 if (system.hasBlackHole()) continue;
1203 if (!system.hasTag(Tags.THEME_MISC_SKIP) && !system.hasTag(Tags.THEME_MISC)) continue;
1204 if (system.hasTag(Tags.THEME_DERELICT)) continue;
1205
1206 for (PlanetAPI curr : system.getPlanets()) {
1207 if (curr.isStar()) continue;
1208 if (!curr.getMarket().isPlanetConditionMarketOnly()) continue;
1209 if (curr.hasTag(Tags.NOT_RANDOM_MISSION_TARGET)) continue;
1210 if (curr.getMarket().hasCondition(Conditions.DECIVILIZED_SUBPOP)) continue; // no competition, please.
1211 if (curr.getMarket().hasCondition(Conditions.WATER_SURFACE)) continue; // I'd have to write around this.
1212 if (!curr.getMarket().hasCondition(Conditions.HABITABLE)) continue;
1213
1214 picker.add(curr);
1215 }
1216 }
1217 }
1218
1219 PlanetAPI planet = picker.pick();
1220
1221 if (planet != null) {
1222 if (DEBUG) System.out.println("Adding LOCR_UTOPIA flag to [" + planet.getName() + "] in [" + planet.getContainingLocation().getNameWithLowercaseType() + "]");
1223 Global.getSector().getMemoryWithoutUpdate().set(LOCR_UTOPIA_PLANET_KEY, planet);
1224 planet.getMemoryWithoutUpdate().set(LOCR_UTOPIA, true);
1225 planet.getMemoryWithoutUpdate().set(LOCR_BLOCK_FIRST_SURVEY, true);
1226
1227 long seed = StarSystemGenerator.random.nextLong();
1228 planet.addTag(Tags.NOT_RANDOM_MISSION_TARGET);
1229
1230 } else {
1231 if (DEBUG) System.out.println("Failed to find a planet for LOCR_UTOPIA; the dream is dead :( ");
1232 }
1233 if (DEBUG) System.out.println("Finished adding LOCR_UTOPIA planet\n\n\n");
1234 }
1235*/
1236
1237 protected void addLOCRMinersPlanet(ThemeGenContext context) {
1238 if (DEBUG) System.out.println("Looking for LOCR_MINERS planet");
1239
1241
1242 // looking for a non-habitable planet or moon with good mining in the fringe
1243 for (Constellation c : context.constellations) {
1244 for (StarSystemAPI system : c.getSystems()) {
1245
1246 if (system.hasTag(Tags.THEME_SPECIAL)) continue;
1247 if (system.hasPulsar()) continue;
1248 if (!system.hasTag(Tags.THEME_MISC_SKIP) && !system.hasTag(Tags.THEME_MISC)) continue;
1249 if (system.hasTag(Tags.THEME_DERELICT)) continue;
1250
1251 for (PlanetAPI curr : system.getPlanets()) {
1252 if (curr.isStar()) continue;
1253 if (!curr.getMarket().isPlanetConditionMarketOnly()) continue;
1254 if (curr.hasTag(Tags.NOT_RANDOM_MISSION_TARGET)) continue;
1255 if (curr.getMarket().hasCondition(Conditions.HABITABLE)) continue;
1256 if (curr.getMarket().hasCondition(Conditions.EXTREME_TECTONIC_ACTIVITY)) continue; // It has to be a GOOD planet.
1257 if (curr.getMarket().hasCondition(Conditions.DECIVILIZED_SUBPOP)) continue;
1258 if (curr.getMarket().hasCondition(Conditions.WATER_SURFACE)) continue; // don't want to write around this.
1259 if (curr.isGasGiant()) continue;
1260 if (!( curr.getMarket().hasCondition(Conditions.VOLATILES_PLENTIFUL) ||
1261 curr.getMarket().hasCondition(Conditions.ORGANICS_PLENTIFUL) ||
1262 curr.getMarket().hasCondition(Conditions.RARE_ORE_ULTRARICH) ) ) continue;
1263 // curr.getMarket().hasCondition(Conditions.ORE_ULTRARICH) ) ) continue;
1264
1265 picker.add(curr);
1266 }
1267 }
1268 }
1269
1270 PlanetAPI planet = picker.pick();
1271
1272 if (planet != null) {
1273 if (DEBUG) System.out.println("Adding LOCR_MINERS flag to [" + planet.getName() + "] in [" + planet.getContainingLocation().getNameWithLowercaseType() + "]");
1275 planet.getMemoryWithoutUpdate().set(LOCR_MINERS, true);
1277
1278 long seed = StarSystemGenerator.random.nextLong();
1280
1281 } else {
1282 if (DEBUG) System.out.println("Failed to find a planet for LOCR_MINERS.");
1283 }
1284 if (DEBUG) System.out.println("Finished adding LOCR_MINERS planet\n\n\n\n\n");
1285 }
1286
1287 protected void addLOCRPiratePlanet(ThemeGenContext context) {
1288 if (DEBUG) System.out.println("Looking for LOCR_PIRATE planet");
1289
1291
1292 // looking for an obscure non-habitable planet or moon
1293 for (Constellation c : context.constellations) {
1294 for (StarSystemAPI system : c.getSystems()) {
1295
1296 if (system.hasTag(Tags.THEME_SPECIAL)) continue;
1297 if (system.hasPulsar()) continue;
1298 if (!system.hasTag(Tags.THEME_MISC_SKIP) && !system.hasTag(Tags.THEME_MISC)) continue;
1299 if (system.hasTag(Tags.THEME_DERELICT)) continue;
1300
1301 for (PlanetAPI curr : system.getPlanets()) {
1302 if (curr.isStar()) continue;
1303 if (!curr.getMarket().isPlanetConditionMarketOnly()) continue;
1304 if (curr.hasTag(Tags.NOT_RANDOM_MISSION_TARGET)) continue;
1305 if (curr.getMarket().hasCondition(Conditions.DECIVILIZED_SUBPOP)) continue; // no competition, please.
1306 if (curr.getMarket().hasCondition(Conditions.HABITABLE)) continue; // should be a POS
1307 if (curr.isGasGiant()) continue;
1308
1309 picker.add(curr);
1310 }
1311 }
1312 }
1313
1314 PlanetAPI planet = picker.pick();
1315
1316 if (planet != null) {
1317 if (DEBUG) System.out.println("Adding LOCR_PIRATE flag to [" + planet.getName() + "] in [" + planet.getContainingLocation().getNameWithLowercaseType() + "]");
1319 planet.getMemoryWithoutUpdate().set(LOCR_PIRATE, true);
1321
1322 long seed = StarSystemGenerator.random.nextLong();
1324
1325 } else {
1326 if (DEBUG) System.out.println("Failed to find a planet for LOCR_PIRATE; the dream is dead :( ");
1327 }
1328 if (DEBUG) System.out.println("Finished adding LOCR_PIRATE planet\n\n\n");
1329 }
1330
1331
1332 public static List<CampaignFleetAPI> getRemnantStations(boolean includeDamaged, boolean onlyDamaged) {
1333 List<CampaignFleetAPI> stations = new ArrayList<CampaignFleetAPI>();
1334 for (StarSystemAPI system : Global.getSector().getStarSystems()) {
1335 if (!system.hasTag(Tags.THEME_REMNANT_MAIN)) continue;
1336 if (system.hasTag(Tags.THEME_REMNANT_DESTROYED)) continue;
1337
1338 for (CampaignFleetAPI fleet : system.getFleets()) {
1339 if (!fleet.isStationMode()) continue;
1340 if (!Factions.REMNANTS.equals(fleet.getFaction().getId())) continue;
1341
1342 boolean damaged = fleet.getMemoryWithoutUpdate().getBoolean("$damagedStation");
1343 if (damaged && !includeDamaged) continue;
1344 if (!damaged && onlyDamaged) continue;
1345
1346 stations.add(fleet);
1347 }
1348 }
1349 return stations;
1350 }
1351}
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
static SettingsAPI getSettings()
Definition Global.java:57
static FactoryAPI getFactory()
Definition Global.java:41
static SectorAPI getSector()
Definition Global.java:65
static final String THEME_DERELICT_SURVEY_SHIP
Definition Tags.java:176
static final String THEME_INTERESTING_MINOR
Definition Tags.java:158
static final String THEME_REMNANT_DESTROYED
Definition Tags.java:186
static final String THEME_RUINS_SECONDARY
Definition Tags.java:165
static final String NOT_RANDOM_MISSION_TARGET
Definition Tags.java:398
static final String THEME_DERELICT_MOTHERSHIP
Definition Tags.java:174
static final String THEME_REMNANT_NO_FLEETS
Definition Tags.java:185
static final String THEME_DERELICT_CRYOSLEEPER
Definition Tags.java:175
static void generateConditionsForPlanet(GenContext context, PlanetAPI planet)
static NamePick pickName(String tag, String parent, LagrangePointType lagrangePoint)
void addShipGraveyard(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker< String > factions)
void addDerelictShip(StarSystemData data, EntityLocation loc, WeightedRandomPicker< String > factions)
static AddedEntity addEntity(Random random, StarSystemAPI system, WeightedRandomPicker< EntityLocation > locs, String type, String faction)
void addResearchStations(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker< String > stationTypes)
static EntityLocation pickAnyLocation(Random random, StarSystemAPI system, float gap, Set< SectorEntityToken > exclude)
static List< OrbitGap > findGaps(SectorEntityToken center, float minPad, float maxDist, float minGap)
void addCaches(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker< String > cacheTypes)
void addDerelictShips(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker< String > factions)
static SectorEntityToken addSalvageEntity(LocationAPI location, String id, String faction)
AddedEntity addInactiveGate(StarSystemData data, float prob, float probDebris, float probShips, WeightedRandomPicker< String > factions)
WeightedRandomPicker< String > createStringPicker(Object ... params)
void addDebrisFields(StarSystemData data, float chanceToAddAny, int min, int max)
AddedEntity addDebrisField(StarSystemData data, SectorEntityToken focus, float radius)
static void makeDiscoverable(SectorEntityToken entity, float xp, float sensorProfile)
void addDerelicts(ThemeGenContext context, String variant, int minNonSalvageable, int maxNonSalvageable, int minSalvageable, int maxSalvageable, String ... allowedThemes)
static List< CampaignFleetAPI > getRemnantStations(boolean includeDamaged, boolean onlyDamaged)
static WeightedRandomPicker< String > getNearbyFactions(Random random, SectorEntityToken entity)
static void setDefenderOverride(SectorEntityToken entity, DefenderDataOverride override)
Definition Misc.java:3629
static float getDistanceLY(SectorEntityToken from, SectorEntityToken to)
Definition Misc.java:602
static void setAbandonedStationMarket(String marketId, SectorEntityToken station)
Definition Misc.java:4177
static void addDefeatTrigger(CampaignFleetAPI fleet, String trigger)
Definition Misc.java:5920
static float getDistance(SectorEntityToken from, SectorEntityToken to)
Definition Misc.java:599
static void setSalvageSpecial(SectorEntityToken entity, Object data)
Definition Misc.java:3633
static boolean hasFarmland(MarketAPI market)
Definition Misc.java:5910
static float getAngleInDegrees(Vector2f v)
Definition Misc.java:1126
CampaignFleetAPI createEmptyFleet(String factionId, String name, boolean aiMode)
OrbitAPI createCircularOrbitPointingDown(SectorEntityToken focus, float angle, float orbitRadius, float orbitDays)
ShipVariantAPI getVariant(String variantId)
Object getSpec(Class c, String id, boolean nullOnNotFound)
CustomEntitySpecAPI getCustomEntitySpec(String id)
void setInflater(FleetInflater inflater)
void addWeapons(String id, int count)
void initMothballedShips(String factionId)
void addCommodity(String commodityId, float quantity)
void addFleetMember(FleetMemberAPI member)
List< FleetMemberAPI > getMembersListCopy()
SectorEntityToken addTerrain(String terrainId, Object param)
PlanetAPI addPlanet(String id, SectorEntityToken focus, String name, String type, float angle, float radius, float orbitRadius, float orbitDays)
List getEntities(Class implementedClassOrInterface)
List< SectorEntityToken > getEntitiesWithTag(String tag)
void addScript(EveryFrameScript script)
CustomCampaignEntityAPI addCustomEntity(String id, String name, String type, String factionId)
void removeEntity(SectorEntityToken entity)
void changeType(String type, Random random)
Map< String, Object > getPersistentData()
List< StarSystemAPI > getStarSystems()
CustomCampaignEntityPlugin getCustomPlugin()
void setCircularOrbitPointingDown(SectorEntityToken focus, float angle, float orbitRadius, float orbitDays)
void setCircularOrbit(SectorEntityToken focus, float angle, float orbitRadius, float orbitDays)
void setDiscoverable(Boolean discoverable)
void setCustomDescriptionId(String customDescriptionId)
SubmarketAPI getSubmarket(String specId)
List< MarketConditionAPI > getConditions()
void set(String key, Object value)