Starsector API
Loading...
Searching...
No Matches
BaseThemeGenerator.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.Collections;
5import java.util.Comparator;
6import java.util.EnumSet;
7import java.util.HashSet;
8import java.util.LinkedHashMap;
9import java.util.LinkedHashSet;
10import java.util.List;
11import java.util.Random;
12import java.util.Set;
13
14import org.lwjgl.util.vector.Vector2f;
15
16import com.fs.starfarer.api.Global;
17import com.fs.starfarer.api.campaign.CampaignTerrainAPI;
18import com.fs.starfarer.api.campaign.CampaignTerrainPlugin;
19import com.fs.starfarer.api.campaign.CargoAPI;
20import com.fs.starfarer.api.campaign.CircularOrbitWithSpinAPI;
21import com.fs.starfarer.api.campaign.CustomCampaignEntityAPI;
22import com.fs.starfarer.api.campaign.LocationAPI;
23import com.fs.starfarer.api.campaign.OrbitAPI;
24import com.fs.starfarer.api.campaign.PlanetAPI;
25import com.fs.starfarer.api.campaign.SectorEntityToken;
26import com.fs.starfarer.api.campaign.StarSystemAPI;
27import com.fs.starfarer.api.campaign.econ.MarketAPI;
28import com.fs.starfarer.api.campaign.rules.MemoryAPI;
29import com.fs.starfarer.api.impl.campaign.DerelictShipEntityPlugin;
30import com.fs.starfarer.api.impl.campaign.DerelictShipEntityPlugin.DerelictShipData;
31import com.fs.starfarer.api.impl.campaign.ids.Conditions;
32import com.fs.starfarer.api.impl.campaign.ids.Entities;
33import com.fs.starfarer.api.impl.campaign.ids.Factions;
34import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
35import com.fs.starfarer.api.impl.campaign.ids.Tags;
36import com.fs.starfarer.api.impl.campaign.procgen.Constellation;
37import com.fs.starfarer.api.impl.campaign.procgen.ObjectiveGenDataSpec;
38import com.fs.starfarer.api.impl.campaign.procgen.SalvageEntityGenDataSpec;
39import com.fs.starfarer.api.impl.campaign.procgen.SalvageEntityGenDataSpec.DropData;
40import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator;
41import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator.LagrangePointType;
42import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator.StarSystemType;
43import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.SalvageEntity;
44import com.fs.starfarer.api.impl.campaign.terrain.AsteroidBeltTerrainPlugin;
45import com.fs.starfarer.api.impl.campaign.terrain.AsteroidFieldTerrainPlugin;
46import com.fs.starfarer.api.impl.campaign.terrain.BaseRingTerrain;
47import com.fs.starfarer.api.impl.campaign.terrain.BaseTiledTerrain;
48import com.fs.starfarer.api.impl.campaign.terrain.DebrisFieldTerrainPlugin;
49import com.fs.starfarer.api.impl.campaign.terrain.DebrisFieldTerrainPlugin.DebrisFieldParams;
50import com.fs.starfarer.api.impl.campaign.terrain.DebrisFieldTerrainPlugin.DebrisFieldSource;
51import com.fs.starfarer.api.impl.campaign.terrain.MagneticFieldTerrainPlugin;
52import com.fs.starfarer.api.impl.campaign.terrain.NebulaTerrainPlugin;
53import com.fs.starfarer.api.impl.campaign.terrain.PulsarBeamTerrainPlugin;
54import com.fs.starfarer.api.impl.campaign.terrain.RadioChatterTerrainPlugin;
55import com.fs.starfarer.api.impl.campaign.terrain.RingSystemTerrainPlugin;
56import com.fs.starfarer.api.impl.campaign.terrain.StarCoronaTerrainPlugin;
57import com.fs.starfarer.api.util.Misc;
58import com.fs.starfarer.api.util.WeightedRandomPicker;
59
60public abstract class BaseThemeGenerator implements ThemeGenerator {
61
62 public static enum HabitationLevel {
63 LOW,
64 MEDIUM,
65 HIGH,
66 }
67
68 public static class StarSystemData {
69 public StarSystemAPI system;
70 public List<PlanetAPI> stars = new ArrayList<PlanetAPI>();
71 public List<PlanetAPI> planets = new ArrayList<PlanetAPI>();
72 public List<PlanetAPI> habitable = new ArrayList<PlanetAPI>();
73 public List<PlanetAPI> gasGiants = new ArrayList<PlanetAPI>();
74 public List<PlanetAPI> resourceRich = new ArrayList<PlanetAPI>();
75
76 public Set<SectorEntityToken> alreadyUsed = new LinkedHashSet<SectorEntityToken>();
77
78 public Set<AddedEntity> generated = new LinkedHashSet<AddedEntity>();
79
80 public boolean isBlackHole() {
81 return system.getStar() != null && system.getStar().getSpec().isBlackHole();
82 }
83
84 public boolean isPulsar() {
85 //return system.getStar() != null && system.getStar().getSpec().getPlanetType().equals(StarTypes.NEUTRON_STAR);
86 return system.hasPulsar();
87 }
88
89 public boolean isNebula() {
90 return system.isNebula();
91 }
92
93 @Override
94 public String toString() {
95 return String.format(system.getName() + " %d %d %d %d %d", stars.size(), planets.size(), habitable.size(),
96 gasGiants.size(),
97 resourceRich.size());
98 }
99
100
101 }
102
103
104 public static boolean DEBUG = Global.getSettings().isDevMode();
105
106
107 public static class AddedEntity {
108 public SectorEntityToken entity;
109 public EntityLocation location;
110 public String entityType;
111 public AddedEntity(SectorEntityToken entity, EntityLocation location, String entityType) {
112 this.entity = entity;
113 this.location = location;
114 this.entityType = entityType;
115 }
116 }
117
118
119 public static enum LocationType {
120 PLANET_ORBIT,
121 GAS_GIANT_ORBIT,
122 JUMP_ORBIT,
123 NEAR_STAR,
124 IN_ASTEROID_BELT,
125 IN_ASTEROID_FIELD,
126 IN_RING,
127
128 L_POINT,
129 IN_SMALL_NEBULA,
130
131 OUTER_SYSTEM,
132 STAR_ORBIT,
133 }
134
135 public static class EntityLocation {
136 public LocationType type;
137 public Vector2f location = null;
138 public OrbitAPI orbit = null;
139
140
141 @Override
142 public String toString() {
143 return String.format("Type: %s, orbitPeriod: %s", type.name(), orbit == null ? "null" : "" + orbit.getOrbitalPeriod());
144 }
145
146
147 }
148
149 abstract public int getOrder();
150 abstract public String getThemeId();
151
152 public float getWeight() {
153 return 100f;
154 }
155
156 protected Random random;
160
161
162 abstract public void generateForSector(ThemeGenContext context, float allowedSectorFraction);
163
164
165 public void addShipGraveyard(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker<String> factions) {
166 if (random.nextFloat() >= chanceToAddAny) return;
167 int num = min + random.nextInt(max - min + 1);
168
169 for (int i = 0; i < num; i++) {
170 LinkedHashMap<LocationType, Float> weights = new LinkedHashMap<LocationType, Float>();
171// weights.put(LocationType.IN_ASTEROID_BELT, 5f);
172// weights.put(LocationType.IN_ASTEROID_FIELD, 5f);
173// weights.put(LocationType.IN_RING, 5f);
174// weights.put(LocationType.IN_SMALL_NEBULA, 5f);
175// weights.put(LocationType.L_POINT, 5f);
176// weights.put(LocationType.NEAR_STAR, 5f);
177// weights.put(LocationType.OUTER_SYSTEM, 5f);
178 weights.put(LocationType.STAR_ORBIT, 5f);
179 WeightedRandomPicker<EntityLocation> locs = getLocations(random, data.system, null, 1000f, weights);
180 EntityLocation loc = locs.pick();
181
182 if (loc != null) {
183 SectorEntityToken token = data.system.createToken(0, 0);
184 data.system.addEntity(token);
185 setEntityLocation(token, loc, null);
186 addShipGraveyard(data, token, factions);
187 }
188 }
189
190 }
191
192 public void addShipGraveyard(StarSystemData data, SectorEntityToken focus, WeightedRandomPicker<String> factions) {
193 addShipGraveyard(data, focus, factions, null);
194 }
195 public void addShipGraveyard(StarSystemData data, SectorEntityToken focus, WeightedRandomPicker<String> factions,
196 WeightedRandomPicker<String> hulls) {
197 int numShips = random.nextInt(9) + 3;
198 //numShips = 12;
199 if (DEBUG) System.out.println(" Adding ship graveyard (" + numShips + " ships)");
200
201 WeightedRandomPicker<Float> bands = new WeightedRandomPicker<Float>(random);
202 for (int i = 0; i < numShips + 5; i++) {
203 bands.add(new Float(140 + i * 20), (i + 1) * (i + 1));
204 }
205
206// WeightedRandomPicker<String> factions = new WeightedRandomPicker<String>(random);
207// factions.add(Factions.TRITACHYON, 10f);
208// factions.add(Factions.HEGEMONY, 7f);
209// factions.add(Factions.INDEPENDENT, 3f);
210
211 for (int i = 0; i < numShips; i++) {
212 float radius = bands.pickAndRemove();
213
214 DerelictShipData params = DerelictShipEntityPlugin.createRandom(factions.pick(), null, random, DerelictShipEntityPlugin.getDefaultSModProb());
215 if (hulls != null && !hulls.isEmpty()) {
217 }
218 if (params != null) {
219 CustomCampaignEntityAPI entity = (CustomCampaignEntityAPI) addSalvageEntity(random,
220 focus.getContainingLocation(),
221 Entities.WRECK, Factions.NEUTRAL, params);
222 entity.setDiscoverable(true);
223 float orbitDays = radius / (5f + random.nextFloat() * 10f);
224 entity.setCircularOrbit(focus, random.nextFloat() * 360f, radius, orbitDays);
225 if (DEBUG) System.out.println(" Added ship: " +
226 ((DerelictShipEntityPlugin)entity.getCustomPlugin()).getData().ship.variantId);
227
228 AddedEntity added = new AddedEntity(entity, null, Entities.WRECK);
229 data.generated.add(added);
230 }
231 }
232 }
233
234 public void addDerelictShips(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker<String> factions) {
235 if (random.nextFloat() >= chanceToAddAny) return;
236
237 //data.system.updateAllOrbits();
238
239 int num = min + random.nextInt(max - min + 1);
240 for (int i = 0; i < num; i++) {
241 EntityLocation loc = pickAnyLocation(random, data.system, 70f, null);
242 addDerelictShip(data, loc, factions);
243 }
244
245 }
246
247 public void addMiningStations(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker<String> stationTypes) {
248 if (random.nextFloat() >= chanceToAddAny) return;
249
250 int num = min + random.nextInt(max - min + 1);
251 if (DEBUG) System.out.println(" Adding " + num + " mining stations");
252 for (int i = 0; i < num; i++) {
253 List<PlanetAPI> miningCandidates = new ArrayList<PlanetAPI>();
254 miningCandidates.addAll(data.gasGiants);
255 miningCandidates.addAll(data.resourceRich);
256
257 LinkedHashMap<LocationType, Float> weights = new LinkedHashMap<LocationType, Float>();
258 weights.put(LocationType.IN_ASTEROID_BELT, 10f);
259 weights.put(LocationType.IN_ASTEROID_FIELD, 10f);
260 weights.put(LocationType.IN_RING, 10f);
261 weights.put(LocationType.IN_SMALL_NEBULA, 10f);
262 WeightedRandomPicker<EntityLocation> locs = getLocations(random, data.system, null, 100f, weights);
263 EntityLocation loc = locs.pick();
264
265 String type = stationTypes.pick();
266 if (loc != null || !miningCandidates.isEmpty()) {
267 if ((random.nextFloat() > 0.5f && loc != null) || miningCandidates.isEmpty()) {
268 addStation(loc, data, type, Factions.NEUTRAL);
269 } else {
270 PlanetAPI planet = miningCandidates.get(random.nextInt(miningCandidates.size()));
271 EntityLocation planetOrbitLoc = createLocationAtRandomGap(random, planet, 100f);
272 addStation(planetOrbitLoc, data, type, Factions.NEUTRAL);
273 data.alreadyUsed.add(planet);
274 }
275 }
276 }
277 }
278
279
280 public static float NOT_HABITABLE_PLANET_PROB = 0.1f;
281 public static float ORBITAL_HABITAT_PROB = 0.5f;
282
283 public void addHabCenters(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker<String> stationTypes) {
284 if (random.nextFloat() >= chanceToAddAny) return;
285
286 WeightedRandomPicker<PlanetAPI> habPlanets = new WeightedRandomPicker<PlanetAPI>(random);
287 for (PlanetAPI planet : data.habitable) {
288 float h = planet.getMarket().getHazardValue();
289 h -= 0.5f;
290 if (h < 0.1f) h = 0.1f;
291 float w = 1f / h;
292 habPlanets.add(planet, w);
293 }
294
295 WeightedRandomPicker<PlanetAPI> otherPlanets = new WeightedRandomPicker<PlanetAPI>(random);
296 for (PlanetAPI planet : data.planets) {
297 if (data.habitable.contains(planet)) continue;
298 otherPlanets.add(planet);
299 }
300
301 int num = min + random.nextInt(max - min + 1);
302 if (DEBUG) System.out.println(" Adding up to " + num + " hab centers on planets/in orbit");
303 for (int i = 0; i < num; i++) {
304 int option = 0;
305 if (!habPlanets.isEmpty() && (random.nextFloat() > NOT_HABITABLE_PLANET_PROB || i == 0)) {
306 option = 0; // habitable planet
307 } else {
308 if (otherPlanets.isEmpty() || random.nextFloat() < ORBITAL_HABITAT_PROB) {
309 option = 2; // orbital habitat
310 } else {
311 option = 1; // other planet
312 }
313 }
314
315 if (option == 0) {
316 PlanetAPI planet = habPlanets.pickAndRemove();
317 addRuins(planet);
318 data.alreadyUsed.add(planet);
319 } else if (option == 1) {
320 PlanetAPI planet = otherPlanets.pickAndRemove();
321 addRuins(planet);
322 data.alreadyUsed.add(planet);
323 } else if (option == 2) {
324 String type = stationTypes.pick();
325 EntityLocation loc = pickCommonLocation(random, data.system, 100f, true, null);
326 addStation(loc, data, type, Factions.NEUTRAL);
327 }
328 }
329 }
330
331
332 public void addResearchStations(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker<String> stationTypes) {
333 if (random.nextFloat() >= chanceToAddAny) return;
334
335 int num = min + random.nextInt(max - min + 1);
336 if (DEBUG) System.out.println(" Adding " + num + " research stations");
337 for (int i = 0; i < num; i++) {
338 String type = stationTypes.pick();
339
340 List<PlanetAPI> researchCandidates = new ArrayList<PlanetAPI>();
341 researchCandidates.addAll(data.gasGiants);
342
343 LinkedHashMap<LocationType, Float> weights = new LinkedHashMap<LocationType, Float>();
344 weights.put(LocationType.IN_SMALL_NEBULA, 5f);
345 weights.put(LocationType.GAS_GIANT_ORBIT, 10f);
346 weights.put(LocationType.NEAR_STAR, 5f);
347 WeightedRandomPicker<EntityLocation> locs = getLocations(random, data.system, data.alreadyUsed, 100f, weights);
348 EntityLocation loc = locs.pick();
349
350 if (loc != null) {
351 AddedEntity added = addStation(loc, data, type, Factions.NEUTRAL);
352 if (loc.orbit != null && loc.orbit.getFocus() instanceof PlanetAPI) {
353 PlanetAPI planet = (PlanetAPI) loc.orbit.getFocus();
354 if (!planet.isStar()) {
355 data.alreadyUsed.add(planet);
356 }
357 }
358 }
359 }
360 }
361
362
363 public void addRuins(PlanetAPI planet) {
364 if (planet == null) return;
365
366 MarketAPI market = planet.getMarket();
367 clearRuins(market);
368
369 String ruins = pickRuinsType(planet);
370 if (DEBUG) System.out.println(" Added " + ruins + " to " + market.getName());
371 market.addCondition(ruins);
372 if (shouldHaveDecivilized(planet, ruins)) {
373 if (DEBUG) System.out.println(" Added decivilized to " + market.getName());
374 market.addCondition(Conditions.DECIVILIZED);
375 }
376 }
377
378 public boolean shouldHaveDecivilized(PlanetAPI planet, String ruins) {
379 float chance = 0.25f;
380
381 if (planet.getMarket().hasCondition(Conditions.HABITABLE)) {
382 chance += 0.25f;
383 }
384
385 if (ruins != null && ruins.equals(Conditions.RUINS_EXTENSIVE)) {
386 chance += 0.1f;
387 }
388 if (ruins != null && ruins.equals(Conditions.RUINS_VAST)) {
389 chance += 0.2f;
390 }
391
392 return random.nextFloat() < chance;
393 }
394
395
396 public List<AddedEntity> addObjectives(StarSystemData data, float prob) {
397 List<AddedEntity> result = new ArrayList<AddedEntity>();
398
399 Set<String> used = new HashSet<String>();
400
401 float mult = 2f;
402 for (SectorEntityToken loc : data.system.getEntitiesWithTag(Tags.STABLE_LOCATION)) {
403 mult *= 0.5f;
404 if (random.nextFloat() >= prob * mult) continue;
405
406 WeightedRandomPicker<ObjectiveGenDataSpec> picker = new WeightedRandomPicker<ObjectiveGenDataSpec>(random);
407 for (Object o : Global.getSettings().getAllSpecs(ObjectiveGenDataSpec.class)) {
409 if (used.contains(spec.getCategory())) continue;
410 picker.add(spec, spec.getFrequency());
411 }
412
413 ObjectiveGenDataSpec pick = picker.pick();
414 if (pick == null) break;
415
416 used.add(pick.getCategory());
417
418 SectorEntityToken built = data.system.addCustomEntity(null,
419 null,
420 pick.getId(), // type of object, defined in custom_entities.json
421 Factions.NEUTRAL); // faction
422 built.getMemoryWithoutUpdate().set(MemFlags.OBJECTIVE_NON_FUNCTIONAL, true);
423 if (loc.getOrbit() != null) {
424 built.setOrbit(loc.getOrbit().makeCopy());
425 }
426 built.setLocation(loc.getLocation().x, loc.getLocation().y);
427 data.system.removeEntity(loc);
428
429 AddedEntity e = new AddedEntity(built, null, pick.getId());
430 result.add(e);
431 }
432
433
434 return result;
435 }
436
437 public static ObjectiveGenDataSpec getObjectiveSpec(String id) {
439 return spec;
440 }
441
442 public AddedEntity addCommRelay(StarSystemData data, float prob) {
443 if (random.nextFloat() >= prob) return null;
444
445 LinkedHashMap<LocationType, Float> weights = new LinkedHashMap<LocationType, Float>();
446 weights.put(LocationType.STAR_ORBIT, 10f);
447 weights.put(LocationType.OUTER_SYSTEM, 10f);
448 WeightedRandomPicker<EntityLocation> locs = getLocations(random, data.system, null, 100f, weights);
449 EntityLocation loc = locs.pick();
450
451 AddedEntity added = addNonSalvageEntity(data.system, loc, Entities.COMM_RELAY, Factions.NEUTRAL);
452 if (DEBUG && added != null) System.out.println(" Added comm relay");
453
454 if (added != null) {
455 convertOrbitNoSpin(added.entity);
456 added.entity.getMemoryWithoutUpdate().set(MemFlags.OBJECTIVE_NON_FUNCTIONAL, true);
457 }
458
459 return added;
460 }
461
462 //public static boolean USE_NEW_SPAWN = false;
463 public AddedEntity addInactiveGate(StarSystemData data, float prob, float probDebris, float probShips, WeightedRandomPicker<String> factions) {
464 if (random.nextFloat() >= prob) return null;
465
466// USE_NEW_SPAWN = false;
467// if (data.system != null && Misc.getDistance(data.system.getLocation(), new Vector2f(62500, -5500)) < 1000) {
468// System.out.println("efwefwefe");
469// USE_NEW_SPAWN = true;
470// }
471
472 LinkedHashMap<LocationType, Float> weights = new LinkedHashMap<LocationType, Float>();
473 weights.put(LocationType.STAR_ORBIT, 10f);
474 weights.put(LocationType.OUTER_SYSTEM, 10f);
475 WeightedRandomPicker<EntityLocation> locs = getLocations(random, data.system, null, 100f, weights);
476 EntityLocation loc = locs.pick();
477
478 AddedEntity added = addNonSalvageEntity(data.system, loc, Entities.INACTIVE_GATE, Factions.NEUTRAL);
479 if (DEBUG && added != null) System.out.println(" Added inactive gate to " + data.system.getNameWithLowercaseTypeShort());
480
481 if (added != null) {
482 convertOrbitNoSpin(added.entity);
483
484 if (random.nextFloat() < probDebris) {
485 if (DEBUG && added != null) System.out.println(" Added debris field around gate");
486 addDebrisField(data, added.entity, 500f + random.nextFloat() * 100f);
487 if (random.nextFloat() < probShips) {
488 if (DEBUG && added != null) System.out.println(" Added ship graveyard around gate");
489 addShipGraveyard(data, added.entity, factions);
490 }
491 }
492 }
493
494 return added;
495 }
496
497
498 public String pickRuinsType(PlanetAPI planet) {
499 WeightedRandomPicker<String> picker = new WeightedRandomPicker<String>(random);
500
501 float hazard = planet.getMarket().getHazardValue();
502
503 float add1 = 0, add2 = 0;
504
505 if (hazard <= 1f) {
506 add1 = 10f;
507 add2 = 5f;
508 } else if (hazard <= 1.25f) {
509 add1 = 5f;
510 add2 = 1f;
511 }
512
513 picker.add(Conditions.RUINS_SCATTERED, 10f);
514 picker.add(Conditions.RUINS_WIDESPREAD, 10f);
515 picker.add(Conditions.RUINS_EXTENSIVE, 3f + add1);
516 picker.add(Conditions.RUINS_VAST, 1f + add2);
517
518 return picker.pick();
519 }
520
521
522 public AddedEntity addStation(EntityLocation loc, StarSystemData data, String customEntityId, String factionId) {
523 if (loc == null) return null;
524
525 AddedEntity station = addEntity(random, data.system, loc, customEntityId, factionId);
526 if (station != null) {
527 data.generated.add(station);
528 }
529 SectorEntityToken focus = station.entity.getOrbitFocus();
530 if (DEBUG) System.out.println(" Added " + customEntityId);
531 if (focus instanceof PlanetAPI) {
532 PlanetAPI planet = (PlanetAPI) focus;
533 data.alreadyUsed.add(planet);
534
535 boolean nearStar = planet.isStar() && station.entity.getOrbit() != null && station.entity.getCircularOrbitRadius() < 5000;
536
537 if (planet.isStar() && !nearStar) {
538// station.entity.setFacing(random.nextFloat() * 360f);
539// convertOrbitNoSpin(station.entity);
540 } else {
541 convertOrbitPointingDown(station.entity);
542 }
543 }
544
545// station.entity.getMemoryWithoutUpdate().set(MemFlags.SALVAGE_DEFENDER_FACTION, Factions.REMNANTS);
546// station.entity.getMemoryWithoutUpdate().set(MemFlags.SALVAGE_DEFENDER_PROB, 1f);
547
548 return station;
549 }
550
551
552 public void addCaches(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker<String> cacheTypes) {
553 if (random.nextFloat() >= chanceToAddAny) return;
554
555 int num = min + random.nextInt(max - min + 1);
556 if (DEBUG) System.out.println(" Adding " + num + " resource caches");
557 for (int i = 0; i < num; i++) {
558 EntityLocation loc = pickHiddenLocation(random, data.system, 70f, null);
559 String type = cacheTypes.pick();
560 AddedEntity added = addEntity(random, data.system, loc, type, Factions.NEUTRAL);
561 if (added != null) {
562 data.generated.add(added);
563 }
564
565 if (DEBUG && added != null) System.out.println(" Added resource cache: " + type);
566 }
567 }
568
569 public void addDebrisFields(StarSystemData data, float chanceToAddAny, int min, int max) {
570 addDebrisFields(data, chanceToAddAny, min, max, null, 0f, 0, 0);
571 }
572 public void addDebrisFields(StarSystemData data, float chanceToAddAny, int min, int max, String defFaction, float defProb, int minStr, int maxStr) {
573 if (random.nextFloat() >= chanceToAddAny) return;
574
575 int numDebrisFields = min + random.nextInt(max - min + 1);
576 if (DEBUG) System.out.println(" Adding up to " + numDebrisFields + " debris fields");
577 for (int i = 0; i < numDebrisFields; i++) {
578
579
580 float radius = 150f + random.nextFloat() * 300f;
581 EntityLocation loc = pickAnyLocation(random, data.system, radius + 100f, null);
582 if (loc == null) continue;
583
584 DebrisFieldParams params = new DebrisFieldParams(
585 radius, // field radius - should not go above 1000 for performance reasons
586 -1f, // density, visual - affects number of debris pieces
587 10000000f, // duration in days
588 0f); // days the field will keep generating glowing pieces
589
590 if (defFaction != null) {
591 params.defFaction = defFaction;
592 params.defenderProb = defProb;
593 params.minStr = minStr;
594 params.maxStr = maxStr;
595 }
596
597 params.source = DebrisFieldSource.GEN;
598 SectorEntityToken debris = Misc.addDebrisField(data.system, params, random);
599 setEntityLocation(debris, loc, Entities.DEBRIS_FIELD_SHARED);
600
601 AddedEntity added = new AddedEntity(debris, loc, Entities.DEBRIS_FIELD_SHARED);
602 data.generated.add(added);
603
604 if (DEBUG) System.out.println(" Added debris field");
605 }
606 }
607
608 public AddedEntity addDebrisField(StarSystemData data, SectorEntityToken focus, float radius) {
609 DebrisFieldParams params = new DebrisFieldParams(
610 radius, // field radius - should not go above 1000 for performance reasons
611 -1f, // density, visual - affects number of debris pieces
612 10000000f, // duration in days
613 0f); // days the field will keep generating glowing pieces
614
615 params.source = DebrisFieldSource.GEN;
616 SectorEntityToken debris = Misc.addDebrisField(focus.getContainingLocation(), params, random);
617 debris.setCircularOrbit(focus, 0, 0, 100f);
618 if (DEBUG) System.out.println(" Added debris field");
619
620 EntityLocation loc = new EntityLocation();
621 loc.type = LocationType.OUTER_SYSTEM; // sigh
622 AddedEntity added = new AddedEntity(debris, loc, Entities.DEBRIS_FIELD_SHARED);
623 data.generated.add(added);
624
625 return added;
626 }
627
628
629 public WeightedRandomPicker<String> createStringPicker(Object ... params) {
630 return createStringPicker(random, params);
631 }
632
633 public static WeightedRandomPicker<String> createStringPicker(Random random, Object ... params) {
635 WeightedRandomPicker<String> picker = new WeightedRandomPicker<String>(random);
636 for (int i = 0; i < params.length; i += 2) {
637 String item = (String) params[i];
638 float weight = 0f;
639 if (params[i+1] instanceof Float) {
640 weight = (Float) params[i+1];
641 } else if (params[i+1] instanceof Integer) {
642 weight = (Integer) params[i+1];
643 }
644 picker.add(item, weight);
645 }
646 return picker;
647 }
648
649
650 public void addDerelictShip(StarSystemData data, EntityLocation loc, WeightedRandomPicker<String> factions) {
651 if (loc == null) return;
652
653// WeightedRandomPicker<String> factionPicker = new WeightedRandomPicker<String>(random);
654// for (String faction : factions) {
655// factionPicker.add(faction);
656// }
657 String faction = factions.pick();
659 if (params != null) {
660 CustomCampaignEntityAPI entity = (CustomCampaignEntityAPI) addSalvageEntity(random, data.system,
661 Entities.WRECK, Factions.NEUTRAL, params);
662 entity.setDiscoverable(true);
663 setEntityLocation(entity, loc, Entities.WRECK);
664 if (DEBUG) System.out.println(" Added ship: " +
665 ((DerelictShipEntityPlugin)entity.getCustomPlugin()).getData().ship.variantId);
666
667 AddedEntity added = new AddedEntity(entity, null, Entities.WRECK);
668 data.generated.add(added);
669 }
670
671 }
672
673 public AddedEntity addDerelictShip(StarSystemData data, EntityLocation loc, String variantId) {
674 if (loc == null) return null;
675
677 if (params != null) {
678 CustomCampaignEntityAPI entity = (CustomCampaignEntityAPI) addSalvageEntity(random, data.system,
679 Entities.WRECK, Factions.NEUTRAL, params);
680 entity.setDiscoverable(true);
681 setEntityLocation(entity, loc, Entities.WRECK);
682 if (DEBUG) System.out.println(" Added ship: " +
683 ((DerelictShipEntityPlugin)entity.getCustomPlugin()).getData().ship.variantId);
684
685 AddedEntity added = new AddedEntity(entity, null, Entities.WRECK);
686 data.generated.add(added);
687 return added;
688 }
689 return null;
690
691 }
692
693
694 public static EntityLocation pickCommonLocation(Random random, StarSystemAPI system, float gap, boolean allowStarOrbit, Set<SectorEntityToken> exclude) {
696 LinkedHashMap<LocationType, Float> weights = new LinkedHashMap<LocationType, Float>();
697 weights.put(LocationType.PLANET_ORBIT, 10f);
698 if (allowStarOrbit) {
699 weights.put(LocationType.STAR_ORBIT, 10f);
700 }
701 weights.put(LocationType.GAS_GIANT_ORBIT, 5f);
702 WeightedRandomPicker<EntityLocation> locs = getLocations(random, system, exclude, gap, weights);
703 if (locs.isEmpty()) {
704 return pickAnyLocation(random, system, gap, exclude);
705 }
706 return locs.pick();
707 }
708
709 public static EntityLocation pickUncommonLocation(Random random, StarSystemAPI system, float gap, Set<SectorEntityToken> exclude) {
711 LinkedHashMap<LocationType, Float> weights = new LinkedHashMap<LocationType, Float>();
712 weights.put(LocationType.IN_ASTEROID_BELT, 5f);
713 weights.put(LocationType.IN_ASTEROID_FIELD, 5f);
714 weights.put(LocationType.IN_RING, 5f);
715 weights.put(LocationType.IN_SMALL_NEBULA, 5f);
716 weights.put(LocationType.L_POINT, 5f);
717 weights.put(LocationType.GAS_GIANT_ORBIT, 5f);
718 weights.put(LocationType.JUMP_ORBIT, 5f);
719 weights.put(LocationType.NEAR_STAR, 5f);
720 weights.put(LocationType.OUTER_SYSTEM, 5f);
721 WeightedRandomPicker<EntityLocation> locs = getLocations(random, system, exclude, gap, weights);
722 if (locs.isEmpty()) {
723 return pickAnyLocation(random, system, gap, exclude);
724 }
725 return locs.pick();
726 }
727
728 public static EntityLocation pickAnyLocation(Random random, StarSystemAPI system, float gap, Set<SectorEntityToken> exclude) {
730 LinkedHashMap<LocationType, Float> weights = new LinkedHashMap<LocationType, Float>();
731 weights.put(LocationType.PLANET_ORBIT, 10f);
732 weights.put(LocationType.STAR_ORBIT, 10f);
733 weights.put(LocationType.IN_ASTEROID_BELT, 5f);
734 weights.put(LocationType.IN_ASTEROID_FIELD, 5f);
735 weights.put(LocationType.IN_RING, 5f);
736 weights.put(LocationType.IN_SMALL_NEBULA, 5f);
737 weights.put(LocationType.L_POINT, 5f);
738 weights.put(LocationType.GAS_GIANT_ORBIT, 5f);
739 weights.put(LocationType.JUMP_ORBIT, 5f);
740 weights.put(LocationType.NEAR_STAR, 5f);
741 weights.put(LocationType.OUTER_SYSTEM, 5f);
742 WeightedRandomPicker<EntityLocation> locs = getLocations(random, system, exclude, gap, weights);
743 return locs.pick();
744 }
745
746 public static EntityLocation pickHiddenLocation(Random random, StarSystemAPI system, float gap, Set<SectorEntityToken> exclude) {
748 LinkedHashMap<LocationType, Float> weights = new LinkedHashMap<LocationType, Float>();
749 weights.put(LocationType.IN_ASTEROID_BELT, 5f);
750 weights.put(LocationType.IN_ASTEROID_FIELD, 5f);
751 weights.put(LocationType.IN_RING, 5f);
752 weights.put(LocationType.IN_SMALL_NEBULA, 5f);
753 weights.put(LocationType.L_POINT, 5f);
754 weights.put(LocationType.GAS_GIANT_ORBIT, 5f);
755 weights.put(LocationType.NEAR_STAR, 5f);
756 weights.put(LocationType.OUTER_SYSTEM, 5f);
757 WeightedRandomPicker<EntityLocation> locs = getLocations(random, system, exclude, gap, weights);
758 if (locs.isEmpty()) {
759 return pickAnyLocation(random, system, gap, exclude);
760 }
761 return locs.pick();
762 }
763
764 public static EntityLocation pickHiddenLocationNotNearStar(Random random, StarSystemAPI system, float gap, Set<SectorEntityToken> exclude) {
766 LinkedHashMap<LocationType, Float> weights = new LinkedHashMap<LocationType, Float>();
767 weights.put(LocationType.IN_ASTEROID_BELT, 5f);
768 weights.put(LocationType.IN_ASTEROID_FIELD, 5f);
769 weights.put(LocationType.IN_RING, 5f);
770 weights.put(LocationType.IN_SMALL_NEBULA, 5f);
771 weights.put(LocationType.L_POINT, 5f);
772 weights.put(LocationType.GAS_GIANT_ORBIT, 5f);
773 weights.put(LocationType.OUTER_SYSTEM, 5f);
774 WeightedRandomPicker<EntityLocation> locs = getLocations(random, system, exclude, gap, weights);
775 if (locs.isEmpty()) {
776 return pickAnyLocation(random, system, gap, exclude);
777 }
778 return locs.pick();
779 }
780
781
782
783
784
785 public static WeightedRandomPicker<EntityLocation> getLocations(Random random, StarSystemAPI system,
786 float minGap, LinkedHashMap<LocationType, Float> weights) {
787 return getLocations(random, system, null, minGap, weights);
788 }
789 public static WeightedRandomPicker<EntityLocation> getLocations(Random random, StarSystemAPI system, Set<SectorEntityToken> exclude,
790 float minGap, LinkedHashMap<LocationType, Float> weights) {
792 WeightedRandomPicker<EntityLocation> result = new WeightedRandomPicker<EntityLocation>(random);
793
794 system.updateAllOrbits();
795
796// if (system.getType() == StarSystemType.TRINARY_1CLOSE_1FAR) {
797// System.out.println("fwfewfwe");
798// }
799
800 float inner = getInnerRadius(system);
801 float outer = getOuterRadius(system);
802 //outer += 1000f;
803 if (outer < 3000) outer = 3000;
804 if (outer > 25000) outer = 25000;
805
806 StarSystemType systemType = system.getType();
807
808 for (LocationType type : weights.keySet()) {
809 float weight = weights.get(type);
810 List<EntityLocation> locs = new ArrayList<EntityLocation>();
811 switch (type) {
812 case PLANET_ORBIT:
813 for (PlanetAPI planet : system.getPlanets()) {
814 //if (planet.isMoon()) continue;
815 if (planet.isGasGiant()) continue;
816 if (planet.isStar()) continue;
817 if (exclude != null && exclude.contains(planet)) continue;
818
819 float ow = getOrbitalRadius(planet);
820 List<OrbitGap> gaps = findGaps(planet, 100f, 100f + ow + minGap, minGap);
821 EntityLocation loc = createLocationAtRandomGap(random, planet, gaps, type);
822 if (loc != null) locs.add(loc);
823 }
824 break;
825 case L_POINT:
826 for (PlanetAPI planet : system.getPlanets()) {
827 if (planet.isStar()) continue;
828 if (planet.isMoon()) continue;
829 if (planet.getRadius() < 100) continue;
830 if (planet.getOrbit() == null || planet.getOrbit().getFocus() == null) continue;
831 if (planet.getCircularOrbitRadius() <= 0) continue;
832 for (LagrangePointType lpt : EnumSet.of(LagrangePointType.L4, LagrangePointType.L5)) {
833 float orbitRadius = planet.getCircularOrbitRadius();
834 float angleOffset = -StarSystemGenerator.LAGRANGE_OFFSET * 0.5f;
835 if (lpt == LagrangePointType.L5) angleOffset = StarSystemGenerator.LAGRANGE_OFFSET * 0.5f;
836 float angle = planet.getCircularOrbitAngle() + angleOffset;
837 Vector2f location = Misc.getUnitVectorAtDegreeAngle(angle);
838 location.scale(orbitRadius);
839 Vector2f.add(location, planet.getOrbit().getFocus().getLocation(), location);
840
841 boolean clear = isAreaEmpty(system, location);
842 if (clear) {
843 EntityLocation loc = new EntityLocation();
844 loc.type = type;
845 float orbitDays = planet.getCircularOrbitPeriod();
846// loc.orbit = Global.getFactory().createCircularOrbit(planet.getOrbitFocus(),
847// angle, orbitRadius, orbitDays);
848 loc.orbit = Global.getFactory().createCircularOrbitWithSpin(planet.getOrbitFocus(),
849 angle, orbitRadius, orbitDays, random.nextFloat() * 10f + 1f);
850 locs.add(loc);
851 }
852 }
853 }
854 break;
855 case GAS_GIANT_ORBIT:
856 for (PlanetAPI planet : system.getPlanets()) {
857 if (planet.isStar()) continue;
858 if (!planet.isGasGiant()) continue;
859 if (exclude != null && exclude.contains(planet)) continue;
860
861 float ow = getOrbitalRadius(planet);
862 List<OrbitGap> gaps = findGaps(planet, 100f, 100f + ow + minGap, minGap);
863 EntityLocation loc = createLocationAtRandomGap(random, planet, gaps, type);
864 if (loc != null) locs.add(loc);
865 }
866 break;
867 case JUMP_ORBIT:
868 List<SectorEntityToken> jumpPoints = system.getEntitiesWithTag(Tags.JUMP_POINT);
869 for (SectorEntityToken point : jumpPoints) {
870 if (exclude != null && exclude.contains(point)) continue;
871 List<OrbitGap> gaps = findGaps(point, 200f, 200f + point.getRadius() + minGap, minGap);
872 EntityLocation loc = createLocationAtRandomGap(random, point, gaps, type);
873 if (loc != null) locs.add(loc);
874 }
875 break;
876 case NEAR_STAR:
877 if (systemType != StarSystemType.NEBULA) {
878 float r = system.getStar().getRadius();
879 float extra = 500f;
880 r += extra;
881 List<OrbitGap> gaps = findGaps(system.getStar(), 200f, 200f + r + minGap, minGap);
882 EntityLocation loc = createLocationAtRandomGap(random, system.getStar(), gaps, type);
883 if (loc != null) locs.add(loc);
884
885 if (system.getSecondary() != null) {
886 r = system.getSecondary().getRadius();
887 gaps = findGaps(system.getSecondary(), 200f, 200f + r + minGap, minGap);
888 loc = createLocationAtRandomGap(random, system.getSecondary(), gaps, type);
889 if (loc != null) locs.add(loc);
890 }
891 if (system.getTertiary() != null) {
892 r = system.getTertiary().getRadius();
893 gaps = findGaps(system.getTertiary(), 200f, 200f + r + minGap, minGap);
894 loc = createLocationAtRandomGap(random, system.getTertiary(), gaps, type);
895 if (loc != null) locs.add(loc);
896 }
897 }
898 break;
899 case IN_RING:
900 for (CampaignTerrainAPI terrain : system.getTerrainCopy()) {
901 if (exclude != null && exclude.contains(terrain)) continue;
902 if (terrain.hasTag(Tags.ACCRETION_DISK)) continue;
903 CampaignTerrainPlugin plugin = terrain.getPlugin();
904 if (plugin instanceof RingSystemTerrainPlugin) {
905 RingSystemTerrainPlugin ring = (RingSystemTerrainPlugin) plugin;
906 float start = ring.params.middleRadius - ring.params.bandWidthInEngine / 2f;
907 List<OrbitGap> gaps = findGaps(terrain,
908 start - 100f, start + ring.params.bandWidthInEngine + 100f, minGap);
909 EntityLocation loc = createLocationAtRandomGap(random, terrain, gaps, type);
910 if (loc != null) locs.add(loc);
911 }
912 }
913 break;
914 case IN_SMALL_NEBULA:
915 for (CampaignTerrainAPI terrain : system.getTerrainCopy()) {
916 if (exclude != null && exclude.contains(terrain)) continue;
917 CampaignTerrainPlugin plugin = terrain.getPlugin();
918 if (plugin instanceof NebulaTerrainPlugin) {
919 NebulaTerrainPlugin nebula = (NebulaTerrainPlugin) plugin;
920 float tilesHigh = nebula.getTiles()[0].length;
921 float tilesWide = nebula.getTiles().length;
922 float ts = nebula.getTileSize();
923 float w = ts * tilesWide;
924 float h = ts * tilesHigh;
925 if (w <= 10000) {
926 float r = (float) Math.sqrt(w * w + h * h);
927 if (terrain.getOrbit() == null) {
928 Vector2f point = Misc.getPointWithinRadius(terrain.getLocation(), r * 0.5f, random);
929 EntityLocation loc = new EntityLocation();
930 loc.type = type;
931 loc.location = point;
932 loc.orbit = null;
933 locs.add(loc);
934 } else {
935 float min = Math.min(100f, r * 0.25f);
936 float max = r;
937 EntityLocation loc = new EntityLocation();
938 loc.type = type;
939 float orbitRadius = min + (max - min) * (0.75f * random.nextFloat());
940 float orbitDays = orbitRadius / (20f + random.nextFloat() * 5f);
941 loc.orbit = Global.getFactory().createCircularOrbitWithSpin(terrain,
942 random.nextFloat() * 360f, orbitRadius, orbitDays, random.nextFloat() * 10f + 1f);
943 locs.add(loc);
944 }
945 }
946 }
947 }
948 break;
949 case IN_ASTEROID_BELT:
950 for (CampaignTerrainAPI terrain : system.getTerrainCopy()) {
951 if (exclude != null && exclude.contains(terrain)) continue;
952 CampaignTerrainPlugin plugin = terrain.getPlugin();
953 if (plugin instanceof AsteroidBeltTerrainPlugin && !(plugin instanceof AsteroidFieldTerrainPlugin)) {
954 AsteroidBeltTerrainPlugin ring = (AsteroidBeltTerrainPlugin) plugin;
955 if (ring.params != null) {
956 float start = ring.params.middleRadius - ring.params.bandWidthInEngine / 2f;
957 List<OrbitGap> gaps = findGaps(terrain,
958 start - 100f, start + ring.params.bandWidthInEngine + 100f, minGap);
959 EntityLocation loc = createLocationAtRandomGap(random, terrain, gaps, type);
960 if (loc != null) locs.add(loc);
961 } else {
962 //System.out.println("egaegfwgwgew");
963 }
964 }
965 }
966 break;
967 case IN_ASTEROID_FIELD:
968 for (CampaignTerrainAPI terrain : system.getTerrainCopy()) {
969 if (exclude != null && exclude.contains(terrain)) continue;
970 CampaignTerrainPlugin plugin = terrain.getPlugin();
971 if (plugin instanceof AsteroidFieldTerrainPlugin) {
972 AsteroidFieldTerrainPlugin ring = (AsteroidFieldTerrainPlugin) plugin;
973 if (isAreaEmpty(system, terrain.getLocation())) {
974 float min = Math.min(100f, ring.params.bandWidthInEngine * 0.25f);
975 float max = ring.params.bandWidthInEngine;
976 EntityLocation loc = new EntityLocation();
977 loc.type = type;
978 float orbitRadius = min + (max - min) * (0.75f * random.nextFloat());
979 float orbitDays = orbitRadius / (20f + random.nextFloat() * 5f);
980// loc.orbit = Global.getFactory().createCircularOrbit(terrain,
981// random.nextFloat() * 360f, orbitRadius, orbitDays);
982 loc.orbit = Global.getFactory().createCircularOrbitWithSpin(terrain,
983 random.nextFloat() * 360f, orbitRadius, orbitDays, random.nextFloat() * 10f + 1f);
984 locs.add(loc);
985
986 }
987 }
988 }
989 break;
990 case OUTER_SYSTEM:
991 SectorEntityToken near = pickOuterEntityToSpawnNear(random, system);
992// if (!USE_NEW_SPAWN && near != null) {
993// EntityLocation loc = new EntityLocation();
994// loc.type = type;
995// float orbitRadius = 3000 + 1500f * random.nextFloat();
996// float orbitDays = orbitRadius / (20f + random.nextFloat() * 5f);
997// loc.orbit = Global.getFactory().createCircularOrbitWithSpin(near,
998// random.nextFloat() * 360f, orbitRadius, orbitDays, random.nextFloat() * 10f + 1f);
999// locs.add(loc);
1000// } else {
1001 if (near != null && near.getCircularOrbitRadius() > 0) {
1002 EntityLocation loc = new EntityLocation();
1003 loc.type = type;
1004 // float orbitRadius = 3000 + 1500f * random.nextFloat();
1005 // float orbitDays = orbitRadius / (20f + random.nextFloat() * 5f);
1008 // loc.orbit = Global.getFactory().createCircularOrbitWithSpin(near,
1009 // random.nextFloat() * 360f, orbitRadius, orbitDays, random.nextFloat() * 10f + 1f);
1010 float orbitRadius = near.getCircularOrbitRadius() + 1000f + 1500f * random.nextFloat();
1011 float orbitDays = near.getCircularOrbitPeriod();
1012 loc.orbit = Global.getFactory().createCircularOrbitWithSpin(system.getCenter(),
1013 near.getCircularOrbitAngle() + 15f - 30f * random.nextFloat(),
1014 orbitRadius, orbitDays, random.nextFloat() * 10f + 1f);
1015 locs.add(loc);
1016 } else if (near != null) {
1017 EntityLocation loc = new EntityLocation();
1018 loc.type = type;
1019 float orbitRadius = outer + 500f + 500f * random.nextFloat();
1020 float orbitDays = orbitRadius / (20f + random.nextFloat() * 5f);
1021 loc.orbit = Global.getFactory().createCircularOrbitWithSpin(system.getCenter(),
1022 random.nextFloat() * 360f, orbitRadius, orbitDays, random.nextFloat() * 10f + 1f);
1023 locs.add(loc);
1024 }
1025// }
1026 break;
1027 case STAR_ORBIT:
1028// if (system.getType() == StarSystemType.TRINARY_1CLOSE_1FAR) {
1029// System.out.println("fwfewfwe");
1030// }
1031
1032 SectorEntityToken main = system.getCenter();
1033 List<SectorEntityToken> secondary = new ArrayList<SectorEntityToken>();
1034 switch (system.getType()) {
1035 case BINARY_FAR:
1036 secondary.add(system.getSecondary());
1037 break;
1038 case TRINARY_1CLOSE_1FAR:
1039 secondary.add(system.getTertiary());
1040 break;
1041 case TRINARY_2FAR:
1042 secondary.add(system.getSecondary());
1043 secondary.add(system.getTertiary());
1044 break;
1045 }
1046
1047 if (main != null) {
1048 List<OrbitGap> gaps = findGaps(main, inner, outer + minGap, minGap);
1049 EntityLocation loc;
1050 for (OrbitGap gap : gaps) {
1051 loc = createLocationAtGap(random, main, gap, type);
1052 if (loc != null) locs.add(loc);
1053 }
1054 }
1055
1056 for (SectorEntityToken star : secondary) {
1057 float ow = getOrbitalRadius((PlanetAPI) star);
1058 if (ow < 3000) ow = 3000;
1059 float r = star.getRadius();
1060 List<OrbitGap> gaps = findGaps(star, r, ow + r + minGap, minGap);
1061 EntityLocation loc;
1062 for (OrbitGap gap : gaps) {
1063 loc = createLocationAtGap(random, star, gap, type);
1064 if (loc != null) locs.add(loc);
1065 }
1066 }
1067
1068 break;
1069 }
1070
1071 // if in nebula, convert circular orbits to fixed locations
1072 if (system.getType() == StarSystemType.NEBULA) {
1073 for (EntityLocation loc : locs) {
1074 if (loc.orbit != null && loc.orbit.getFocus() == system.getCenter()) {
1075 loc.location = loc.orbit.computeCurrentLocation();
1076 loc.orbit = null;
1077 }
1078 }
1079 }
1080
1081 if (!locs.isEmpty()) {
1082 float weightPer = weight / (float) locs.size();
1083 for (EntityLocation loc : locs) {
1084 result.add(loc, weightPer);
1085 }
1086 }
1087
1088 }
1089
1090 return result;
1091 }
1092
1093 public static EntityLocation createLocationAtRandomGap(Random random, SectorEntityToken center, float minGap) {
1094 if (random == null) random = StarSystemGenerator.random;
1095 float ow = getOrbitalRadius(center);
1096 List<OrbitGap> gaps = findGaps(center, 100f, 100f + ow + minGap, minGap);
1097 EntityLocation loc = createLocationAtRandomGap(random, center, gaps, LocationType.PLANET_ORBIT);
1098 return loc;
1099 }
1100
1101
1102 private static EntityLocation createLocationAtRandomGap(Random random, SectorEntityToken center, List<OrbitGap> gaps, LocationType type) {
1103 if (gaps.isEmpty()) return null;
1104 if (random == null) random = StarSystemGenerator.random;
1105 WeightedRandomPicker<OrbitGap> picker = new WeightedRandomPicker<OrbitGap>(random);
1106 picker.addAll(gaps);
1107 OrbitGap gap = picker.pick();
1108 return createLocationAtGap(random, center, gap, type);
1109 }
1110
1111 private static EntityLocation createLocationAtGap(Random random, SectorEntityToken center, OrbitGap gap, LocationType type) {
1112 if (gap != null) {
1113 if (random == null) random = StarSystemGenerator.random;
1114 EntityLocation loc = new EntityLocation();
1115 loc.type = type;
1116 float orbitRadius = gap.start + (gap.end - gap.start) * (0.25f + 0.5f * random.nextFloat());
1117 float orbitDays = orbitRadius / (20f + random.nextFloat() * 5f);
1118// loc.orbit = Global.getFactory().createCircularOrbit(center,
1119// random.nextFloat() * 360f, orbitRadius, orbitDays);
1120 loc.orbit = Global.getFactory().createCircularOrbitWithSpin(center,
1121 random.nextFloat() * 360f, orbitRadius, orbitDays, random.nextFloat() * 10f + 1f);
1122 return loc;
1123 }
1124 return null;
1125 }
1126
1127
1128 public static class OrbitGap {
1129 public float start;
1130 public float end;
1131 }
1132
1133 public static class OrbitItem {
1134 public SectorEntityToken item;
1135 public float orbitRadius;
1136 public float orbitalWidth;
1137 }
1138
1139 public static List<OrbitGap> findGaps(SectorEntityToken center, float minPad, float maxDist, float minGap) {
1140 List<OrbitGap> gaps = new ArrayList<OrbitGap>();
1141
1142 LocationAPI loc = center.getContainingLocation();
1143 if (loc == null) return gaps;
1144
1145 List<OrbitItem> items = new ArrayList<OrbitItem>();
1146 for (PlanetAPI planet : loc.getPlanets()) {
1147 if (planet.getOrbitFocus() != center) continue;
1148
1149 OrbitItem item = new OrbitItem();
1150 item.item = planet;
1151 item.orbitRadius = planet.getCircularOrbitRadius();
1152 if (item.orbitRadius > maxDist) continue;
1153
1154 item.orbitalWidth = getOrbitalRadius(planet) * 2f;
1155 items.add(item);
1156 }
1157
1158 for (CampaignTerrainAPI terrain : loc.getTerrainCopy()) {
1159 if (terrain.getOrbitFocus() != center) continue;
1160
1161 CampaignTerrainPlugin plugin = terrain.getPlugin();
1162 if (plugin instanceof StarCoronaTerrainPlugin) continue;
1163 if (plugin instanceof MagneticFieldTerrainPlugin) continue;
1164 if (plugin instanceof PulsarBeamTerrainPlugin) continue;
1165
1166 if (plugin instanceof BaseRingTerrain) {
1167 BaseRingTerrain ring = (BaseRingTerrain) plugin;
1168
1169 OrbitItem item = new OrbitItem();
1170 item.item = terrain;
1171 item.orbitRadius = ring.params.middleRadius;
1172 if (item.orbitRadius > maxDist) continue;
1173
1174 item.orbitalWidth = ring.params.bandWidthInEngine;
1175 items.add(item);
1176 }
1177 }
1178
1179 List<CustomCampaignEntityAPI> entities = loc.getEntities(CustomCampaignEntityAPI.class);
1180 for (SectorEntityToken custom : entities) {
1181 if (custom.getOrbitFocus() != center) continue;
1182
1183 OrbitItem item = new OrbitItem();
1184 item.item = custom;
1185 item.orbitRadius = custom.getCircularOrbitRadius();
1186 if (item.orbitRadius > maxDist) continue;
1187
1188 item.orbitalWidth = custom.getRadius() * 2f;
1189 items.add(item);
1190 }
1191
1192 //List<SectorEntityToken> jumpPoints = loc.getEntitiesWithTag(Tags.JUMP_POINT);
1193 List<SectorEntityToken> jumpPoints = loc.getJumpPoints();
1194 for (SectorEntityToken point : jumpPoints) {
1195 if (point.getOrbitFocus() != center) continue;
1196
1197 OrbitItem item = new OrbitItem();
1198 item.item = point;
1199 item.orbitRadius = point.getCircularOrbitRadius();
1200 if (item.orbitRadius > maxDist) continue;
1201
1202 item.orbitalWidth = point.getRadius() * 2f;
1203 items.add(item);
1204 }
1205
1206 Collections.sort(items, new Comparator<OrbitItem>() {
1207 public int compare(OrbitItem o1, OrbitItem o2) {
1208 return (int)Math.signum(o1.orbitRadius - o2.orbitRadius);
1209 }
1210 });
1211
1212 float prev = center.getRadius() + minPad;
1213 for (OrbitItem item : items) {
1214 float next = item.orbitRadius - item.orbitalWidth / 2f;
1215 if (next - prev >= minGap) {
1216 OrbitGap gap = new OrbitGap();
1217 gap.start = prev;
1218 gap.end = next;
1219 gaps.add(gap);
1220 }
1221 prev = Math.max(prev, item.orbitRadius + item.orbitalWidth / 2f);
1222 }
1223
1224 if (maxDist - prev >= minGap) {
1225 OrbitGap gap = new OrbitGap();
1226 gap.start = prev;
1227 gap.end = maxDist;
1228 gaps.add(gap);
1229 }
1230
1231 return gaps;
1232 }
1233
1234
1235 public static float getInnerRadius(StarSystemAPI system) {
1236 switch (system.getType()) {
1237 case NEBULA:
1238 return 0;
1239 case DEEP_SPACE:
1240 return 500f;
1241 case SINGLE:
1242 case BINARY_FAR:
1243 case TRINARY_2FAR:
1244 if (system.getStar() == null) return 0; // alpha site
1245 return system.getStar().getRadius();
1246 case BINARY_CLOSE:
1247 case TRINARY_1CLOSE_1FAR:
1248 return Math.max(system.getStar().getCircularOrbitRadius() + system.getStar().getRadius(),
1249 system.getSecondary().getCircularOrbitRadius() + system.getSecondary().getRadius());
1250 case TRINARY_2CLOSE:
1251 float max = Math.max(system.getStar().getCircularOrbitRadius() + system.getStar().getRadius(),
1252 system.getSecondary().getCircularOrbitRadius() + system.getSecondary().getRadius());
1253 max = Math.max(max,
1254 system.getTertiary().getCircularOrbitRadius() + system.getTertiary().getRadius());
1255 return max;
1256 }
1257 return 0;
1258 }
1259
1260
1261 public static SectorEntityToken pickOuterEntityToSpawnNear(Random random, StarSystemAPI system) {
1262 if (random == null) random = StarSystemGenerator.random;
1263
1264 WeightedRandomPicker<SectorEntityToken> picker = new WeightedRandomPicker<SectorEntityToken>(random);
1265 float max = getOuterRadius(system);
1266 float threshold = max * 0.75f;
1267
1268 for (PlanetAPI planet : system.getPlanets()) {
1269 float r = planet.getLocation().length() + getOrbitalRadius(planet);
1270 if (r > threshold) {
1271 picker.add(planet);
1272 }
1273 }
1274
1275// for (CampaignTerrainAPI terrain : system.getTerrainCopy()) {
1276// CampaignTerrainPlugin plugin = terrain.getPlugin();
1277// if (plugin instanceof BaseRingTerrain && !(plugin instanceof PulsarBeamTerrainPlugin)) {
1278// BaseRingTerrain ring = (BaseRingTerrain) plugin;
1279// float r = ring.params.middleRadius + ring.params.bandWidthInEngine * 0.5f;
1280// r += Misc.getDistance(system.getCenter().getLocation(), terrain.getLocation());
1281// if (r > threshold) {
1282// picker.add(terrain);
1283// }
1284// } else if (plugin instanceof BaseTiledTerrain) {
1285// if (plugin instanceof NebulaTerrainPlugin) continue;
1286//
1287// BaseTiledTerrain tiles = (BaseTiledTerrain) plugin;
1288// float r = tiles.getRenderRange();
1289// r += Misc.getDistance(system.getCenter().getLocation(), terrain.getLocation());
1290// if (r > threshold) {
1291// picker.add(terrain);
1292// }
1293// }
1294// }
1295
1296 List<SectorEntityToken> jumpPoints = system.getEntitiesWithTag(Tags.JUMP_POINT);
1297 for (SectorEntityToken point : jumpPoints) {
1298 float r = Misc.getDistance(system.getCenter().getLocation(), point.getLocation());
1299 r += point.getRadius();
1300 if (r > threshold) {
1301 picker.add(point);
1302 }
1303 }
1304
1305 return picker.pick();
1306 }
1307
1308
1309 public static float getOuterRadius(StarSystemAPI system) {
1310 float max = 0f;
1311
1312 for (PlanetAPI planet : system.getPlanets()) {
1313 //float r = planet.getCircularOrbitRadius() + getOrbitalRadius(planet);
1314 float r = planet.getLocation().length() + getOrbitalRadius(planet);
1315 if (r > max) max = r;
1316 }
1317
1318 for (CampaignTerrainAPI terrain : system.getTerrainCopy()) {
1319 CampaignTerrainPlugin plugin = terrain.getPlugin();
1320
1321 if (plugin instanceof BaseRingTerrain && !(plugin instanceof PulsarBeamTerrainPlugin)) {
1322 BaseRingTerrain ring = (BaseRingTerrain) plugin;
1323 float r = ring.params.middleRadius + ring.params.bandWidthInEngine * 0.5f;
1324 r += Misc.getDistance(system.getCenter().getLocation(), terrain.getLocation());
1325 if (r > max) max = r;
1326 } else if (plugin instanceof BaseTiledTerrain) {
1327 if (plugin instanceof NebulaTerrainPlugin) continue;
1328
1329 BaseTiledTerrain tiles = (BaseTiledTerrain) plugin;
1330 float r = tiles.getRenderRange();
1331 r += Misc.getDistance(system.getCenter().getLocation(), terrain.getLocation());
1332 if (r > max) max = r;
1333 }
1334 }
1335
1336// List<CustomCampaignEntityAPI> entities = system.getEntities(CustomCampaignEntityAPI.class);
1337// for (SectorEntityToken custom : entities) {
1338// //float r = custom.getCircularOrbitRadius() + custom.getRadius();
1339// float r = Misc.getDistance(system.getCenter().getLocation(), custom.getLocation());
1340// r += custom.getRadius();
1341// if (r > max) max = r;
1342// }
1343
1344 List<SectorEntityToken> jumpPoints = system.getEntitiesWithTag(Tags.JUMP_POINT);
1345 for (SectorEntityToken point : jumpPoints) {
1346 float r = Misc.getDistance(system.getCenter().getLocation(), point.getLocation());
1347 r += point.getRadius();
1348 if (r > max) max = r;
1349 }
1350
1351 return max;
1352 }
1353
1354 public static boolean isAreaEmpty(LocationAPI loc, Vector2f coords) {
1355 //loc.updateAllOrbits();
1356
1357 float range = 400f;
1358 for (PlanetAPI planet : loc.getPlanets()) {
1359 float dist = Misc.getDistance(planet.getLocation(), coords);
1360 if (dist < range + planet.getRadius()) return false;
1361 }
1362
1363 List<CustomCampaignEntityAPI> entities = loc.getEntities(CustomCampaignEntityAPI.class);
1364 for (SectorEntityToken custom : entities) {
1365 float dist = Misc.getDistance(custom.getLocation(), coords);
1366 if (dist < range + custom.getRadius()) {
1367 return false;
1368 }
1369 }
1370
1371 for (CampaignTerrainAPI terrain : loc.getTerrainCopy()) {
1372 CampaignTerrainPlugin plugin = terrain.getPlugin();
1373// if (plugin instanceof PulsarBeamTerrainPlugin) continue;
1374// if (plugin instanceof HyperspaceTerrainPlugin) continue;
1375// if (plugin instanceof NebulaTerrainPlugin) continue;
1376// if (plugin instanceof BaseRingTerrain) {
1377 if (plugin instanceof DebrisFieldTerrainPlugin) {
1378 DebrisFieldTerrainPlugin ring = (DebrisFieldTerrainPlugin) plugin;
1379 float r = ring.params.middleRadius + ring.params.bandWidthInEngine * 0.5f;
1380 float dist = Misc.getDistance(terrain.getLocation(), coords);
1381 if (dist < range + r) return false;
1382 }
1383 }
1384
1385 return true;
1386 }
1387
1388 public static float getOrbitalRadius(SectorEntityToken center) {
1389 LocationAPI loc = center.getContainingLocation();
1390 if (loc == null) return center.getRadius();
1391
1392 float max = center.getRadius();
1393 for (PlanetAPI planet : loc.getPlanets()) {
1394 if (planet.getOrbitFocus() != center) continue;
1395 float r = planet.getCircularOrbitRadius() + getOrbitalRadius(planet);
1396 if (r > max) max = r;
1397 }
1398
1399 for (CampaignTerrainAPI terrain : loc.getTerrainCopy()) {
1400 if (terrain.getOrbitFocus() != center) continue;
1401 CampaignTerrainPlugin plugin = terrain.getPlugin();
1402
1403 if (plugin instanceof PulsarBeamTerrainPlugin) continue;
1404 if (plugin instanceof RadioChatterTerrainPlugin) continue;
1405
1406 if (plugin instanceof BaseRingTerrain) {
1407 BaseRingTerrain ring = (BaseRingTerrain) plugin;
1408 float r = ring.params.middleRadius + ring.params.bandWidthInEngine * 0.5f;
1409 if (r > max) max = r;
1410 }
1411 }
1412
1413 List<CustomCampaignEntityAPI> entities = loc.getEntities(CustomCampaignEntityAPI.class);
1414 for (SectorEntityToken custom : entities) {
1415 if (custom.getOrbitFocus() != center) continue;
1416 float r = custom.getCircularOrbitRadius() + custom.getRadius();
1417 if (r > max) max = r;
1418 }
1419
1420 return max;
1421 }
1422
1423 public static AddedEntity addEntity(Random random, StarSystemAPI system, WeightedRandomPicker<EntityLocation> locs, String type, String faction) {
1424 EntityLocation loc = locs.pickAndRemove();
1425 return addEntity(random, system, loc, type, faction);
1426 }
1427
1428 public static AddedEntity addNonSalvageEntity(LocationAPI system, EntityLocation loc, String type, String faction) {
1429 if (loc != null) {
1430 SectorEntityToken entity = system.addCustomEntity(null, null, type, faction);
1431 if (loc.orbit != null) {
1432 entity.setOrbit(loc.orbit);
1433 loc.orbit.setEntity(entity);
1434 } else {
1435 entity.setOrbit(null);
1436 entity.getLocation().set(loc.location);
1437 }
1438 AddedEntity data = new AddedEntity(entity, loc, type);
1439 return data;
1440 }
1441 return null;
1442 }
1443
1444 public static AddedEntity addEntityAutoDetermineType(Random random, LocationAPI system, EntityLocation loc, String type, String faction) {
1446 return addEntity(random, system, loc, type, faction);
1447 } else {
1448 return addNonSalvageEntity(system, loc, type, faction);
1449 }
1450 }
1451
1452 public static AddedEntity addEntity(Random random, LocationAPI system, EntityLocation loc, String type, String faction) {
1453 if (loc != null) {
1454 if (random == null) random = StarSystemGenerator.random;
1455 SectorEntityToken entity = addSalvageEntity(random, system, type, faction);
1456 if (loc.orbit != null) {
1457 entity.setOrbit(loc.orbit);
1458 loc.orbit.setEntity(entity);
1459 } else {
1460 entity.setOrbit(null);
1461 entity.getLocation().set(loc.location);
1462 }
1463 AddedEntity data = new AddedEntity(entity, loc, type);
1464 return data;
1465 }
1466 return null;
1467 }
1468
1469 public static AddedEntity setEntityLocation(SectorEntityToken entity, EntityLocation loc, String type) {
1470 if (loc != null) {
1471 if (loc.orbit != null) {
1472 entity.setOrbit(loc.orbit);
1473 loc.orbit.setEntity(entity);
1474 } else {
1475 entity.setOrbit(null);
1476 entity.getLocation().set(loc.location);
1477 }
1478 AddedEntity data = new AddedEntity(entity, loc, type);
1479 return data;
1480 }
1481 return null;
1482 }
1483
1484 public static SectorEntityToken addSalvageEntity(LocationAPI location, String id, String faction) {
1485 return addSalvageEntity(null, location, id, faction);
1486 }
1487 public static SectorEntityToken addSalvageEntity(Random random, LocationAPI location, String id, String faction) {
1488 return addSalvageEntity(random, location, id, faction, null);
1489 }
1490 public static SectorEntityToken addSalvageEntity(LocationAPI location, String id, String faction, Object pluginParams) {
1491 return addSalvageEntity(null, location, id, faction, pluginParams);
1492 }
1493 public static SectorEntityToken addSalvageEntity(Random random, LocationAPI location, String id, String faction, Object pluginParams) {
1494 if (random == null) random = StarSystemGenerator.random;
1496
1497 CustomCampaignEntityAPI entity = location.addCustomEntity(null, spec.getNameOverride(), id, faction, pluginParams);
1498
1499 if (spec.getRadiusOverride() > 0) {
1500 entity.setRadius(spec.getRadiusOverride());
1501 }
1502
1503 switch (spec.getType()) {
1504 case ALWAYS_VISIBLE:
1505 entity.setSensorProfile(null);
1506 entity.setDiscoverable(null);
1507 break;
1508 case DISCOVERABLE:
1509 entity.setSensorProfile(1f);
1510 entity.setDiscoverable(true);
1511 break;
1512 case NOT_DISCOVERABLE:
1513 entity.setSensorProfile(1f);
1514 entity.setDiscoverable(false);
1515 break;
1516 }
1517
1518 long seed = random.nextLong();
1519 entity.getMemoryWithoutUpdate().set(MemFlags.SALVAGE_SEED, seed);
1520
1521 entity.getDetectedRangeMod().modifyFlat("gen", spec.getDetectionRange());
1522
1523 return entity;
1524 }
1525
1526
1527 public static CargoAPI genCargoFromDrop(SectorEntityToken entity) {
1528 MemoryAPI memory = entity.getMemoryWithoutUpdate();
1529 long seed = memory.getLong(MemFlags.SALVAGE_SEED);
1530 Random random = Misc.getRandom(seed, 1);
1531
1532 List<DropData> dropValue = new ArrayList<DropData>(entity.getDropValue());
1533 List<DropData> dropRandom = new ArrayList<DropData>(entity.getDropRandom());
1535 SalvageEntityGenDataSpec.class, entity.getCustomEntityType(), true);
1536
1537 if (spec != null) {
1538 dropValue.addAll(spec.getDropValue());
1539 dropRandom.addAll(spec.getDropRandom());
1540 }
1541
1542 CargoAPI salvage = SalvageEntity.generateSalvage(random, 1f, 1f, 1f, 1f, dropValue, dropRandom);
1543 return salvage;
1544 }
1545
1546
1547 public static StarSystemData computeSystemData(StarSystemAPI system) {
1548 StarSystemData data = new StarSystemData();
1549 data.system = system;
1550
1551 for (PlanetAPI planet : system.getPlanets()) {
1552 if (planet.isStar()) {
1553 data.stars.add(planet);
1554 } else {
1555 data.planets.add(planet);
1556 }
1557
1558 if (planet.isGasGiant()) {
1559 data.gasGiants.add(planet);
1560 }
1561
1562 if (planet.getMarket() != null && planet.getMarket().isPlanetConditionMarketOnly()) {
1563 MarketAPI market = planet.getMarket();
1564 if (market.hasCondition(Conditions.HABITABLE)) {
1565 data.habitable.add(planet);
1566 }
1567
1569 if (market.hasCondition(conditionId)) {
1570 data.resourceRich.add(planet);
1571 break;
1572 }
1573 }
1574
1575 }
1576 }
1577
1578 return data;
1579 }
1580
1581 public static void clearRuins(MarketAPI market) {
1582 if (market == null) return;
1583
1584 market.removeCondition(Conditions.RUINS_EXTENSIVE);
1585 market.removeCondition(Conditions.RUINS_SCATTERED);
1586 market.removeCondition(Conditions.RUINS_VAST);
1587 market.removeCondition(Conditions.RUINS_WIDESPREAD);
1588 market.removeCondition(Conditions.DECIVILIZED);
1589 }
1590
1591 public static void convertOrbitPointingDown(SectorEntityToken entity) {
1592 SectorEntityToken focus = entity.getOrbitFocus();
1593 if (focus != null) {
1594 float angle = entity.getCircularOrbitAngle();
1595 float period = entity.getCircularOrbitPeriod();
1596 float radius = entity.getCircularOrbitRadius();
1597 entity.setCircularOrbitPointingDown(focus, angle, radius, period);
1598 }
1599 }
1600
1601 public static void convertOrbitNoSpin(SectorEntityToken entity) {
1602 convertOrbitNoSpin(entity, 90f);
1603 }
1604 public static void convertOrbitNoSpin(SectorEntityToken entity, float facing) {
1605 SectorEntityToken focus = entity.getOrbitFocus();
1606 if (focus != null) {
1607 float angle = entity.getCircularOrbitAngle();
1608 float period = entity.getCircularOrbitPeriod();
1609 float radius = entity.getCircularOrbitRadius();
1610 entity.setCircularOrbit(focus, angle, radius, period);
1611 entity.setFacing(facing);
1612 }
1613 }
1614
1615 public static void convertOrbitWithSpin(SectorEntityToken entity, float spin) {
1616 SectorEntityToken focus = entity.getOrbitFocus();
1617 if (focus != null) {
1618 float angle = entity.getCircularOrbitAngle();
1619 float period = entity.getCircularOrbitPeriod();
1620 float radius = entity.getCircularOrbitRadius();
1621 entity.setCircularOrbitWithSpin(focus, angle, radius, period, spin, spin);
1622 ((CircularOrbitWithSpinAPI) entity.getOrbit()).setSpinVel(spin);
1623 }
1624 }
1625
1626
1627 public Random getRandom() {
1628 return random;
1629 }
1630 public void setRandom(Random random) {
1631 this.random = random;
1632 }
1633
1634
1641 protected List<Constellation> getSortedAvailableConstellations(ThemeGenContext context, boolean emptyOk, final Vector2f sortFrom, List<Constellation> exclude) {
1642 List<Constellation> constellations = new ArrayList<Constellation>();
1643 for (Constellation c : context.constellations) {
1644 if (context.majorThemes.containsKey(c)) continue;
1645 if (!emptyOk && constellationIsEmpty(c)) continue;
1646
1647 constellations.add(c);
1648 }
1649
1650 if (exclude != null) {
1651 constellations.removeAll(exclude);
1652 }
1653
1654 Collections.sort(constellations, new Comparator<Constellation>() {
1655 public int compare(Constellation o1, Constellation o2) {
1656 float d1 = Misc.getDistance(o1.getLocation(), sortFrom);
1657 float d2 = Misc.getDistance(o2.getLocation(), sortFrom);
1658 return (int) Math.signum(d2 - d1);
1659 }
1660 });
1661 return constellations;
1662 }
1663
1664 public static boolean constellationIsEmpty(Constellation c) {
1665 for (StarSystemAPI s : c.getSystems()) {
1666 if (!systemIsEmpty(s)) return false;
1667 }
1668 return true;
1669 }
1670 public static boolean systemIsEmpty(StarSystemAPI system) {
1671 for (PlanetAPI p : system.getPlanets()) {
1672 if (!p.isStar()) return false;
1673 }
1674 //system.getTerrainCopy().isEmpty()
1675 return true;
1676 }
1677
1678}
1679
1680
1681
1682
1683
1684
1685
1686
1687
static SettingsAPI getSettings()
Definition Global.java:51
static FactoryAPI getFactory()
Definition Global.java:35
static DerelictShipData createRandom(String factionId, DerelictType type, Random random)
static DerelictShipData createVariant(String variantId, Random random, float sModProb)
static DerelictShipData createHull(String hullId, Random random, float sModProb)
static EntityLocation pickHiddenLocationNotNearStar(Random random, StarSystemAPI system, float gap, Set< SectorEntityToken > exclude)
static AddedEntity addEntityAutoDetermineType(Random random, LocationAPI system, EntityLocation loc, String type, String faction)
List< Constellation > getSortedAvailableConstellations(ThemeGenContext context, boolean emptyOk, final Vector2f sortFrom, List< Constellation > exclude)
static SectorEntityToken addSalvageEntity(Random random, LocationAPI location, String id, String faction)
void addShipGraveyard(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker< String > factions)
static SectorEntityToken addSalvageEntity(LocationAPI location, String id, String faction, Object pluginParams)
static SectorEntityToken pickOuterEntityToSpawnNear(Random random, StarSystemAPI system)
AddedEntity addDerelictShip(StarSystemData data, EntityLocation loc, String variantId)
static AddedEntity setEntityLocation(SectorEntityToken entity, EntityLocation loc, String type)
void addDerelictShip(StarSystemData data, EntityLocation loc, WeightedRandomPicker< String > factions)
static AddedEntity addEntity(Random random, StarSystemAPI system, WeightedRandomPicker< EntityLocation > locs, String type, String faction)
static EntityLocation pickHiddenLocation(Random random, StarSystemAPI system, float gap, Set< SectorEntityToken > exclude)
static EntityLocation pickCommonLocation(Random random, StarSystemAPI system, float gap, boolean allowStarOrbit, Set< SectorEntityToken > exclude)
static WeightedRandomPicker< EntityLocation > getLocations(Random random, StarSystemAPI system, float minGap, LinkedHashMap< LocationType, Float > weights)
void addResearchStations(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker< String > stationTypes)
List< AddedEntity > addObjectives(StarSystemData data, float prob)
static EntityLocation pickAnyLocation(Random random, StarSystemAPI system, float gap, Set< SectorEntityToken > exclude)
static EntityLocation pickUncommonLocation(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)
static EntityLocation createLocationAtRandomGap(Random random, SectorEntityToken center, float minGap)
abstract void generateForSector(ThemeGenContext context, float allowedSectorFraction)
void addDerelictShips(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker< String > factions)
static SectorEntityToken addSalvageEntity(Random random, LocationAPI location, String id, String faction, Object pluginParams)
static SectorEntityToken addSalvageEntity(LocationAPI location, String id, String faction)
static AddedEntity addEntity(Random random, LocationAPI system, EntityLocation loc, String type, String faction)
static WeightedRandomPicker< EntityLocation > getLocations(Random random, StarSystemAPI system, Set< SectorEntityToken > exclude, float minGap, LinkedHashMap< LocationType, Float > weights)
static void convertOrbitWithSpin(SectorEntityToken entity, float spin)
AddedEntity addInactiveGate(StarSystemData data, float prob, float probDebris, float probShips, WeightedRandomPicker< String > factions)
static void convertOrbitNoSpin(SectorEntityToken entity, float facing)
WeightedRandomPicker< String > createStringPicker(Object ... params)
void addHabCenters(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker< String > stationTypes)
void addDebrisFields(StarSystemData data, float chanceToAddAny, int min, int max)
AddedEntity addDebrisField(StarSystemData data, SectorEntityToken focus, float radius)
void addDebrisFields(StarSystemData data, float chanceToAddAny, int min, int max, String defFaction, float defProb, int minStr, int maxStr)
static AddedEntity addNonSalvageEntity(LocationAPI system, EntityLocation loc, String type, String faction)
static WeightedRandomPicker< String > createStringPicker(Random random, Object ... params)
void addShipGraveyard(StarSystemData data, SectorEntityToken focus, WeightedRandomPicker< String > factions, WeightedRandomPicker< String > hulls)
AddedEntity addStation(EntityLocation loc, StarSystemData data, String customEntityId, String factionId)
void addShipGraveyard(StarSystemData data, SectorEntityToken focus, WeightedRandomPicker< String > factions)
void addMiningStations(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker< String > stationTypes)
OrbitAPI createCircularOrbitWithSpin(SectorEntityToken focus, float angle, float orbitRadius, float orbitDays, float spin)
< T > Collection< T > getAllSpecs(Class< T > c)
Object getSpec(Class c, String id, boolean nullOnNotFound)