Starsector API
Loading...
Searching...
No Matches
StarSystemGenerator.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.procgen;
2
3import java.awt.Color;
4import java.util.ArrayList;
5import java.util.Collection;
6import java.util.EnumSet;
7import java.util.LinkedHashMap;
8import java.util.LinkedHashSet;
9import java.util.List;
10import java.util.Map;
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.JumpPointAPI;
19import com.fs.starfarer.api.campaign.LocationAPI;
20import com.fs.starfarer.api.campaign.PlanetAPI;
21import com.fs.starfarer.api.campaign.PlanetSpecAPI;
22import com.fs.starfarer.api.campaign.SectorAPI;
23import com.fs.starfarer.api.campaign.SectorEntityToken;
24import com.fs.starfarer.api.campaign.StarSystemAPI;
25import com.fs.starfarer.api.characters.FullName.Gender;
26import com.fs.starfarer.api.impl.campaign.ids.Entities;
27import com.fs.starfarer.api.impl.campaign.ids.Factions;
28import com.fs.starfarer.api.impl.campaign.ids.Tags;
29import com.fs.starfarer.api.impl.campaign.ids.Terrain;
30import com.fs.starfarer.api.impl.campaign.procgen.Constellation.ConstellationType;
31import com.fs.starfarer.api.impl.campaign.procgen.ConstellationGen.SpringConnection;
32import com.fs.starfarer.api.impl.campaign.procgen.ConstellationGen.SpringSystem;
33import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator;
34import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator.AddedEntity;
35import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator.EntityLocation;
36import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator.LocationType;
37import com.fs.starfarer.api.impl.campaign.terrain.BaseTiledTerrain.TileParams;
38import com.fs.starfarer.api.impl.campaign.terrain.HyperspaceTerrainPlugin;
39import com.fs.starfarer.api.impl.campaign.terrain.NebulaTerrainPlugin;
40import com.fs.starfarer.api.impl.campaign.terrain.PulsarBeamTerrainPlugin;
41import com.fs.starfarer.api.impl.campaign.terrain.StarCoronaTerrainPlugin;
42import com.fs.starfarer.api.impl.campaign.terrain.StarCoronaTerrainPlugin.CoronaParams;
43import com.fs.starfarer.api.util.Misc;
44import com.fs.starfarer.api.util.WeightedRandomPicker;
45
46
47public class StarSystemGenerator {
48
49 public static class CustomConstellationParams implements Cloneable {
50 public String name = null;
51 public String secondaryName = null;
52 public StarAge age = null;
53 public int minStars = 0;
54 public int maxStars = 0;
55 public int numStars = 0;
56 public boolean forceNebula = false;
57 public List<StarSystemType> systemTypes = new ArrayList<StarSystemType>();
58 public List<String> starTypes = new ArrayList<String>();
59 public Vector2f location = null;
60
61 public CustomConstellationParams(StarAge age) {
62 this.age = age;
63 }
64
65 @Override
66 public CustomConstellationParams clone() {
67 try {
68 return (CustomConstellationParams) super.clone();
69 } catch (CloneNotSupportedException e) {
70 return null;
71 }
72 }
73
74
75 }
76
77
78 public static enum StarSystemType {
79 SINGLE,
80 BINARY_CLOSE,
81 BINARY_FAR,
82 TRINARY_2CLOSE,
83 TRINARY_1CLOSE_1FAR,
84 TRINARY_2FAR,
85 NEBULA,
86 DEEP_SPACE,
87
88 @Deprecated DEEP_SPACE_GAS_GIANT,
89 }
90
91 public static final float MIN_STAR_DIST = 2000f;
92 public static final float MAX_STAR_DIST = 2000f;
93
94 public static final float TILT_MIN = -45f;
95 public static final float TILT_MAX = 45f;
96 public static final float PITCH_MIN = -15f;
97 public static final float PITCH_MAX = 45f;
98
99 public static final float MAX_ORBIT_RADIUS = 20000;
100 public static final float FAR_MAX_ORBIT_RADIUS = 5000;
101
102 public static final float LAGRANGE_OFFSET = 60f;
103
104 public static final float BASE_INCR = 800f;
105 public static final float BASE_INCR_MOON = 200f;
106
107 public static final float STARTING_RADIUS_STAR_BASE = 750f;
108 public static final float STARTING_RADIUS_STAR_RANGE = 500f;
109
110 public static final float STARTING_RADIUS_MOON_BASE = 300f;
111 public static final float STARTING_RADIUS_MOON_RANGE = 100f;
112
113 //public static final float MOON_RADIUS_MULT = 0.75f;
114 public static final float MOON_RADIUS_MAX_FRACTION_OF_PARENT = 0.33f;
115 public static final float MOON_RADIUS_MIN_FRACTION_OF_NORMAL = 0.2f;
116 public static final float MOON_RADIUS_MAX_FRACTION_OF_NORMAL = 0.75f;
117 public static final float MIN_MOON_RADIUS = 60f;
118 //public static final float MAX_MOON_RADIUS = 100;
119
120
121 public static final String TAG_FIRST_ORBIT_ONLY = "first_orbit_only";
122 public static final String TAG_GIANT_MOON = "around_giant_at_any_offset";
123 public static final String TAG_LAGRANGE_ONLY = "lagrange_only";
124 public static final String TAG_NOT_IN_NEBULA = "not_in_nebula";
125 public static final String TAG_REQUIRES_NEBULA = "requires_nebula";
126
127 public static final String TAG_NOT_NEBULA_UNLESS_MOON = "not_NEBULA_unless_moon";
128
129 public static final String CAT_HAB5 = "cat_hab5";
130 public static final String CAT_HAB4 = "cat_hab4";
131 public static final String CAT_HAB3 = "cat_hab3";
132 public static final String CAT_HAB2 = "cat_hab2";
133 public static final String CAT_HAB1 = "cat_hab1";
134
135 public static final String CAT_NOTHING = "cat_nothing";
136 public static final String CAT_GIANT = "cat_giant";
137
138 public static final String COL_LAGRANGE = "lagrange";
139 public static final String COL_IN_ASTEROIDS = "in_asteroids";
140 public static final String COL_IS_MOON = "is_moon";
141 public static final String COL_BINARY = "binary";
142 public static final String COL_TRINARY = "trinary";
143
144 public static final String NEBULA_DEFAULT = "nebula";
145 public static final String NEBULA_AMBER = "nebula_amber";
146 public static final String NEBULA_BLUE = "nebula_blue";
147 public static final String NEBULA_NONE = "no_nebula";
148
149
150 public static Map<StarAge, String> nebulaTypes = new LinkedHashMap<StarAge, String>();
151 public static Map<String, WeightedRandomPicker<String>> backgroundsByNebulaType = new LinkedHashMap<String, WeightedRandomPicker<String>>();
152
153
154 public static List<TerrainGenPlugin> terrainPlugins = new ArrayList<TerrainGenPlugin>();
155 public static void addTerrainGenPlugin(TerrainGenPlugin plugin) {
156 terrainPlugins.add(0, plugin);
157 }
158 public static void removeTerrainGenPlugin(TerrainGenPlugin plugin) {
159 terrainPlugins.remove(plugin);
160 }
161 public static Random random = new Random();
162
163 static {
164 terrainPlugins.add(new RingGenPlugin());
167
170
172
176
178
180 }
181
182 public static void updateBackgroundPickers()
183 {
184 WeightedRandomPicker<String> picker;
185 picker = new WeightedRandomPicker<String>(random);
186 picker.add("graphics/backgrounds/background2.jpg", 10);
187 picker.add("graphics/backgrounds/background4.jpg", 10);
189
190 picker = new WeightedRandomPicker<String>(random);
191 picker.add("graphics/backgrounds/background5.jpg", 10);
193
194 picker = new WeightedRandomPicker<String>(random);
195 picker.add("graphics/backgrounds/background6.jpg", 10);
197
198 picker = new WeightedRandomPicker<String>(random);
199 picker.add("graphics/backgrounds/background1.jpg", 10);
200 picker.add("graphics/backgrounds/background2.jpg", 10);
202 }
203
204 public static boolean DEBUG = Global.getSettings().isDevMode();
205
206 public static TerrainGenPlugin pickTerrainGenPlugin(TerrainGenDataSpec terrainData, GenContext context) {
207 for (TerrainGenPlugin plugin : terrainPlugins) {
208 if (plugin.wantsToHandle(terrainData, context)) return plugin;
209 }
210 return null;
211 }
212
213
214 public static class GeneratedPlanet {
215 public SectorEntityToken parent;
216 public PlanetAPI planet;
217 public float orbitDays;
218 public float orbitRadius;
219 public float orbitAngle;
220 public boolean isMoon;
221 public GeneratedPlanet(SectorEntityToken parent, PlanetAPI planet, boolean isMoon, float orbitDays, float orbitRadius, float orbitAngle) {
222 this.parent = parent;
223 this.planet = planet;
224 this.isMoon = isMoon;
225 this.orbitDays = orbitDays;
226 this.orbitRadius = orbitRadius;
227 this.orbitAngle = orbitAngle;
228 }
229 }
230
231 public static enum LagrangePointType {
232// L1,
233// L2,
234// L3,
235 L4,
236 L5,
237 }
238
239
240 public static class LagrangePoint {
241 public GeneratedPlanet parent;
242 public LagrangePointType type;
243 public LagrangePoint(GeneratedPlanet parent, LagrangePointType type) {
244 this.parent = parent;
245 this.type = type;
246 }
247 }
248
249
250 public static class GenResult {
251 public float orbitalWidth;
252 public boolean onlyIncrementByWidth = false;
253 public List<SectorEntityToken> entities = new ArrayList<SectorEntityToken>();
254 public GenContext context;
255
256 public GenResult() {
257
258 }
259 }
260
261 public static class GenContext {
262 public StarSystemGenerator gen;
263 public List<GeneratedPlanet> generatedPlanets = new ArrayList<GeneratedPlanet>();
264
265 public Set<String> excludeCategories = new LinkedHashSet<String>();
266
267 //public NamePick parentNamePick = null;
268 public StarSystemAPI system;
269 public SectorEntityToken center;
270 public StarGenDataSpec starData;
271 public PlanetAPI parent;
272 public int orbitIndex = -1;
273
274 public int startingOrbitIndex = 0;
275 public String age;
276
277 public float currentRadius;
278 public String parentCategory;
279 public int parentOrbitIndex;
280 public float parentRadiusOverride = -1;
281
282 public GeneratedPlanet lagrangeParent = null;
283 public LagrangePointType lagrangePointType = null;
284
285 public List<String> multipliers = new ArrayList<String>();
286 public float maxOrbitRadius;
287
288 public Map<Object, Object> customData = new LinkedHashMap<Object, Object>();
289
290 public GenContext(StarSystemGenerator gen, StarSystemAPI system, SectorEntityToken center,
291 StarGenDataSpec starData, PlanetAPI parent,
292 //NamePick parentNamePick,
293 int orbitIndex,
294 String age, float currentRadius, float maxOrbitRadius, String parentCategory, int parentOrbitIndex) {
295 super();
296 //this.parentNamePick = parentNamePick;
297 this.maxOrbitRadius = maxOrbitRadius;
298 this.gen = gen;
299 this.system = system;
300 this.center = center;
301 this.starData = starData;
302 this.parent = parent;
303 this.startingOrbitIndex = orbitIndex;
304 this.orbitIndex = 0;
305 this.age = age;
306 this.currentRadius = currentRadius;
307 this.parentCategory = parentCategory;
308 this.parentOrbitIndex = parentOrbitIndex;
309 }
310
311 }
312
313 //private static long index = 0;
314
316
317 protected StarSystemType systemType = StarSystemType.SINGLE;
318 protected StarAge starAge;
319 protected SectorAPI sector;
320 protected StarSystemAPI system;
321 protected LocationAPI hyper;
322
323 protected PlanetAPI star;
324 protected PlanetAPI secondary;
325 protected PlanetAPI tertiary;
326
327 protected SectorEntityToken systemCenter;
328 protected float centerRadius = 0f;
332 protected String nebulaType;
333 protected String backgroundName;
334// protected NamePick constellationName;
335// protected NamePick primaryName;
336// protected NamePick secondaryName;
337// protected NamePick tertiaryName;
338
339 protected Map<SectorEntityToken, PlanetAPI> lagrangeParentMap = new LinkedHashMap<SectorEntityToken, PlanetAPI>();
340 protected Map<SectorEntityToken, List<SectorEntityToken>> allNameableEntitiesAdded = new LinkedHashMap<SectorEntityToken, List<SectorEntityToken>>();
341 protected CustomConstellationParams params;
342
343
344 public StarSystemGenerator(CustomConstellationParams params) {
345 this.params = params;
346 this.constellationAge = params.age;
347
348 if (this.constellationAge == StarAge.ANY) {
349 WeightedRandomPicker<StarAge> picker = new WeightedRandomPicker<StarAge>(random);
350 picker.add(StarAge.AVERAGE);
351 picker.add(StarAge.OLD);
352 picker.add(StarAge.YOUNG);
353 this.constellationAge = picker.pick();
354 }
355
357 }
358
359
360
361
362
364 boolean hasNebula = constellationAgeData.getProbNebula() > random.nextFloat();
365 if (params != null && params.forceNebula) hasNebula = true;
366
367// hasNebula = true;
368// hasNebula = false;
369
371 if (hasNebula) {
373 }
374
375 WeightedRandomPicker<String> bgPicker = backgroundsByNebulaType.get(nebulaType);
376 backgroundName = bgPicker.pick();
377 }
378
379
380
381
383
384// if (true) {
385// params = new CustomConstellationParams(StarAge.OLD);
386// params.numStars = 1;
387// params.starTypes.add(StarTypes.YELLOW);
388// params.systemTypes.add(StarSystemType.SINGLE);
389//
390// this.constellationAge = params.age;
391// constellationAgeData = (AgeGenDataSpec) Global.getSettings().getSpec(AgeGenDataSpec.class, constellationAge.name(), true);
392// }
393
394 //random = new Random(12312312312L);
395
396 //DEBUG = false;
397
398 lagrangeParentMap = new LinkedHashMap<SectorEntityToken, PlanetAPI>();
399 allNameableEntitiesAdded = new LinkedHashMap<SectorEntityToken, List<SectorEntityToken>>();
400
401 SectorAPI sector = Global.getSector();
402 Vector2f loc = new Vector2f();
403 if (params != null && params.location != null) {
404 loc = new Vector2f(params.location);
405 } else {
406 loc = new Vector2f(sector.getPlayerFleet().getLocation());
407 loc.x = (int) loc.x;
408 loc.y = (int) loc.y;
409 }
410
411
413
414 List<StarSystemAPI> systems = new ArrayList<StarSystemAPI>();
415 int stars = (int) Math.round(getNormalRandom(1, 7));
416 if (params != null && params.numStars > 0) {
417 stars = params.numStars;
418 } else if (params != null && params.minStars > 0 && params.maxStars > 0) {
419 stars = (int) Math.round(getNormalRandom(params.minStars, params.maxStars));
420 }
421
422// constellationName = ProcgenUsedNames.pickName(NameGenData.TAG_CONSTELLATION, null);
423// ProcgenUsedNames.notifyUsed(constellationName.nameWithRomanSuffixIfAny);
424// Global.getSettings().greekLetterReset();
425
426 for (int i = 0; i < stars; i++) {
427 generateSystem(new Vector2f(0, 0));
428 if (system != null) {
429 systems.add(system);
430 }
431 }
432
433
434 SpringSystem springs = ConstellationGen.doConstellationLayout(systems, random, loc);
435 Global.getSector().getHyperspace().updateAllOrbits();
436
437 HyperspaceTerrainPlugin plugin = (HyperspaceTerrainPlugin) Misc.getHyperspaceTerrain().getPlugin();
438 NebulaEditor editor = new NebulaEditor(plugin);
439
440 float minRadius = plugin.getTileSize() * 2f;
441 for (StarSystemAPI curr : systems) {
442 float radius = curr.getMaxRadiusInHyperspace();
443 editor.clearArc(curr.getLocation().x, curr.getLocation().y, 0, radius + minRadius * 0.5f, 0, 360f);
444 editor.clearArc(curr.getLocation().x, curr.getLocation().y, 0, radius + minRadius, 0, 360f, 0.25f);
445 }
446
447 for (SpringConnection conn : springs.connections) {
448 if (!conn.pull) continue;
449 float r1 = ((StarSystemAPI)conn.from.custom).getMaxRadiusInHyperspace();
450 float r2 = ((StarSystemAPI)conn.to.custom).getMaxRadiusInHyperspace();
451 float dist = Misc.getDistance(conn.from.loc, conn.to.loc);
452
453 float radius = Math.max(0, dist * 0.67f - r1 - r2);
454
455// float x = (conn.from.loc.x + conn.to.loc.x) * 0.5f;
456// float y = (conn.from.loc.y + conn.to.loc.y) * 0.5f;
457// editor.clearArc(x, y, 0, radius + minRadius * 0.5f, 0, 360f);
458// editor.clearArc(x, y, 0, radius + minRadius, 0, 360f, 0.25f);
459
460 Vector2f diff = Vector2f.sub(conn.to.loc, conn.from.loc, new Vector2f());
461 float x = conn.from.loc.x + diff.x * 0.33f;
462 float y = conn.from.loc.y + diff.y * 0.33f;
463 editor.clearArc(x, y, 0, radius + minRadius * 1f, 0, 360f);
464 editor.clearArc(x, y, 0, radius + minRadius * 2f, 0, 360f, 0.25f);
465
466 x = conn.from.loc.x + diff.x * 0.67f;
467 y = conn.from.loc.y + diff.y * 0.67f;
468 editor.clearArc(x, y, 0, radius + minRadius * 1f, 0, 360f);
469 editor.clearArc(x, y, 0, radius + minRadius * 2f, 0, 360f, 0.25f);
470 }
471
472 ConstellationType type = ConstellationType.NORMAL;
473 if (!NEBULA_NONE.equals(nebulaType)) {
474 type = ConstellationType.NEBULA;
475 }
476
478 //c.setType(ConstellationType.NORMAL); // for now; too many end up being called "Nebula" otherwise
479 c.getSystems().addAll(systems);
482
483
484// SalvageEntityGeneratorOld seg = new SalvageEntityGeneratorOld(c);
485// seg.addSalvageableEntities();
486
487
488 NameAssigner namer = new NameAssigner(c);
489 namer.setSpecialNamesProbability(0.37f);
490 namer.assignNames(params.name, params.secondaryName);
491
492 for (SectorEntityToken entity : allNameableEntitiesAdded.keySet()) {
493 if (entity instanceof PlanetAPI && entity.getMarket() != null) {
494 entity.getMarket().setName(entity.getName());
495 }
496 }
497
498 //if (systems.size() > 1) {
499 for (StarSystemAPI system : systems) {
500 system.setConstellation(c);
501 }
502 //}
503
504 return c;
505 }
506
507
508 public void generateSystem(Vector2f loc) {
509 //index++;
510
512
513// if (systemType == StarSystemType.NEBULA) {
514// System.out.println("wfwefwe1231232");
515// }
516
517 String uuid = Misc.genUID();
518
519// String id = "system_" + index;
520// String name = "System " + index;
521
522 String id = "system_" + uuid;
523 String name = "System " + uuid;
524
525// String base = constellationName.nameWithRomanSuffixIfAny;
526// if (constellationName.secondaryWithRomanSuffixIfAny != null) {
527// base = constellationName.secondaryWithRomanSuffixIfAny;
528// }
529// String name = Global.getSettings().getNextGreekLetter(constellationName) + " " + base;
530// String id = name.toLowerCase();
531
532
533 //if (systemType == StarSystemType.NEBULA) name += " Nebula";
534
535 if (!initSystem(name, loc)) {
536 cleanup();
537 return;
538 }
539
540 star = null;
541 secondary = null;
542 tertiary = null;
543 systemCenter = null;
544
545
546
547 if (!addStars(id)) {
548 cleanup();
549 return;
550 }
551
552// if (systemType == StarSystemType.NEBULA) {
553// if (star.getSpec().isBlackHole()) {
554// System.out.println("wefwefew");
555// }
556// }
557
559
560 float binaryPad = 1500f;
561
562 float maxOrbitRadius = MAX_ORBIT_RADIUS;
563 if (systemType == StarSystemType.BINARY_FAR ||
564 systemType == StarSystemType.TRINARY_1CLOSE_1FAR ||
565 systemType == StarSystemType.TRINARY_2FAR) {
566 maxOrbitRadius -= FAR_MAX_ORBIT_RADIUS + binaryPad;
567 }
568 GenResult result = addPlanetsAndTerrain(MAX_ORBIT_RADIUS);
569 //addJumpPoints(result);
570 float primaryOrbitalRadius = star.getRadius();
571 if (result != null) {
572 primaryOrbitalRadius = result.orbitalWidth * 0.5f;
573 }
574
575 // add far stars, if needed
576 float orbitAngle = random.nextFloat() * 360f;
577 float baseOrbitRadius = primaryOrbitalRadius + binaryPad;
578 float orbitDays = baseOrbitRadius / (3f + random.nextFloat() * 2f);
579 if (systemType == StarSystemType.BINARY_FAR && secondary != null) {
580 addFarStar(secondary, orbitAngle, baseOrbitRadius, orbitDays);
581 } else if (systemType == StarSystemType.TRINARY_1CLOSE_1FAR && tertiary != null) {
582 addFarStar(tertiary, orbitAngle, baseOrbitRadius, orbitDays);
583 } else if (systemType == StarSystemType.TRINARY_2FAR) {
584 addFarStar(secondary, orbitAngle, baseOrbitRadius, orbitDays);
585 addFarStar(tertiary, orbitAngle + 60f + 180f * random.nextFloat(), baseOrbitRadius, orbitDays);
586 }
587
588
589 if (systemType == StarSystemType.NEBULA) {
590 star.setSkipForJumpPointAutoGen(true);
591 }
592
593 addJumpPoints(result, false);
594
595 if (systemType == StarSystemType.NEBULA) {
596 system.removeEntity(star);
597 StarCoronaTerrainPlugin coronaPlugin = Misc.getCoronaFor(star);
598 if (coronaPlugin != null) {
599 system.removeEntity(coronaPlugin.getEntity());
600 }
601 system.setStar(null);
602 system.initNonStarCenter();
603 for (SectorEntityToken entity : system.getAllEntities()) {
604 if (entity.getOrbitFocus() == star ||
605 entity.getOrbitFocus() == system.getCenter()) {
606 entity.setOrbit(null);
607 }
608 }
609 system.getCenter().addTag(Tags.AMBIENT_LS);
610 }
611
612 system.autogenerateHyperspaceJumpPoints(true, false);
613
614 if (systemType == StarSystemType.NEBULA) {
615 //system.addEntity(star);
616 system.setStar(star);
617 //system.removeEntity(system.getCenter());
618 //system.setCenter(null);
619 }
620
622
624 }
625
626
627 protected void addFarStar(PlanetAPI farStar, float orbitAngle, float baseOrbitRadius, float orbitPeriod) {
628 float min = 0;
629 float max = 2;
630 int numOrbits = (int) Math.round(getNormalRandom(min, max));
631 GenResult resultFar = null;
632 if (numOrbits > 0) {
633 float currentRadius = farStar.getRadius() + STARTING_RADIUS_STAR_BASE + STARTING_RADIUS_STAR_RANGE * random.nextFloat();
634
635 StarGenDataSpec farData = (StarGenDataSpec) Global.getSettings().getSpec(StarGenDataSpec.class, farStar.getSpec().getPlanetType(), false);
636 StarAge farAge = farData.getAge();
637 if (farAge == StarAge.ANY) {
638 farAge = constellationAge;
639 }
640
641 //GenContext context = new GenContext(this, system, star, starData,
642 GenContext context = new GenContext(this, system, farStar, farData,
643 null, 0, farAge.name(), currentRadius, FAR_MAX_ORBIT_RADIUS, null, -1);
644
645
646 resultFar = addOrbitingEntities(context, numOrbits, false, true, false, true);
647 resultFar.context = context;
648 }
649
650 if (resultFar != null) {
651 baseOrbitRadius += resultFar.orbitalWidth * 0.5f;
652 }
653
654 SectorEntityToken center = star;
655 if (systemType == StarSystemType.TRINARY_1CLOSE_1FAR) {
656 center = systemCenter;
657 }
658 farStar.setCircularOrbit(center, orbitAngle, baseOrbitRadius, orbitPeriod);
659
660 if (resultFar != null) {
661 addJumpPoints(resultFar, true);
662 }
663 }
664
665
666
667 protected StarSystemType pickSystemType(StarAge constellationAge) {
668// if (true) {
669// return StarSystemType.BINARY_CLOSE;
670// }
671
672 if (params != null && !params.systemTypes.isEmpty()) {
673 return params.systemTypes.remove(0);
674 }
675
676
677 WeightedRandomPicker<StarSystemType> picker = new WeightedRandomPicker<StarSystemType>(random);
678 for (StarSystemType type : EnumSet.allOf(StarSystemType.class)) {
679 if (type == StarSystemType.DEEP_SPACE || type == StarSystemType.DEEP_SPACE_GAS_GIANT) continue;
680
681 Object test = Global.getSettings().getSpec(LocationGenDataSpec.class, type.name(), true);
682 if (test == null) continue;
684
685 boolean nebulaStatusOk = NEBULA_NONE.equals(nebulaType) || !data.hasTag(TAG_NOT_IN_NEBULA);
686 nebulaStatusOk &= !NEBULA_NONE.equals(nebulaType) || !data.hasTag(TAG_REQUIRES_NEBULA);
687
688 if (!nebulaStatusOk) continue;
689
690 float freq = 0f;
691 switch (constellationAge) {
692 case AVERAGE:
693 freq = data.getFreqAVERAGE();
694 break;
695 case OLD:
696 freq = data.getFreqOLD();
697 break;
698 case YOUNG:
699 freq = data.getFreqYOUNG();
700 break;
701 }
702 picker.add(type, freq);
703 }
704
705 return picker.pick();
706
707 //return StarSystemType.TRINARY_1CLOSE_1FAR;
708 //return StarSystemType.TRINARY_2FAR;
709 //return StarSystemType.TRINARY_2CLOSE;
710 //return StarSystemType.BINARY_CLOSE;
711 //return StarSystemType.BINARY_FAR;
712 //return StarSystemType.NORMAL;
713 }
714
715
716 protected boolean addStars(String id) {
717 if (systemType == StarSystemType.BINARY_CLOSE ||
718 systemType == StarSystemType.TRINARY_1CLOSE_1FAR ||
719 systemType == StarSystemType.TRINARY_2CLOSE) {
720 system.initNonStarCenter();
721 systemCenter = system.getCenter();
722 }
723
724// if (systemType == StarSystemType.NEBULA) {
725// if (system.getId().equals("system 7f6")) {
726// System.out.println("wefwefew");
727// }
728// }
729
730 PlanetSpecAPI starSpec = pickStar(constellationAge);
731 if (starSpec == null) return false;
732
733 starData = (StarGenDataSpec) Global.getSettings().getSpec(StarGenDataSpec.class, starSpec.getPlanetType(), false);
735
736 float corona = radius * (starData.getCoronaMult() + starData.getCoronaVar() * (random.nextFloat() - 0.5f));
737 if (corona < starData.getCoronaMin()) corona = starData.getCoronaMin();
738
739 //corona += 2000f;
740
741 star = system.initStar(id, // unique id for this star
742 starSpec.getPlanetType(), // id in planets.json
743 radius, // radius (in pixels at default zoom)
744 corona, // corona radius, from star edge
746 (float) (starData.getMinFlare() + (starData.getMaxFlare() - starData.getMinFlare()) * random.nextFloat()),
748 );
749
750 if (systemType == StarSystemType.NEBULA) {
751 star.addTag(Tags.AMBIENT_LS);
752 }
753
754 if (systemCenter == null) {
756 centerRadius = star.getRadius();
757 }
758
759
760 // create and switch aronud stars so that the primary is always the largest
761 if (systemType == StarSystemType.BINARY_CLOSE) {
762 secondary = addRandomStar(id + "_b", system.getBaseName() + " B");
763 if (secondary == null) return false;
765 } else if (systemType == StarSystemType.BINARY_FAR) {
766 secondary = addRandomStar(id + "_b", system.getBaseName() + " B");
767 if (secondary == null) return false;
769
770 centerRadius = star.getRadius();
771
772 secondary.setLightColorOverrideIfStar(pickLightColorForStar(secondary));
773 } else if (systemType == StarSystemType.TRINARY_2CLOSE ||
774 systemType == StarSystemType.TRINARY_1CLOSE_1FAR ||
775 systemType == StarSystemType.TRINARY_2FAR) {
776 secondary = addRandomStar(id + "_b", system.getBaseName() + " B");
777 if (secondary == null) return false;
779
780 tertiary = addRandomStar(id + "_c", system.getBaseName() + " C");
781 if (tertiary == null) return false;
783
784 if (systemType == StarSystemType.TRINARY_1CLOSE_1FAR) {
785 tertiary.setLightColorOverrideIfStar(pickLightColorForStar(tertiary));
786 } else if (systemType == StarSystemType.TRINARY_2FAR) {
787 secondary.setLightColorOverrideIfStar(pickLightColorForStar(secondary));
788 tertiary.setLightColorOverrideIfStar(pickLightColorForStar(tertiary));
789 }
790 }
791
792 // make close stars orbit common center
793 if (systemType == StarSystemType.BINARY_CLOSE || systemType == StarSystemType.TRINARY_1CLOSE_1FAR) {
795
796 float r1 = star.getRadius();
797 float r2 = secondary.getRadius();
798 if (star.getSpec().getPlanetType().equals("black_hole")) r1 *= 5f;
799 if (secondary.getSpec().getPlanetType().equals("black_hole")) r2 *= 5f;
800
801 float totalRadius = r1 + r2;
802 dist += totalRadius;
803
804 float orbitPrimary = dist * r2 / totalRadius;
805 float orbitSecondary = dist * r1 / totalRadius;
806
807 centerRadius = Math.max(orbitPrimary + star.getRadius(), orbitSecondary + secondary.getRadius());
808
809 float anglePrimary = random.nextFloat() * 360f;
810 float orbitDays = dist / (30f + random.nextFloat() * 50f);
811
812 star.setCircularOrbit(system.getCenter(), anglePrimary, orbitPrimary, orbitDays);
813 secondary.setCircularOrbit(system.getCenter(), anglePrimary + 180f, orbitSecondary, orbitDays);
814
815// if (systemType == StarSystemType.TRINARY_1CLOSE_1FAR && tertiary != null) {
816// tertiary.setCircularOrbit(system.getCenter(),
817// tertiary.getCircularOrbitAngle(),
818// tertiary.getCircularOrbitRadius(),
819// tertiary.getCircularOrbitPeriod());
820// }
821 } else if (systemType == StarSystemType.TRINARY_2CLOSE) {
823 dist += star.getRadius();
824
825 float anglePrimary = random.nextFloat() * 360f;
826 float orbitDays = dist / (20f + random.nextFloat() * 80f);
827
828 // smaller dist for primary/secondary so that their gravity wells get generated first
829 // and are closer to the center
830 star.setCircularOrbit(system.getCenter(), anglePrimary, dist - 10, orbitDays);
831 secondary.setCircularOrbit(system.getCenter(), anglePrimary + 120f, dist - 5, orbitDays);
832 tertiary.setCircularOrbit(system.getCenter(), anglePrimary + 240f, dist, orbitDays);
833
834 centerRadius = dist + star.getRadius();
835 } else {
836 star.getLocation().set(0, 0);
837 }
838
839
840 if (star != null) {
841 starData = (StarGenDataSpec) Global.getSettings().getSpec(StarGenDataSpec.class, star.getSpec().getPlanetType(), false);
842 }
843// if (systemCenter instanceof PlanetAPI) {
844// centerRadius = star.getRadius();
845// }
846
847
849
850
851 if (star != null) {
852 ArrayList<SectorEntityToken> list = new ArrayList<SectorEntityToken>();
853 list.add(star);
855 system.setStar(star);
856 }
857 if (secondary != null) {
858 ArrayList<SectorEntityToken> list = new ArrayList<SectorEntityToken>();
859 list.add(secondary);
861 system.setSecondary(secondary);
862 }
863 if (tertiary != null){
864 ArrayList<SectorEntityToken> list = new ArrayList<SectorEntityToken>();
865 list.add(tertiary);
867 system.setTertiary(tertiary);
868 }
869
873
877
878 return true;
879 }
880
881 protected void setBlackHoleIfBlackHole(PlanetAPI star) {
882 if (star == null) return;
883
884 if (star.getSpec().getPlanetType().equals("black_hole")) {
885 StarCoronaTerrainPlugin coronaPlugin = Misc.getCoronaFor(star);
886 if (coronaPlugin != null) {
887 system.removeEntity(coronaPlugin.getEntity());
888 }
889
890 StarGenDataSpec starData = (StarGenDataSpec) Global.getSettings().getSpec(StarGenDataSpec.class, star.getSpec().getPlanetType(), false);
891 float corona = star.getRadius() * (starData.getCoronaMult() + starData.getCoronaVar() * (random.nextFloat() - 0.5f));
892 if (corona < starData.getCoronaMin()) corona = starData.getCoronaMin();
893
894 SectorEntityToken eventHorizon = system.addTerrain(Terrain.EVENT_HORIZON,
895 new CoronaParams(star.getRadius() + corona, (star.getRadius() + corona) / 2f,
897 (float) (starData.getMinFlare() + (starData.getMaxFlare() - starData.getMinFlare()) * random.nextFloat()),
899 eventHorizon.setCircularOrbit(star, 0, 0, 100);
900 }
901 }
902
903 protected void setPulsarIfNeutron(PlanetAPI star) {
904 if (star == null) return;
905
906 if (star.getSpec().getPlanetType().equals("star_neutron")) {
907 StarCoronaTerrainPlugin coronaPlugin = Misc.getCoronaFor(star);
908 if (coronaPlugin != null) {
909 system.removeEntity(coronaPlugin.getEntity());
910 }
911
912 system.addCorona(star,
913 300, // radius
914 3, // wind
915 0, // flares
916 3); // cr loss
917
918
919 StarGenDataSpec starData = (StarGenDataSpec) Global.getSettings().getSpec(StarGenDataSpec.class, star.getSpec().getPlanetType(), false);
920 float corona = star.getRadius() * (starData.getCoronaMult() + starData.getCoronaVar() * (random.nextFloat() - 0.5f));
921 if (corona < starData.getCoronaMin()) corona = starData.getCoronaMin();
922
923 SectorEntityToken eventHorizon = system.addTerrain(Terrain.PULSAR_BEAM,
924 new CoronaParams(star.getRadius() + corona, (star.getRadius() + corona) / 2f,
926 (float) (starData.getMinFlare() + (starData.getMaxFlare() - starData.getMinFlare()) * random.nextFloat()),
928 eventHorizon.setCircularOrbit(star, 0, 0, 100);
929 }
930 }
931
932 protected void switchPrimaryAndSecondaryIfNeeded(boolean sizeDownSmaller) {
933 if (star == null || secondary == null) return;
934
935 if (star.getRadius() < secondary.getRadius()) {
936 star = secondary;
937 secondary = system.getStar();
938 system.setStar(star);
939
940 String temp = star.getName();
941 star.setName(secondary.getName());
942 secondary.setName(temp);
943
944 temp = star.getId();
945 star.setId(secondary.getId());
946 secondary.setId(temp);
947
948 if (sizeDownSmaller) {
949 secondary.setRadius(Math.min(secondary.getRadius(), star.getRadius() * 0.67f));
950 }
951
952 if (secondary == systemCenter) {
954 centerRadius = systemCenter.getRadius();
955 }
956 }
957 }
958
959 protected void switchPrimaryAndTertiaryIfNeeded(boolean sizeDownSmaller) {
960 if (star == null || tertiary == null) return;
961
962 if (star.getRadius() < tertiary.getRadius()) {
963 star = tertiary;
964 tertiary = system.getStar();
965 system.setStar(star);
966
967 String temp = star.getName();
968 star.setName(tertiary.getName());
969 tertiary.setName(temp);
970
971 temp = star.getId();
972 star.setId(tertiary.getId());
973 tertiary.setId(temp);
974
975 if (sizeDownSmaller) {
976 tertiary.setRadius(Math.min(tertiary.getRadius(), star.getRadius() * 0.67f));
977 }
978
979 if (tertiary == systemCenter) {
981 centerRadius = systemCenter.getRadius();
982 }
983 }
984 }
985
986
987
988 protected void addStableLocations() {
989 int min = 1;
990 int max = 3;
991
992// int planets = system.getPlanets().size(); // includes stars
993// max = Math.min(max, planets/2);
994// if (min > max) min = max;
995
996 //int num = (int) Math.round(getNormalRandom(min, max));
997 int num = random.nextInt(max + 1 - min) + min;
998
999 if (num == min && random.nextFloat() < 0.25f) {
1000 num = 0;
1001 }
1002
1004 }
1005 public static void addStableLocations(StarSystemAPI system, int num) {
1006 for (int i = 0; i < num; i++) {
1007 LinkedHashMap<LocationType, Float> weights = new LinkedHashMap<LocationType, Float>();
1008 weights.put(LocationType.STAR_ORBIT, 10f);
1009 weights.put(LocationType.OUTER_SYSTEM, 10f);
1010 weights.put(LocationType.L_POINT, 10f);
1011 weights.put(LocationType.IN_SMALL_NEBULA, 2f);
1012 WeightedRandomPicker<EntityLocation> locs = BaseThemeGenerator.getLocations(random, system, null, 100f, weights);
1013 EntityLocation loc = locs.pick();
1014
1015 AddedEntity added = BaseThemeGenerator.addNonSalvageEntity(system, loc, Entities.STABLE_LOCATION, Factions.NEUTRAL);
1016 //if (DEBUG && added != null) System.out.println(" Added stable location");
1017
1018 if (added != null) {
1019 BaseThemeGenerator.convertOrbitPointingDown(added.entity);
1020 }
1021 }
1022 }
1023
1024
1025 protected void addJumpPoints(GenResult result, boolean farStarMode) {
1026
1027 //float outerRadius = star.getRadius() + STARTING_RADIUS_STAR_BASE + STARTING_RADIUS_STAR_RANGE * random.nextFloat();
1028 float outerRadius = centerRadius + STARTING_RADIUS_STAR_BASE + STARTING_RADIUS_STAR_RANGE * random.nextFloat();
1029 if (result != null) {
1030 outerRadius = result.orbitalWidth / 2f + 500f;
1031 }
1032
1033 if (farStarMode) {
1034 //if (result.context.orbitIndex < 0) {
1035 if (result.context.orbitIndex < 0 && random.nextFloat() < 0.5f) {
1036 return;
1037 }
1038 SectorEntityToken farStar = result.context.center;
1039 String name = "Omega Jump-point";
1040 if (result.context.center == tertiary) {
1041 name = "Omicron Jump-point";
1042 }
1043 JumpPointAPI point = Global.getFactory().createJumpPoint(null, name);
1044 point.setStandardWormholeToHyperspaceVisual();
1045 float orbitDays = outerRadius / (15f + random.nextFloat() * 5f);
1046 //point.setCircularOrbit(star, random.nextFloat() * 360f, outerRadius, orbitDays);
1047 point.setCircularOrbit(farStar, random.nextFloat() * 360f, outerRadius, orbitDays);
1048 system.addEntity(point);
1049
1050 return;
1051 }
1052
1053
1054 //JumpPointAPI point = Global.getFactory().createJumpPoint(null, system.getBaseName() + " Fringe");
1055 JumpPointAPI point = Global.getFactory().createJumpPoint(null, "Fringe Jump-point");
1056 point.setStandardWormholeToHyperspaceVisual();
1057 float orbitDays = outerRadius / (15f + random.nextFloat() * 5f);
1058 //point.setCircularOrbit(star, random.nextFloat() * 360f, outerRadius, orbitDays);
1059 point.setCircularOrbit(systemCenter, random.nextFloat() * 360f, outerRadius, orbitDays);
1060 system.addEntity(point);
1061
1062
1063 // to make sure that "is this location clear" calculations below always work
1064 system.updateAllOrbits();
1065
1066
1067 if (result != null) {
1068 float halfway = outerRadius * 0.5f;
1069
1070 WeightedRandomPicker<LagrangePoint> inner = new WeightedRandomPicker<LagrangePoint>(random);
1071 WeightedRandomPicker<LagrangePoint> outer = new WeightedRandomPicker<LagrangePoint>(random);
1072
1073 int total = 0;
1074 for (GeneratedPlanet planet : result.context.generatedPlanets) {
1075 if (planet.isMoon) continue;
1076 if (planet.planet.getOrbit() == null || planet.planet.getOrbit().getFocus() == null) continue;
1077 total++;
1078
1079 for (LagrangePointType type : EnumSet.of(LagrangePointType.L4, LagrangePointType.L5)) {
1080 float orbitRadius = planet.orbitRadius;
1081 float angleOffset = -LAGRANGE_OFFSET * 0.5f;
1082 if (type == LagrangePointType.L5) angleOffset = LAGRANGE_OFFSET * 0.5f;
1083 float angle = planet.orbitAngle + angleOffset;
1084 Vector2f location = Misc.getUnitVectorAtDegreeAngle(angle + angleOffset);
1085 location.scale(orbitRadius);
1086 Vector2f.add(location, planet.planet.getOrbit().getFocus().getLocation(), location);
1087
1088 boolean clear = true;
1089 for (PlanetAPI curr : system.getPlanets()) {
1090 float dist = Misc.getDistance(curr.getLocation(), location);
1091 //System.out.println(type.name() + ": " + location + ", " + "Dist: " + dist + " (to " + curr.getName() + " at " + curr.getLocation() + ")");
1092 if (dist < 500) {
1093 clear = false;
1094 break;
1095 }
1096 }
1097 if (clear) {
1098 if (planet.orbitRadius < halfway || planet.orbitRadius < 5000f) {
1099 inner.add(new LagrangePoint(planet, type), 10f);
1100 } else {
1101 outer.add(new LagrangePoint(planet, type), 10f);
1102 }
1103 }
1104 }
1105 }
1106
1107
1108 if (outerRadius > 2000f + 5000f * random.nextFloat()) {
1109 boolean addedOne = false;
1110 if (!inner.isEmpty()) {
1111 LagrangePoint p = inner.pick();
1112 //addJumpPoint(p, p.parent.planet.getName() + " Jump-point");
1113 String name = "Inner System Jump-point";
1114 if (systemType == StarSystemType.NEBULA) name = "Inner Jump-point";
1115 addJumpPoint(p, name);
1116 addedOne = true;
1117 }
1118
1119
1120 if (!outer.isEmpty() && (random.nextFloat() < outer.getItems().size() * 0.2f || !addedOne)) {
1121 LagrangePoint p = outer.pick();
1122 String name = "Outer System Jump-point";
1123 if (systemType == StarSystemType.NEBULA) name = "Outer Jump-point";
1124 addJumpPoint(p, name);
1125 //addJumpPoint(p, "Outer System Jump-point");
1126 addedOne = true;
1127 }
1128
1129// while (!inner.isEmpty()) {
1130// LagrangePoint p = inner.pickAndRemove();
1131// //addJumpPoint(p, p.parent.planet.getName() + " Jump-point");
1132// addJumpPoint(p, system.getBaseName() + " Inner System Jump-point");
1133// }
1134// while (!outer.isEmpty()) {
1135// LagrangePoint p = outer.pickAndRemove();
1136// //addJumpPoint(p, p.parent.planet.getName() + " Jump-point");
1137// addJumpPoint(p, system.getBaseName() + " Outer System Jump-point");
1138// }
1139 }
1140 }
1141
1142 //system.autogenerateHyperspaceJumpPoints(true, false);
1143 }
1144
1145 protected void addJumpPoint(LagrangePoint p, String name) {
1146 float orbitRadius = p.parent.orbitRadius;
1147 float orbitDays = p.parent.orbitDays;
1148 float angleOffset = -LAGRANGE_OFFSET * 0.5f;
1149 if (p.type == LagrangePointType.L5) angleOffset = LAGRANGE_OFFSET * 0.5f;
1150 float angle = p.parent.orbitAngle + angleOffset;
1151
1152 SectorEntityToken focus = p.parent.planet.getOrbitFocus();
1153 if (focus == null) focus = systemCenter;
1154
1155 JumpPointAPI point = Global.getFactory().createJumpPoint(null, name);
1156 point.setStandardWormholeToHyperspaceVisual();
1157 if (!p.parent.planet.isGasGiant()) {
1158 point.setRelatedPlanet(p.parent.planet);
1159 }
1160 //point.setCircularOrbit(star, angle + angleOffset, orbitRadius, orbitDays);
1161 //point.setCircularOrbit(systemCenter, angle + angleOffset, orbitRadius, orbitDays);
1162 point.setCircularOrbit(focus, angle + angleOffset, orbitRadius, orbitDays);
1163 system.addEntity(point);
1164 }
1165
1166 public static float addOrbitingEntities(StarSystemAPI system, SectorEntityToken parentStar, StarAge age,
1167 int min, int max, float startingRadius,
1168 int nameOffset, boolean withSpecialNames) {
1169 return addOrbitingEntities(system, parentStar, age, min, max, startingRadius, nameOffset, withSpecialNames, true);
1170 }
1171
1172 public static float addOrbitingEntities(StarSystemAPI system, SectorEntityToken parentStar, StarAge age,
1173 int min, int max, float startingRadius,
1174 int nameOffset, boolean withSpecialNames,
1175 boolean allowHabitable) {
1176 CustomConstellationParams p = new CustomConstellationParams(age);
1177 p.forceNebula = true; // not sure why this is here; should avoid small nebula at lagrange points though (but is that desired?)
1178
1180 gen.system = system;
1181 gen.starData = (StarGenDataSpec) Global.getSettings().getSpec(StarGenDataSpec.class, system.getStar().getSpec().getPlanetType(), false);
1182 gen.starAge = age;
1183 gen.constellationAge = age;
1184 gen.starAgeData = (AgeGenDataSpec) Global.getSettings().getSpec(AgeGenDataSpec.class, age.name(), true);
1185 gen.star = system.getStar();
1186
1188 if (system.getType() != null) gen.systemType = system.getType();
1189
1190
1191 gen.systemCenter = system.getCenter();
1192
1194 PlanetGenDataSpec planetData = null;
1195 PlanetAPI parentPlanet = null;
1196 if (parentStar instanceof PlanetAPI) {
1197 PlanetAPI planet = (PlanetAPI) parentStar;
1198 if (planet.isStar()) {
1199 starData = (StarGenDataSpec) Global.getSettings().getSpec(StarGenDataSpec.class, planet.getSpec().getPlanetType(), false);
1200 } else {
1201 planetData = (PlanetGenDataSpec) Global.getSettings().getSpec(PlanetGenDataSpec.class, planet.getSpec().getPlanetType(), false);
1202 parentPlanet = planet;
1203 }
1204 }
1205
1206 int parentOrbitIndex = -1;
1207 int startingOrbitIndex = 0;
1208
1209 boolean addingAroundStar = parentPlanet == null;
1210 float r = 0;
1211 if (parentStar != null) {
1212 r = parentStar.getRadius();
1213 }
1214
1215 float approximateExtraRadiusPerOrbit = 400f;
1216 if (addingAroundStar) {
1217 parentOrbitIndex = -1;
1218 startingOrbitIndex = (int) ((startingRadius - r - STARTING_RADIUS_STAR_BASE - STARTING_RADIUS_STAR_RANGE * 0.5f) /
1219 (BASE_INCR * 1.25f + approximateExtraRadiusPerOrbit));
1220
1221 if (startingOrbitIndex < 0) startingOrbitIndex = 0;
1222 } else {
1223 float dist = 0f;
1224 if (parentPlanet.getOrbitFocus() != null) {
1225 dist = Misc.getDistance(parentPlanet.getLocation(), parentPlanet.getOrbitFocus().getLocation());
1226 }
1227 parentOrbitIndex = (int) ((dist - r - STARTING_RADIUS_STAR_BASE - STARTING_RADIUS_STAR_RANGE * 0.5f) /
1228 (BASE_INCR * 1.25f + approximateExtraRadiusPerOrbit));
1229 startingOrbitIndex = (int) ((startingRadius - STARTING_RADIUS_MOON_BASE - STARTING_RADIUS_MOON_RANGE * 0.5f) /
1230 (BASE_INCR_MOON * 1.25f));
1231
1232 if (parentOrbitIndex < 0) parentOrbitIndex = 0;
1233 if (startingOrbitIndex < 0) startingOrbitIndex = 0;
1234 }
1235
1236 int num = (int) Math.round(getNormalRandom(min, max));
1237
1238 GenContext context = new GenContext(gen, system, gen.systemCenter, starData,
1239 parentPlanet, startingOrbitIndex, age.name(), startingRadius, MAX_ORBIT_RADIUS,
1240 planetData != null ? planetData.getCategory() : null, parentOrbitIndex);
1241
1242 if (!allowHabitable) {
1243 context.excludeCategories.add(CAT_HAB5);
1244 context.excludeCategories.add(CAT_HAB4);
1245 context.excludeCategories.add(CAT_HAB3);
1246 context.excludeCategories.add(CAT_HAB2);
1247 }
1248
1249 GenResult result = gen.addOrbitingEntities(context, num, false, addingAroundStar, false, false);
1250
1251
1252 Constellation c = new Constellation(ConstellationType.NORMAL, age);
1253 c.getSystems().add(system);
1257 NameAssigner namer = new NameAssigner(c);
1258 if (withSpecialNames) {
1260 } else {
1262 }
1263 namer.setRenameSystem(false);
1264 namer.setStructuralNameOffset(nameOffset);
1265 namer.assignNames(null, null);
1266
1267 for (SectorEntityToken entity : gen.allNameableEntitiesAdded.keySet()) {
1268 if (entity instanceof PlanetAPI && entity.getMarket() != null) {
1269 entity.getMarket().setName(entity.getName());
1270 }
1271 }
1272
1273 return result.orbitalWidth * 0.5f;
1274
1275 }
1276
1277 public static void addSystemwideNebula(StarSystemAPI system, StarAge age) {
1278 CustomConstellationParams p = new CustomConstellationParams(age);
1279 p.forceNebula = true;
1280
1282 gen.system = system;
1283 gen.starData = (StarGenDataSpec) Global.getSettings().getSpec(StarGenDataSpec.class, system.getStar().getSpec().getPlanetType(), false);
1284 gen.starAge = age;
1285 gen.constellationAge = age;
1286 gen.starAgeData = (AgeGenDataSpec) Global.getSettings().getSpec(AgeGenDataSpec.class, age.name(), true);
1288 if (system.getType() != null) gen.systemType = system.getType();
1289
1290 gen.addSystemwideNebula();
1291
1292 system.setAge(age);
1293 system.setHasSystemwideNebula(true);
1294 }
1295
1296
1297 protected void addSystemwideNebula() {
1298 if (nebulaType.equals(NEBULA_NONE)) return;
1299
1300
1301 int w = 128;
1302 int h = 128;
1303
1304 StringBuilder string = new StringBuilder();
1305 for (int y = h - 1; y >= 0; y--) {
1306 for (int x = 0; x < w; x++) {
1307 string.append("x");
1308 }
1309 }
1310 SectorEntityToken nebula = system.addTerrain(Terrain.NEBULA, new TileParams(string.toString(),
1311 w, h,
1312 "terrain", nebulaType, 4, 4, null));
1313 nebula.getLocation().set(0, 0);
1314
1315 NebulaTerrainPlugin nebulaPlugin = (NebulaTerrainPlugin)((CampaignTerrainAPI)nebula).getPlugin();
1316 NebulaEditor editor = new NebulaEditor(nebulaPlugin);
1317
1318 editor.regenNoise();
1319
1320 // good medium thickness: 0.6
1321 //editor.noisePrune(0.8f);
1322
1323 // yes, star age here, despite using constellation age to determine if a nebula to all exists
1324 // basically: young star in old constellation will have lots of nebula, but of the constellation-age color
1326 //editor.noisePrune(0.75f);
1327 //editor.noisePrune(0.1f);
1328
1329// for (float f = 0.1f; f <= 0.9f; f += 0.05f) {
1330// editor.noisePrune(f);
1331// }
1332
1333 editor.regenNoise();
1334
1335 if (systemType != StarSystemType.NEBULA) {
1336 for (PlanetAPI planet : system.getPlanets()) {
1337
1338 if (planet.getOrbit() != null && planet.getOrbit().getFocus() != null &&
1339 planet.getOrbit().getFocus().getOrbit() != null) {
1340 // this planet is orbiting something that's orbiting something
1341 // its motion will be relative to its parent moving
1342 // don't clear anything out for this planet
1343 continue;
1344 }
1345
1346 float clearThreshold = 0f; // clear everything by default
1347 float clearInnerRadius = 0f;
1348 float clearOuterRadius = 0f;
1349 Vector2f clearLoc = null;
1350
1351
1352 if (!planet.isStar() && !planet.isGasGiant()) {
1353 clearThreshold = 1f - Math.min(0f, planet.getRadius() / 300f);
1354 if (clearThreshold > 0.5f) clearThreshold = 0.5f;
1355 }
1356
1357 Vector2f loc = planet.getLocation();
1358 if (planet.getOrbit() != null && planet.getOrbit().getFocus() != null) {
1359 Vector2f focusLoc = planet.getOrbit().getFocus().getLocation();
1360 float dist = Misc.getDistance(planet.getOrbit().getFocus().getLocation(), loc);
1361 float width = planet.getRadius() * 4f + 100f;
1362 if (planet.isStar()) {
1363 StarCoronaTerrainPlugin corona = Misc.getCoronaFor(planet);
1364 if (corona != null) {
1365 width = corona.getParams().bandWidthInEngine * 4f;
1366 }
1367 PulsarBeamTerrainPlugin pulsar = Misc.getPulsarFor(planet);
1368 if (pulsar != null) {
1369 width = Math.max(width, pulsar.getParams().bandWidthInEngine * 0.5f);
1370 }
1371 }
1372 clearLoc = focusLoc;
1373 clearInnerRadius = dist - width / 2f;
1374 clearOuterRadius = dist + width / 2f;
1375 } else if (planet.getOrbit() == null) {
1376 float width = planet.getRadius() * 4f + 100f;
1377 if (planet.isStar()) {
1378 StarCoronaTerrainPlugin corona = Misc.getCoronaFor(planet);
1379 if (corona != null) {
1380 width = corona.getParams().bandWidthInEngine * 4f;
1381 }
1382 PulsarBeamTerrainPlugin pulsar = Misc.getPulsarFor(planet);
1383 if (pulsar != null) {
1384 width = Math.max(width, pulsar.getParams().bandWidthInEngine * 0.5f);
1385 }
1386 }
1387 clearLoc = loc;
1388 clearInnerRadius = 0f;
1389 clearOuterRadius = width;
1390 }
1391
1392 if (clearLoc != null) {
1393 float min = nebulaPlugin.getTileSize() * 2f;
1394 if (clearOuterRadius - clearInnerRadius < min) {
1395 clearOuterRadius = clearInnerRadius + min;
1396 }
1397 editor.clearArc(clearLoc.x, clearLoc.y, clearInnerRadius, clearOuterRadius, 0, 360f, clearThreshold);
1398 }
1399 }
1400 }
1401
1402 // add a spiral going from the outside towards the star
1403 float angleOffset = random.nextFloat() * 360f;
1404 editor.clearArc(0f, 0f, 30000, 31000 + 1000f * random.nextFloat(),
1405 angleOffset + 0f, angleOffset + 360f * (2f + random.nextFloat() * 2f), 0.01f, 0f);
1406
1407 // do some random arcs
1408 int numArcs = (int) (8f + 6f * random.nextFloat());
1409 //int numArcs = 11;
1410
1411 for (int i = 0; i < numArcs; i++) {
1412 //float dist = 4000f + 10000f * random.nextFloat();
1413 float dist = 15000f + 15000f * random.nextFloat();
1414 float angle = random.nextFloat() * 360f;
1415
1416 Vector2f dir = Misc.getUnitVectorAtDegreeAngle(angle);
1417 dir.scale(dist - (2000f + 8000f * random.nextFloat()));
1418
1419 //float tileSize = nebulaPlugin.getTileSize();
1420 //float width = tileSize * (2f + 4f * random.nextFloat());
1421 float width = 800f * (1f + 2f * random.nextFloat());
1422
1423 float clearThreshold = 0f + 0.5f * random.nextFloat();
1424 //clearThreshold = 0f;
1425
1426 editor.clearArc(dir.x, dir.y, dist - width/2f, dist + width/2f, 0, 360f, clearThreshold);
1427 }
1428 }
1429
1430
1431 protected GenResult addPlanetsAndTerrain(float maxOrbitRadius) {
1432 boolean hasOrbits = random.nextFloat() < starData.getProbOrbits();
1433 if (!hasOrbits) return null;
1434
1437 int numOrbits = (int) Math.round(getNormalRandom(min, max));
1438
1439 if (numOrbits <= 0) return null;
1440
1441
1442
1443 float currentRadius = centerRadius + STARTING_RADIUS_STAR_BASE + STARTING_RADIUS_STAR_RANGE * random.nextFloat();
1444
1445 //GenContext context = new GenContext(this, system, star, starData,
1446 GenContext context = new GenContext(this, system, systemCenter, starData,
1447 null, 0, starAge.name(), currentRadius, maxOrbitRadius, null, -1);
1448
1449 if (systemType == StarSystemType.BINARY_CLOSE || systemType == StarSystemType.TRINARY_1CLOSE_1FAR) {
1450 context.multipliers.add(COL_BINARY);
1451 }
1452 if (systemType == StarSystemType.TRINARY_2CLOSE) {
1453 context.multipliers.add(COL_TRINARY);
1454 }
1455
1456
1457 GenResult result = addOrbitingEntities(context, numOrbits, false, true, false, true);
1458 result.context = context;
1459 return result;
1460 }
1461
1462 protected GenResult addOrbitingEntities(GenContext context, int numOrbits, boolean addingMoons, boolean addMoons, boolean parentIsMoon, boolean nothingOk) {
1463
1464 if (DEBUG && context.starData != null) {
1465 if (addingMoons && context.parent != null) {
1466 System.out.println(" Adding " + numOrbits + " moon orbits around " + context.parent.getSpec().getPlanetType());
1467 } else {
1468 System.out.println("Adding " + numOrbits + " orbits around " + context.starData.getId());
1469 }
1470 }
1471
1472 float currentRadius = context.currentRadius;
1473 float lastIncrementExtra = 0f;
1474
1475 String extraMult = null;
1476 if (parentIsMoon) extraMult = COL_IS_MOON;
1477
1478 int extra = 0;
1479 for (int i = 0; i < numOrbits; i++) {
1480
1481 context.orbitIndex = i + context.startingOrbitIndex + extra;
1482 //CategoryGenDataSpec categoryData = pickCategory(orbitIndex, i, starAge.name(), starType, context.parentCategory, null, nothingOk);
1483 CategoryGenDataSpec categoryData = pickCategory(context, extraMult, nothingOk);
1484 nothingOk = true; // only applies to first pick, after this, we'll have *something*
1485
1486// if (!addingMoons) {
1487// categoryData = (CategoryGenDataSpec) Global.getSettings().getSpec(CategoryGenDataSpec.class, "cat_giant", true);
1488// //categoryData = (CategoryGenDataSpec) Global.getSettings().getSpec(CategoryGenDataSpec.class, "cat_terrain_rings", true);
1489// }
1490// if (orbitIndex == 0 && addMoons) {
1491// categoryData = (CategoryGenDataSpec) Global.getSettings().getSpec(CategoryGenDataSpec.class, "cat_giant", true);
1492// //categoryData = (CategoryGenDataSpec) Global.getSettings().getSpec(CategoryGenDataSpec.class, "cat_hab4", true);
1493// }
1494// if (orbitIndex == 1 && addMoons) {
1495// if (!addingMoons) {
1496// categoryData = (CategoryGenDataSpec) Global.getSettings().getSpec(CategoryGenDataSpec.class, "cat_giant", true);
1497// }
1498// } else {
1499// categoryData = (CategoryGenDataSpec) Global.getSettings().getSpec(CategoryGenDataSpec.class, "cat_terrain_rings", true);
1500// }
1501 //categoryData = (CategoryGenDataSpec) Global.getSettings().getSpec(CategoryGenDataSpec.class, "cat_terrain_rings", true);
1502
1503 GenResult result = null;
1504 float incrMult = 1f;
1505
1506 if (categoryData != null && !CAT_NOTHING.equals(categoryData.getCategory())) {
1507 //WeightedRandomPicker<EntityGenDataSpec> picker = getPickerForCategory(categoryData, orbitIndex, i, starAge.name(), starType, context.parentCategory, null);
1508 WeightedRandomPicker<EntityGenDataSpec> picker = getPickerForCategory(categoryData, context, extraMult);
1509 if (DEBUG) {
1510 picker.print(" Picking from category " + categoryData.getCategory() +
1511 ", orbit index " + (context.parent != null ? context.parentOrbitIndex : context.orbitIndex));
1512 }
1513 EntityGenDataSpec entityData = picker.pick();
1514 if (DEBUG) {
1515 if (entityData == null) {
1516 System.out.println(" Nothing to pick");
1517 System.out.println();
1518 } else {
1519 System.out.println(" Picked: " + entityData.getId());
1520 System.out.println();
1521 }
1522 }
1523
1524 context.currentRadius = currentRadius;
1525 //context.orbitIndex = i;
1526
1527 if (entityData instanceof PlanetGenDataSpec) {
1528 PlanetGenDataSpec planetData = (PlanetGenDataSpec) entityData;
1529 result = addPlanet(context, planetData, addingMoons, addMoons);
1530
1531 } else if (entityData instanceof TerrainGenDataSpec) {
1532 TerrainGenDataSpec terrainData = (TerrainGenDataSpec) entityData;
1533 result = addTerrain(context, terrainData);
1534 }
1535
1536 if (result != null) {
1537 //List<SectorEntityToken> combined = new ArrayList<SectorEntityToken>(result.entities);
1538 for (SectorEntityToken curr : result.entities) {
1539 if (context.lagrangeParent != null && !result.entities.isEmpty()) {
1540 lagrangeParentMap.put(curr, context.lagrangeParent.planet);
1541 }
1542 allNameableEntitiesAdded.put(curr, result.entities);
1543 }
1544 } else {
1545 incrMult = 0.5f;
1546 }
1547 } else {
1548 incrMult = 0.5f;
1549 }
1550
1551 float baseIncr = BASE_INCR;
1552 if (addingMoons) {
1553 baseIncr = BASE_INCR_MOON;
1554 }
1555 baseIncr *= incrMult;
1556
1557 float increment = baseIncr + baseIncr * 0.5f * random.nextFloat();
1558 if (result != null) {
1559 if (result.orbitalWidth > 1000) extra++;
1560 //increment = Math.max(increment, result.orbitalWidth + baseIncr * 0.5f);
1561 //increment += result.orbitalWidth;
1562 increment = Math.max(increment + Math.min(result.orbitalWidth, 300f),
1563 result.orbitalWidth + increment * 0.5f);
1564 if (result.onlyIncrementByWidth) {
1565 increment = result.orbitalWidth;
1566 }
1567 lastIncrementExtra = Math.max(increment * 0.1f, increment - result.orbitalWidth);
1568 } else {
1569 lastIncrementExtra = increment;
1570 }
1571 currentRadius += increment;
1572
1573 if (currentRadius >= context.maxOrbitRadius) {
1574 break;
1575 }
1576 }
1577
1578 GenResult result = new GenResult();
1579 result.onlyIncrementByWidth = false;
1580 result.orbitalWidth = (currentRadius - lastIncrementExtra) * 2f;
1581 return result;
1582 }
1583
1584 protected GenResult addTerrain(GenContext context, TerrainGenDataSpec terrainData) {
1585 TerrainGenPlugin plugin = pickTerrainGenPlugin(terrainData, context);
1586 if (plugin == null ) return null;
1587 GenResult result = plugin.generate(terrainData, context);
1588
1589
1590 return result;
1591 }
1592
1593
1594 public GenResult addPlanet(GenContext context, PlanetGenDataSpec planetData, boolean isMoon, boolean addMoons) {
1595 //float orbitRadius = (orbitIndex + 1f) * 1500 + star.getRadius();
1596 float radius = getRadius(planetData.getMinRadius(), planetData.getMaxRadius());
1597 if (isMoon) {// || context.lagrangeParent != null) {
1598 //radius *= MOON_RADIUS_MULT;
1601 radius *= mult;
1602 if (radius < MIN_MOON_RADIUS) {
1603 radius = MIN_MOON_RADIUS;
1604 }
1605 float parentRadius = 100000f;
1606 if (context.parent != null || context.lagrangeParent != null) {
1607 PlanetAPI parent = context.parent;
1608 if (context.lagrangeParent != null) {
1609 parent = context.lagrangeParent.planet;
1610 }
1611 parentRadius = parent.getRadius();
1612 }
1613 if (context.parentRadiusOverride > 0) {
1614 parentRadius = context.parentRadiusOverride;
1615 }
1616
1618 float max = parentRadius * MOON_RADIUS_MAX_FRACTION_OF_PARENT;
1619 if (radius > max) {
1620 radius = max;
1621 }
1622 }
1623 }
1624
1625 float orbitRadius = context.currentRadius + radius;
1626 float orbitDays = orbitRadius / (20f + random.nextFloat() * 5f);
1627
1628 //String planetId = system.getId() + "_planet_" + context.center.getId() + "_" + context.orbitIndex;
1629 String planetId = context.center.getId() + ":planet_" + context.orbitIndex;
1630 String planetName = "Planet " + context.orbitIndex;
1631 if (context.parent != null) {
1632 planetId = system.getId() + "_moon_" + context.center.getId() + "_" + context.parent.getId() + "_" + context.orbitIndex;
1633 planetName = context.parent.getName() + " moon " + context.orbitIndex;
1634 }
1635 String planetType = planetData.getId();
1636 SectorEntityToken parent = context.center;
1637 if (context.parent != null) parent = context.parent;
1638
1639 float angle = random.nextFloat() * 360f;
1640
1641 // if adding a moon to a largange point planet, then parentCategory == null
1642 // will fail and it'll orbit the parent rather than stay at the point
1643 if (context.parentCategory == null) {
1644 if (context.lagrangeParent != null && context.lagrangePointType != null) {
1645 orbitRadius = context.lagrangeParent.orbitRadius;
1646 orbitDays = context.lagrangeParent.orbitDays;
1647 float angleOffset = -LAGRANGE_OFFSET;
1648 if (context.lagrangePointType == LagrangePointType.L5) angleOffset = LAGRANGE_OFFSET;
1649 angle = context.lagrangeParent.orbitAngle + angleOffset;
1650 planetName += " " + context.lagrangePointType.name();
1651 planetId += "_" + context.lagrangePointType.name();
1652 }
1653 }
1654
1655 PlanetAPI planet = system.addPlanet(planetId, parent, planetName, planetType, angle, radius, orbitRadius, orbitDays);
1656 if (planet.isGasGiant()) {
1657 if (systemType == StarSystemType.NEBULA) {
1658 planet.setAutogenJumpPointNameInHyper(system.getBaseName() + ", " + planetName + " Gravity Well");
1659 }
1660 }
1661
1662 float radiusWithMoons = planet.getRadius();
1663 if (addMoons) {
1664 boolean hasOrbits = random.nextFloat() < planetData.getProbOrbits();
1665 float min = planetData.getMinOrbits();
1666 float max = planetData.getMaxOrbits();
1667// double r = random.nextFloat();
1668// r *= r;
1669// int numOrbits = (int) (min + Math.round((max - min) * r));
1670 int numOrbits = (int) Math.round(getNormalRandom(min, max));
1671
1672// hasOrbits = true;
1673// numOrbits = 2;
1674
1675// if (numOrbits == 3) {
1676// System.out.println("efwefwefew");
1677// }
1678
1679 if (hasOrbits && numOrbits > 0) {
1680// if (!planet.isGasGiant()) {
1681// System.out.println("sdfwefew " + star.getId());
1682// }
1683 float startingRadius = planet.getRadius() + STARTING_RADIUS_MOON_BASE + STARTING_RADIUS_MOON_RANGE * random.nextFloat();
1684 GenContext moonContext = new GenContext(this, context.system, context.center, context.starData, planet, 0, starAge.name(),
1685 startingRadius, context.maxOrbitRadius, planetData.getCategory(), context.orbitIndex);
1686 moonContext.excludeCategories.addAll(context.excludeCategories);
1687 moonContext.multipliers.addAll(context.multipliers);
1688 // add moons etc
1689 GenResult moonResult = addOrbitingEntities(moonContext, numOrbits, true, false, false, false);
1690
1691 context.generatedPlanets.addAll(moonContext.generatedPlanets);
1692
1693 // move the parent planet out so that there's room for everythnig that was added
1694 radius = moonResult.orbitalWidth * 0.5f;
1695 orbitRadius = context.currentRadius + radius;
1696 orbitDays = orbitRadius / (20f + random.nextFloat() * 5f);
1697
1698 radiusWithMoons = radius;
1699
1700 planet.setOrbit(Global.getFactory().createCircularOrbit(context.center, angle, orbitRadius, orbitDays));
1701 }
1702 } else if (isMoon) {
1703 float startingRadius = planet.getRadius() + STARTING_RADIUS_MOON_BASE + STARTING_RADIUS_MOON_RANGE * random.nextFloat();
1704 GenContext moonContext = new GenContext(this, context.system, context.center, context.starData, planet, 0, starAge.name(),
1705 startingRadius, context.maxOrbitRadius, planetData.getCategory(), context.orbitIndex);
1706 moonContext.excludeCategories.addAll(context.excludeCategories);
1707 moonContext.multipliers.addAll(context.multipliers);
1708 GenResult moonResult = addOrbitingEntities(moonContext, 1, true, false, true, true);
1709 context.generatedPlanets.addAll(moonContext.generatedPlanets);
1710
1711 }
1712
1713
1714 Color color = getColor(planetData.getMinColor(), planetData.getMaxColor());
1715 //System.out.println("Setting color: " + color);
1716 planet.getSpec().setPlanetColor(color);
1717 if (planet.getSpec().getAtmosphereThickness() > 0) {
1718 Color atmosphereColor = Misc.interpolateColor(planet.getSpec().getAtmosphereColor(), color, 0.25f);
1719 atmosphereColor = Misc.setAlpha(atmosphereColor, planet.getSpec().getAtmosphereColor().getAlpha());
1720 planet.getSpec().setAtmosphereColor(atmosphereColor);
1721
1722 if (planet.getSpec().getCloudTexture() != null) {
1723 Color cloudColor = Misc.interpolateColor(planet.getSpec().getCloudColor(), color, 0.25f);
1724 cloudColor = Misc.setAlpha(cloudColor, planet.getSpec().getCloudColor().getAlpha());
1725 planet.getSpec().setAtmosphereColor(atmosphereColor);
1726 }
1727 }
1728
1729 float tilt = planet.getSpec().getTilt();
1730 float pitch = planet.getSpec().getPitch();
1731
1732// "tilt" # left-right (>0 tilts to the left)
1733// "pitch" # towards-away from the viewer (>0 pitches towards)
1734 float sign = (float) Math.signum(random.nextFloat() - 0.5f);
1735 double r = random.nextFloat();
1736 //r *= r;
1737 if (sign > 0) {
1738 tilt += r * TILT_MAX;
1739 } else {
1740 tilt += r * TILT_MIN;
1741 }
1742
1743 sign = (float) Math.signum(random.nextFloat() - 0.5f);
1744 r = random.nextFloat();
1745 //r *= r;
1746 if (sign > 0) {
1747 pitch += r * PITCH_MAX;
1748 } else {
1749 tilt += r * PITCH_MIN;
1750 }
1751 planet.getSpec().setTilt(tilt);
1752 planet.getSpec().setPitch(pitch);
1753
1754
1755 if (context.orbitIndex == 0 && context.parent == null && context.orbitIndex < context.starData.getHabZoneStart() &&
1756 orbitRadius < 2500f + context.starData.getHabZoneStart() * 200f) {
1757 //&& radiusWithMoons <= planet.getRadius() + 500f) {
1758 if (planet.getSpec().getAtmosphereThickness() > 0) {
1759 WeightedRandomPicker<String> glowPicker = new WeightedRandomPicker<String>(random);
1760 glowPicker.add("banded", 10f);
1761 glowPicker.add("aurorae", 10f);
1762
1763 String glow = glowPicker.pick();
1764
1765 planet.getSpec().setGlowTexture(Global.getSettings().getSpriteName("hab_glows", glow));
1766 //system.getLightColor();
1767 if (context.center instanceof PlanetAPI) {
1768 planet.getSpec().setGlowColor(((PlanetAPI)context.center).getSpec().getCoronaColor());
1769 }
1770 planet.getSpec().setUseReverseLightForGlow(true);
1771 planet.getSpec().setAtmosphereThickness(0.5f);
1772 planet.getSpec().setCloudRotation(planet.getSpec().getCloudRotation() * (-1f - 2f * random.nextFloat()));
1773
1774 if (planet.isGasGiant()) {// && radiusWithMoons <= planet.getRadius() + 500f) {
1775 system.addCorona(planet, Terrain.CORONA_AKA_MAINYU,
1776 300f + 200f * random.nextFloat(), // radius outside planet
1777 5f, // burn level of "wind"
1778 0f, // flare probability
1779 1f // CR loss mult while in it
1780 );
1781 }
1782 }
1783 }
1784
1785 planet.applySpecChanges();
1786
1788
1789
1790 GeneratedPlanet generatedPlanetData = new GeneratedPlanet(parent, planet, isMoon, orbitDays, orbitRadius, angle);
1791 context.generatedPlanets.add(generatedPlanetData);
1792
1793 // need to add this here because planet might have been moved after adding moons
1794 //if (context.parentCategory == null && context.lagrangeParent == null && planet.isGasGiant()) {
1795 if (!isMoon && context.lagrangeParent == null) {// && planet.isGasGiant()) {
1796 addStuffAtLagrangePoints(context, generatedPlanetData);
1797 }
1798
1799 GenResult result = new GenResult();
1800 result.orbitalWidth = radius * 2f;
1801 result.onlyIncrementByWidth = false;
1802 result.entities.add(planet);
1803 return result;
1804 }
1805
1806 protected void addStuffAtLagrangePoints(GenContext context, GeneratedPlanet planet) {
1807 float radius = planet.planet.getRadius();
1808 float probability = radius / 500f;
1809 if (radius < 150f) probability = 0f;
1810 if (planet.planet.isGasGiant()) probability = 1f;
1811 if (random.nextFloat() > probability) {
1812 return;
1813 }
1814
1815 // still a high chance to end up w/ nothing if cat_nothing is picked
1816
1817// int orbitIndex = context.orbitIndex;
1818// String starType = context.star.getTypeId();
1819// if (context.parentOrbitIndex >= 0) {
1820// orbitIndex = context.parentOrbitIndex;
1821// }
1822
1823 Set<LagrangePointType> points = EnumSet.of(LagrangePointType.L4, LagrangePointType.L5);
1824 for (LagrangePointType point : points) {
1825 //CategoryGenDataSpec categoryData = pickCategory(orbitIndex, 0, starAge.name(), starType, context.parentCategory, COL_LAGRANGE, true);
1826 CategoryGenDataSpec categoryData = pickCategory(context, COL_LAGRANGE, true);
1827 if (categoryData != null && !CAT_NOTHING.equals(categoryData.getCategory())) {
1828 //WeightedRandomPicker<EntityGenDataSpec> picker = getPickerForCategory(categoryData, orbitIndex, 0, starAge.name(), starType, context.parentCategory, COL_LAGRANGE);
1829 WeightedRandomPicker<EntityGenDataSpec> picker = getPickerForCategory(categoryData, context, COL_LAGRANGE);
1830 if (DEBUG) {
1831 picker.print(" Picking from category " + categoryData.getCategory() +
1832 ", orbit index " + (context.parent != null ? context.parentOrbitIndex : context.orbitIndex + ", for lagrange point"));
1833 }
1834 EntityGenDataSpec entityData = picker.pick();
1835 if (DEBUG) {
1836 if (entityData == null) {
1837 System.out.println(" Nothing to pick");
1838 System.out.println();
1839 } else {
1840 System.out.println(" Picked: " + entityData.getId());
1841 System.out.println();
1842 }
1843 }
1844
1845 context.lagrangeParent = planet;
1846 context.lagrangePointType = point;
1847
1848 GenResult result = null;
1849 if (entityData instanceof PlanetGenDataSpec) {
1850 PlanetGenDataSpec planetData = (PlanetGenDataSpec) entityData;
1851 result = addPlanet(context, planetData, true, true);
1852 } else if (entityData instanceof TerrainGenDataSpec) {
1853 TerrainGenDataSpec terrainData = (TerrainGenDataSpec) entityData;
1854 result = addTerrain(context, terrainData);
1855 }
1856
1857 if (result != null) {
1858 for (SectorEntityToken curr : result.entities) {
1859 if (context.lagrangeParent != null && !result.entities.isEmpty()) {
1860 lagrangeParentMap.put(curr, context.lagrangeParent.planet);
1861 }
1862 allNameableEntitiesAdded.put(curr, result.entities);
1863 }
1864 }
1865 }
1866 }
1867 context.lagrangeParent = null;
1868 context.lagrangePointType = null;
1869 }
1870
1871
1872
1873 //protected CategoryGenDataSpec pickCategory(int orbitIndex, int fromParentOrbitIndex, String age, String starType, String parentCategory, String extraMult, boolean nothingOk) {
1874 public CategoryGenDataSpec pickCategory(GenContext context, String extraMult, boolean nothingOk) {
1875// int orbitIndex = context.orbitIndex;
1876// if (context.parentOrbitIndex >= 0) {
1877// orbitIndex = context.parentOrbitIndex;
1878// }
1879// int fromParentOrbitIndex = context.orbitIndex;
1880 String age = context.age;
1881 //String starType = context.star.getTypeId();
1882 String starType = star != null ? star.getTypeId() : null;
1883 if (context.center instanceof PlanetAPI) {
1884 PlanetAPI star = (PlanetAPI) context.center;
1885 if (star.isStar()) starType = star.getTypeId();
1886 }
1887
1888 String parentCategory = context.parentCategory;
1889
1890 WeightedRandomPicker<CategoryGenDataSpec> picker = new WeightedRandomPicker<CategoryGenDataSpec>(random);
1891 Collection<CategoryGenDataSpec> categoryDataSpecs = Global.getSettings().getAllSpecs(CategoryGenDataSpec.class);
1892 for (CategoryGenDataSpec categoryData : categoryDataSpecs) {
1893 if (context.excludeCategories.contains(categoryData.getCategory())) continue;
1894
1895 boolean catNothing = categoryData.getCategory().equals(CAT_NOTHING);
1896 if (!nothingOk && catNothing) continue;
1897// if (categoryData.getCategory().equals("cat_terrain_rings")) {
1898// System.out.println("sdfkwefewfe");
1899// }
1900 float weight = categoryData.getFrequency();
1901 if (age != null) weight *= categoryData.getMultiplier(age);
1902 if (starType != null) weight *= categoryData.getMultiplier(starType);
1903 if (parentCategory != null) weight *= categoryData.getMultiplier(parentCategory);
1904 for (String col : context.multipliers) {
1905 weight *= categoryData.getMultiplier(col);
1906 }
1907 if (extraMult != null) weight *= categoryData.getMultiplier(extraMult);
1908
1909 //if (weight > 0 && (catNothing || !isCategoryEmpty(categoryData, orbitIndex, fromParentOrbitIndex, age, starType, parentCategory, extraMult))) {
1910 if (weight > 0 && (catNothing || !isCategoryEmpty(categoryData, context, extraMult, nothingOk))) {
1911 picker.add(categoryData, weight);
1912 }
1913 }
1914
1915 if (DEBUG) {
1916 boolean withParent = context.parent != null;
1917 int orbitIndex = context.orbitIndex;
1918 String parentType = "";
1919 if (withParent) {
1920 parentType = context.parent.getSpec().getPlanetType();
1921 orbitIndex = context.parentOrbitIndex;
1922 }
1923
1924// float offset = orbitIndex;
1925// float minIndex = context.starData.getHabZoneStart() + planetData.getHabOffsetMin() + offset;
1926// float maxIndex = context.starData.getHabZoneStart() + planetData.getHabOffsetMax() + offset;
1927 //boolean inRightRange = orbitIndex >= minIndex && orbitIndex <= maxIndex;
1928 int habDiff = orbitIndex - (int) context.starData.getHabZoneStart();
1929 if (withParent) {
1930 picker.print(" Picking category for moon of " + parentType +
1931 ", orbit from star: " + orbitIndex + " (" + habDiff + ")" + ", extra: " + extraMult);
1932 } else {
1933 picker.print(" Picking category for entity orbiting star " + starType +
1934 ", orbit from star: " + orbitIndex + " (" + habDiff + ")" + ", extra: " + extraMult);
1935 }
1936 }
1937
1938 CategoryGenDataSpec pick = picker.pick();
1939 if (DEBUG) {
1940 System.out.println(" Picked: " + pick.getCategory());
1941 System.out.println();
1942 }
1943
1944 return pick;
1945 }
1946
1947 public boolean isCategoryEmpty(CategoryGenDataSpec categoryData, GenContext context, String extraMult, boolean nothingOk) {
1948 return getPickerForCategory(categoryData, context, extraMult, nothingOk).isEmpty();
1949 }
1950
1951 protected float getHabOffset(EntityGenDataSpec data) {
1952 if (starAge == StarAge.YOUNG) {
1953 return data.getHabOffsetYOUNG();
1954 }
1955 if (starAge == StarAge.AVERAGE) {
1956 return data.getHabOffsetAVERAGE();
1957 }
1958 if (starAge == StarAge.OLD) {
1959 return data.getHabOffsetOLD();
1960 }
1961 return 0f;
1962 }
1963
1964// protected WeightedRandomPicker<EntityGenDataSpec> getPickerForCategory(CategoryGenDataSpec categoryData,
1965// int orbitIndex, int fromParentOrbitIndex, String age, String starType, String parentCategory, String extraMult) {
1966 protected WeightedRandomPicker<EntityGenDataSpec> getPickerForCategory(CategoryGenDataSpec categoryData,
1967 GenContext context, String extraMult) {
1968 return getPickerForCategory(categoryData, context, extraMult, true);
1969 }
1970 protected WeightedRandomPicker<EntityGenDataSpec> getPickerForCategory(CategoryGenDataSpec categoryData,
1971 GenContext context, String extraMult, boolean nothingOk) {
1972 int orbitIndex = context.orbitIndex;
1973 if (context.parentOrbitIndex >= 0) {
1974 orbitIndex = context.parentOrbitIndex;
1975 }
1976 int fromParentOrbitIndex = context.orbitIndex;
1977 String age = context.age;
1978 //String starType = context.star.getTypeId();
1979 String starType = star != null ? star.getTypeId() : null;
1980 if (context.center instanceof PlanetAPI) {
1981 PlanetAPI star = (PlanetAPI) context.center;
1982 if (star.isStar()) starType = star.getTypeId();
1983 }
1984
1985 String parentCategory = context.parentCategory;
1986
1987
1988 WeightedRandomPicker<EntityGenDataSpec> picker = new WeightedRandomPicker<EntityGenDataSpec>(random);
1989
1990 Collection<PlanetGenDataSpec> planetDataSpecs = Global.getSettings().getAllSpecs(PlanetGenDataSpec.class);
1991 for (PlanetGenDataSpec planetData : planetDataSpecs) {
1992 if (!planetData.getCategory().equals(categoryData.getCategory())) continue;
1993
1994 float offset = getHabOffset(planetData);
1995 float minIndex = context.starData.getHabZoneStart() + planetData.getHabOffsetMin() + offset;
1996 float maxIndex = context.starData.getHabZoneStart() + planetData.getHabOffsetMax() + offset;
1997 boolean inRightRange = orbitIndex >= minIndex && orbitIndex <= maxIndex;
1998 boolean giantMoonException = CAT_GIANT.equals(parentCategory) &&
1999 (planetData.hasTag(TAG_GIANT_MOON) && context.parent != null && context.parent.isGasGiant());
2000 if (!inRightRange && !giantMoonException) continue;
2001
2002// if (planetData.getId().equals("rocky_unstable")) {
2003// System.out.println("dsfwefwefw");
2004// }
2005
2006 boolean orbitIndexOk = fromParentOrbitIndex == 0 || !planetData.hasTag(TAG_FIRST_ORBIT_ONLY);
2007 if (!orbitIndexOk) continue;
2008
2009 boolean lagrangeStatusOk = COL_LAGRANGE.equals(extraMult) || !planetData.hasTag(TAG_LAGRANGE_ONLY);
2010 if (!lagrangeStatusOk) continue;
2011
2012 boolean nebulaStatusOk = NEBULA_NONE.equals(nebulaType) || !planetData.hasTag(TAG_NOT_IN_NEBULA);
2013 nebulaStatusOk &= !NEBULA_NONE.equals(nebulaType) || !planetData.hasTag(TAG_REQUIRES_NEBULA);
2014 nebulaStatusOk &= systemType != StarSystemType.NEBULA || !planetData.hasTag(TAG_NOT_NEBULA_UNLESS_MOON) || context.parent != null;
2015 if (!nebulaStatusOk) continue;
2016
2017 float weight = planetData.getFrequency();
2018 if (age != null) weight *= planetData.getMultiplier(age);
2019 if (starType != null) weight *= planetData.getMultiplier(starType);
2020 if (parentCategory != null) weight *= planetData.getMultiplier(parentCategory);
2021 for (String col : context.multipliers) {
2022 weight *= planetData.getMultiplier(col);
2023 }
2024 if (extraMult != null) weight *= planetData.getMultiplier(extraMult);
2025 if (weight > 0) picker.add(planetData, weight);
2026 }
2027
2028 Collection<TerrainGenDataSpec> terrainDataSpecs = Global.getSettings().getAllSpecs(TerrainGenDataSpec.class);
2029 for (TerrainGenDataSpec terrainData : terrainDataSpecs) {
2030 if (!terrainData.getCategory().equals(categoryData.getCategory())) continue;
2031
2032 if (!nothingOk && terrainData.getId().equals("rings_nothing")) continue;
2033
2034 float offset = getHabOffset(terrainData);
2035 float minIndex = context.starData.getHabZoneStart() + terrainData.getHabOffsetMin() + offset;
2036 float maxIndex = context.starData.getHabZoneStart() + terrainData.getHabOffsetMax() + offset;
2037 boolean inRightRange = orbitIndex >= minIndex && orbitIndex <= maxIndex;
2038 boolean giantMoonException = CAT_GIANT.equals(parentCategory) &&
2039 (terrainData.hasTag(TAG_GIANT_MOON) && context.parent != null && context.parent.isGasGiant());
2040 if (!inRightRange && !giantMoonException) continue;
2041
2042 boolean orbitIndexOk = fromParentOrbitIndex == 0 || !terrainData.hasTag(TAG_FIRST_ORBIT_ONLY);
2043 if (!orbitIndexOk) continue;
2044
2045 boolean lagrangeStatusOk = COL_LAGRANGE.equals(extraMult) || !terrainData.hasTag(TAG_LAGRANGE_ONLY);
2046 if (!lagrangeStatusOk) continue;
2047
2048 boolean nebulaStatusOk = NEBULA_NONE.equals(nebulaType) || !terrainData.hasTag(TAG_NOT_IN_NEBULA);
2049 nebulaStatusOk &= !NEBULA_NONE.equals(nebulaType) || !terrainData.hasTag(TAG_REQUIRES_NEBULA);
2050 nebulaStatusOk &= systemType != StarSystemType.NEBULA || !terrainData.hasTag(TAG_NOT_NEBULA_UNLESS_MOON) || context.parent != null;
2051 if (!nebulaStatusOk) continue;
2052
2053 float weight = terrainData.getFrequency();
2054 if (age != null) weight *= terrainData.getMultiplier(age);
2055 if (starType != null) weight *= terrainData.getMultiplier(starType);
2056 if (parentCategory != null) weight *= terrainData.getMultiplier(parentCategory);
2057 for (String col : context.multipliers) {
2058 weight *= terrainData.getMultiplier(col);
2059 }
2060 if (extraMult != null) weight *= terrainData.getMultiplier(extraMult);
2061 if (weight > 0) picker.add(terrainData, weight);
2062 }
2063
2064 return picker;
2065 }
2066
2067
2068
2070 Color one = Color.white, two = null, three = null;
2071
2072 switch (systemType) {
2073 case BINARY_FAR:
2074 case TRINARY_2FAR:
2075 case SINGLE:
2076 case NEBULA:
2078 break;
2079 case BINARY_CLOSE:
2080 case TRINARY_1CLOSE_1FAR:
2083 break;
2084 case TRINARY_2CLOSE:
2088 break;
2089 }
2090
2091 Color result = one;
2092 if (two != null && three == null) {
2093 result = Misc.interpolateColor(one, two, 0.5f);
2094 } else if (two != null && three != null) {
2095 result = Misc.interpolateColor(one, two, 0.5f);
2096 result = Misc.interpolateColor(result, three, 0.5f);
2097 }
2098 system.setLightColor(result); // light color in entire system, affects all entities
2099 }
2100
2101
2102 protected Color pickLightColorForStar(PlanetAPI star) {
2103 StarGenDataSpec starData = (StarGenDataSpec) Global.getSettings().getSpec(StarGenDataSpec.class, star.getSpec().getPlanetType(), false);
2104 Color min = starData.getLightColorMin();
2105 Color max = starData.getLightColorMax();
2106 Color lightColor = Misc.interpolateColor(min, max, random.nextFloat());
2107 return lightColor;
2108 }
2109
2110
2111// protected void setLightColorBasedOnStar(PlanetAPI star) {
2112// StarGenDataSpec starData = (StarGenDataSpec) Global.getSettings().getSpec(StarGenDataSpec.class, star.getSpec().getPlanetType(), false);
2113// Color min = starData.getLightColorMin();
2114// Color max = starData.getLightColorMax();
2115// Color lightColor = Misc.interpolateColor(min, max, random.nextFloat());
2116// system.setLightColor(lightColor); // light color in entire system, affects all entities
2117// }
2118
2119
2120 protected PlanetAPI addRandomStar(String id, String name) {
2121 PlanetSpecAPI starSpec = pickStar(constellationAge);
2122 if (starSpec == null) return null;
2123
2124 StarGenDataSpec starData = (StarGenDataSpec) Global.getSettings().getSpec(StarGenDataSpec.class, starSpec.getPlanetType(), false);
2126
2127 float corona = radius * (starData.getCoronaMult() + starData.getCoronaVar() * (random.nextFloat() - 0.5f));
2128 if (corona < starData.getCoronaMin()) corona = starData.getCoronaMin();
2129
2130 PlanetAPI star = system.addPlanet(id, // unique id for this star
2131 null,
2132 name,
2133 starSpec.getPlanetType(), // id in planets.json
2134 0f, // angle
2135 radius, // radius (in pixels at default zoom)
2136 10000f, // orbit radius
2137 1000f // orbit days
2138 );
2139
2140 system.addCorona(star, corona, // corona radius, from star edge
2142 (float) (starData.getMinFlare() + (starData.getMaxFlare() - starData.getMinFlare()) * random.nextFloat()),
2144
2145 return star;
2146 }
2147
2148
2149
2150 public void init(StarSystemAPI system, StarAge age) {
2152 hyper = Global.getSector().getHyperspace();
2153 this.starAge = age;
2154 this.system = system;
2155
2156 }
2157 protected boolean initSystem(String name, Vector2f loc) {
2159 system = sector.createStarSystem(name);
2160 system.setProcgen(true);
2161 system.setType(systemType);
2162 system.getLocation().set(loc);
2163 hyper = Global.getSector().getHyperspace();
2164
2165 //system.setBackgroundTextureFilename("graphics/backgrounds/background2.jpg");
2166 system.setBackgroundTextureFilename(backgroundName);
2167 return true;
2168 }
2169
2170 protected void updateAgeAfterPickingStar() {
2172 if (starAge == StarAge.ANY) {
2174 }
2176 }
2177
2178 protected void cleanup() {
2179 if (system != null) {
2180 Global.getSector().removeStarSystem(system);
2181 system = null;
2182 }
2183 }
2184
2185 public String getNebulaType() {
2186 return nebulaType;
2187 }
2188
2190 return constellationAge;
2191 }
2192
2194 return starAge;
2195 }
2196
2197
2198 public PlanetSpecAPI pickStar(StarAge age) {
2199 if (params != null && !params.starTypes.isEmpty()) {
2200 String id = params.starTypes.remove(0);
2201 //if (id.equals("black_hole") && systemType == StarSystemType.NEBULA) id = "nebula_center_old";
2202 for (PlanetSpecAPI spec : Global.getSettings().getAllPlanetSpecs()) {
2203 if (spec.getPlanetType().equals(id)) {
2204 Object test = Global.getSettings().getSpec(StarGenDataSpec.class, id, true);
2205 if (test == null) continue;
2206 StarGenDataSpec data = (StarGenDataSpec) test;
2207 boolean hasTag = data.hasTag(StarSystemType.NEBULA.name());
2208 boolean nebType = systemType == StarSystemType.NEBULA;
2209 boolean nebulaStatusOk = hasTag == nebType;
2210 if (nebulaStatusOk) {
2211 return spec;
2212 }
2213 }
2214 }
2215 // doesn't work because the actual class the spec is registered under is PlanetSpec,
2216 // not the API-exposed PlanetSpecAPI
2217 //return (PlanetSpecAPI) Global.getSettings().getSpec(PlanetSpecAPI.class, id, true);
2218 }
2219
2220 WeightedRandomPicker<PlanetSpecAPI> picker = new WeightedRandomPicker<PlanetSpecAPI>(random);
2221 for (PlanetSpecAPI spec : Global.getSettings().getAllPlanetSpecs()) {
2222 if (!spec.isStar()) continue;
2223
2224 String id = spec.getPlanetType();
2225 Object test = Global.getSettings().getSpec(StarGenDataSpec.class, id, true);
2226 if (test == null) continue;
2227 StarGenDataSpec data = (StarGenDataSpec) test;
2228
2229
2230// boolean nebulaStatusOk = NEBULA_NONE.equals(nebulaType) || !data.hasTag(TAG_NOT_IN_NEBULA);
2231// nebulaStatusOk &= !NEBULA_NONE.equals(nebulaType) || !data.hasTag(TAG_REQUIRES_NEBULA);
2232// //nebulaStatusOk &= !NEBULA_NONE.equals(nebulaType) || !data.hasTag(StarSystemType.NEBULA.name());
2233// //nebulaStatusOk &= systemType != StarSystemType.NEBULA || data.hasTag(StarSystemType.NEBULA.name());
2234// nebulaStatusOk &= !data.hasTag(StarSystemType.NEBULA.name()) || systemType == StarSystemType.NEBULA;
2235
2236 boolean hasTag = data.hasTag(StarSystemType.NEBULA.name());
2237 boolean nebType = systemType == StarSystemType.NEBULA;
2238 boolean nebulaStatusOk = hasTag == nebType;
2239
2240 if (!nebulaStatusOk) continue;
2241
2242 //if (!id.equals("empty_nebula_center")) continue;
2243
2244 float freq = 0f;
2245 switch (age) {
2246 case AVERAGE:
2247 freq = data.getFreqAVERAGE();
2248 break;
2249 case OLD:
2250 freq = data.getFreqOLD();
2251 break;
2252 case YOUNG:
2253 freq = data.getFreqYOUNG();
2254 break;
2255 }
2256 //System.out.println("Adding: " + spec.getPlanetType() + ", weight: " + freq);
2257 picker.add(spec, freq);
2258 }
2259// if (systemType == StarSystemType.NEBULA) {
2260// System.out.println("wfwefwe");
2261// }
2262 return picker.pick();
2263 }
2264
2265
2266 public static Color getColor(Color min, Color max) {
2267 Color color = new Color((int) (min.getRed() + (max.getRed() - min.getRed()) * random.nextDouble()),
2268 (int) (min.getGreen() + (max.getGreen() - min.getGreen()) * random.nextDouble()),
2269 (int) (min.getBlue() + (max.getBlue() - min.getBlue()) * random.nextDouble()),
2270 255);
2271
2272 return color;
2273 }
2274
2275
2276
2277 public static float getNormalRandom(float min, float max) {
2278 return getNormalRandom(random, min, max);
2279 }
2280
2281 public static float getNormalRandom(Random random, float min, float max) {
2282 double r = random.nextGaussian();
2283 r *= 0.2f;
2284 r += 0.5f;
2285 if (r < 0) r = 0;
2286 if (r > 1) r = 1;
2287
2288 // 70% chance 0.3 < r < .7
2289 // 95% chance 0.1 < r < .7
2290 // 99% chance 0 < r < 1
2291 return min + (float) r * (max - min);
2292 }
2293
2294 public static float getRadius(float min, float max) {
2295 float radius = (float) (min + (max - min) * random.nextFloat());
2296 return radius;
2297 }
2298
2299 public static float getRandom(float min, float max) {
2300 float radius = (float) (min + (max - min) * random.nextFloat());
2301 return radius;
2302 }
2303 public Map<SectorEntityToken, PlanetAPI> getLagrangeParentMap() {
2304 return lagrangeParentMap;
2305 }
2306
2307 public Map<SectorEntityToken, List<SectorEntityToken>> getAllEntitiesAdded() {
2309 }
2310
2311 public static Gender pickGender() {
2312 if (random.nextBoolean()) {
2313 return Gender.MALE;
2314 }
2315 return Gender.FEMALE;
2316 }
2317}
2318
2319
2320
2321
2322
2323
2324
2325
2326
static SettingsAPI getSettings()
Definition Global.java:51
static FactoryAPI getFactory()
Definition Global.java:35
static SectorAPI getSector()
Definition Global.java:59
static SpringSystem doConstellationLayout(List< StarSystemAPI > systems, Random random, Vector2f centerPoint)
void setAllEntitiesAdded(Map< SectorEntityToken, List< SectorEntityToken > > allEntitiesAdded)
void setLagrangeParentMap(Map< SectorEntityToken, PlanetAPI > lagrangeParentMap)
void setLeavePickedNameUnused(boolean leavePickedNameUnused)
void setSpecialNamesProbability(float specialNamesProbability)
void assignNames(String name, String secondary)
void clearArc(float x, float y, float innerRadius, float outerRadius, float startAngle, float endAngle)
static void generateConditionsForPlanet(GenContext context, PlanetAPI planet)
void addStuffAtLagrangePoints(GenContext context, GeneratedPlanet planet)
static float addOrbitingEntities(StarSystemAPI system, SectorEntityToken parentStar, StarAge age, int min, int max, float startingRadius, int nameOffset, boolean withSpecialNames, boolean allowHabitable)
static TerrainGenPlugin pickTerrainGenPlugin(TerrainGenDataSpec terrainData, GenContext context)
GenResult addTerrain(GenContext context, TerrainGenDataSpec terrainData)
Map< SectorEntityToken, List< SectorEntityToken > > allNameableEntitiesAdded
static void addSystemwideNebula(StarSystemAPI system, StarAge age)
static Map< String, WeightedRandomPicker< String > > backgroundsByNebulaType
boolean isCategoryEmpty(CategoryGenDataSpec categoryData, GenContext context, String extraMult, boolean nothingOk)
CategoryGenDataSpec pickCategory(GenContext context, String extraMult, boolean nothingOk)
GenResult addPlanet(GenContext context, PlanetGenDataSpec planetData, boolean isMoon, boolean addMoons)
void addFarStar(PlanetAPI farStar, float orbitAngle, float baseOrbitRadius, float orbitPeriod)
WeightedRandomPicker< EntityGenDataSpec > getPickerForCategory(CategoryGenDataSpec categoryData, GenContext context, String extraMult, boolean nothingOk)
static float addOrbitingEntities(StarSystemAPI system, SectorEntityToken parentStar, StarAge age, int min, int max, float startingRadius, int nameOffset, boolean withSpecialNames)
Map< SectorEntityToken, List< SectorEntityToken > > getAllEntitiesAdded()
WeightedRandomPicker< EntityGenDataSpec > getPickerForCategory(CategoryGenDataSpec categoryData, GenContext context, String extraMult)
static float getNormalRandom(Random random, float min, float max)
GenResult addOrbitingEntities(GenContext context, int numOrbits, boolean addingMoons, boolean addMoons, boolean parentIsMoon, boolean nothingOk)
OrbitAPI createCircularOrbit(SectorEntityToken focus, float angle, float orbitRadius, float orbitDays)
JumpPointAPI createJumpPoint(String id, String name)
< T > Collection< T > getAllSpecs(Class< T > c)
String getSpriteName(String category, String id)
Object getSpec(Class c, String id, boolean nullOnNotFound)
List< PlanetSpecAPI > getAllPlanetSpecs()
GenResult generate(TerrainGenDataSpec terrainData, GenContext context)