Starsector API
Loading...
Searching...
No Matches
DerelictThemeGenerator.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.HashSet;
7import java.util.LinkedHashMap;
8import java.util.List;
9import java.util.Random;
10import java.util.Set;
11
12import org.lwjgl.util.vector.Vector2f;
13
14import com.fs.starfarer.api.Global;
15import com.fs.starfarer.api.campaign.LocationAPI;
16import com.fs.starfarer.api.campaign.PlanetAPI;
17import com.fs.starfarer.api.campaign.SectorEntityToken;
18import com.fs.starfarer.api.campaign.StarSystemAPI;
19import com.fs.starfarer.api.campaign.econ.MarketAPI.SurveyLevel;
20import com.fs.starfarer.api.campaign.econ.MarketConditionAPI;
21import com.fs.starfarer.api.impl.campaign.ids.Conditions;
22import com.fs.starfarer.api.impl.campaign.ids.Entities;
23import com.fs.starfarer.api.impl.campaign.ids.Factions;
24import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
25import com.fs.starfarer.api.impl.campaign.ids.Tags;
26import com.fs.starfarer.api.impl.campaign.intel.events.ht.HTPoints;
27import com.fs.starfarer.api.impl.campaign.procgen.Constellation;
28import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator;
29import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.DomainSurveyDerelictSpecial.DomainSurveyDerelictSpecialData;
30import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.DomainSurveyDerelictSpecial.SpecialType;
31import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.SurveyDataSpecial.SurveyDataSpecialData;
32import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.SurveyDataSpecial.SurveyDataSpecialType;
33import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.TopographicDataSpecial.TopographicDataSpecialData;
34import com.fs.starfarer.api.util.Misc;
35import com.fs.starfarer.api.util.WeightedRandomPicker;
36
37
39
40 public static final float BASE_LINK_FRACTION = 0.25f;
41 public static final float SALVAGE_SPECIAL_FRACTION = 0.5f;
42 public static final float TOPOGRAPHIC_DATA_FRACTION = 0.1f;
43
44 public static final int BRANCHES_PER_MOTHERSHIP_MIN = 3;
45 public static final int BRANCHES_PER_MOTHERSHIP_MAX = 4;
46
47 public static final int BRANCHES_PER_SHIP_MIN = 2;
48 public static final int BRANCHES_PER_SHIP_MAX = 3;
49
50
51 public static class SystemGenData {
52 public int numMotherships;
53 public int numSurveyShips;
54 public int numProbes;
55 }
56
57
58 public String getThemeId() {
59 return Themes.DERELICTS;
60 }
61
62 @Override
63 public void generateForSector(ThemeGenContext context, float allowedUnusedFraction) {
64
65 float total = (float) (context.constellations.size() - context.majorThemes.size()) * allowedUnusedFraction;
66 if (total <= 0) return;
67
69 float avg2 = (BRANCHES_PER_SHIP_MIN + BRANCHES_PER_SHIP_MAX) / 2f;
70 float perChain = 1 + avg1 + (avg1 * avg2);
71
72 float num = total / perChain;
73 if (num < 1) num = 1;
74 if (num > 3) num = 3;
75
76 if (num > 1 && num < 2) {
77 num = 2;
78 } else {
79 num = Math.round(num);
80 }
81
82 List<AddedEntity> mothershipsSoFar = new ArrayList<AddedEntity>();
83
84 for (int i = 0; i < num; i++) {
85 addMothershipChain(context, mothershipsSoFar);
86 }
87
88
89
90 WeightedRandomPicker<StarSystemAPI> cryoSystems = new WeightedRandomPicker<StarSystemAPI>(StarSystemGenerator.random);
91 WeightedRandomPicker<StarSystemAPI> backup = new WeightedRandomPicker<StarSystemAPI>(StarSystemGenerator.random);
92 OUTER: for (StarSystemAPI system : Global.getSector().getStarSystems()) {
93 float w = 0f;
94 if (system.hasTag(Tags.THEME_DERELICT_PROBES)) {
95 w = 10f;
96 } else if (system.hasTag(Tags.THEME_DERELICT_SURVEY_SHIP)) {
97 w = 10f;
98 } else if (system.hasTag(Tags.THEME_DERELICT_MOTHERSHIP)) {
99 w = 10f;
100 } else if (system.hasTag(Tags.THEME_DERELICT)) {
101 w = 10f;
102 } else {
103 continue;
104 }
105
106 int numPlanets = 0;
107 boolean hasHab = false;
108 for (PlanetAPI planet : system.getPlanets()) {
109 if (planet.isStar()) continue;
110 if (planet.getSpec().isPulsar()) continue OUTER;
111 hasHab |= planet.getMarket() != null && planet.getMarket().hasCondition(Conditions.HABITABLE);
112 numPlanets++;
113 }
114
115 WeightedRandomPicker<StarSystemAPI> use = cryoSystems;
116 if (!hasHab || numPlanets < 3) {
117 use = backup;
118 }
119
120 if (hasHab) w += 5;
121 w += numPlanets;
122
123 if (use == backup) {
124 w *= 0.0001f;
125 }
126 use.add(system, w);
127 }
128
129 int numCryo = 2;
130 if (cryoSystems.isEmpty() || cryoSystems.getItems().size() < numCryo + 1) {
131 cryoSystems.addAll(backup);
132 }
133
134 int added = 0;
135 WeightedRandomPicker<String> cryosleeperNames = new WeightedRandomPicker<String>(random);
136 cryosleeperNames.add("Calypso");
137 cryosleeperNames.add("Tantalus");
138 while (added < numCryo && !cryoSystems.isEmpty()) {
139 StarSystemAPI pick = cryoSystems.pickAndRemove();
140 String name = cryosleeperNames.pickAndRemove();
141 AddedEntity cryo = addCryosleeper(pick, name);
142 if (cryo != null) {
143 added++;
144 }
145 }
146 }
147
148 protected void addMothershipChain(ThemeGenContext context, List<AddedEntity> mothershipsSoFar) {
149
150 List<AddedEntity> all = new ArrayList<AddedEntity>();
151
152
153 Vector2f center = new Vector2f();
154 for (AddedEntity e : mothershipsSoFar) {
155 Vector2f.add(center, e.entity.getLocationInHyperspace(), center);
156 }
157 center.scale(1f / (float)(mothershipsSoFar.size() + 1f));
158
159 List<Constellation> constellations = getSortedAvailableConstellations(context, false, center, null);
160 WeightedRandomPicker<Constellation> picker = new WeightedRandomPicker<Constellation>(StarSystemGenerator.random);
161 for (int i = 0; i < constellations.size() / 3; i++) {
162 picker.add(constellations.get(i));
163 }
164
165 Constellation main = picker.pick();
166 if (main == null) return;
167
168 if (DEBUG) {
169 System.out.println("Picked for mothership chain start: [" + main.getNameWithType() + "] (" + (int)main.getLocation().x + ", " + (int)main.getLocation().y + ")");
170 }
171
172 constellations.remove(main);
173 context.majorThemes.put(main, Themes.DERELICTS);
174
175
176 StarSystemAPI mainSystem = main.getSystemWithMostPlanets();
177 if (mainSystem == null) return;
178
179 //mainSystem.addTag(Tags.THEME_DERELICT);
180 for (StarSystemAPI system : main.getSystems()) {
181 system.addTag(Tags.THEME_DERELICT);
182 }
183
184// if (mainSystem.getName().toLowerCase().contains("valac")) {
185// System.out.println("HERE13123123123");
186// }
187
188 AddedEntity mothership = addMothership(mainSystem);
189 if (mothership == null) return;
190
191 all.add(mothership);
192
193 if (DEBUG) {
194 System.out.println(" Added mothership to [" + mainSystem.getNameWithLowercaseType() + "]");
195 }
196
197 //if (true) return;
198
199 // probes in mothership system
200 //int probesNearMothership = (int) Math.round(StarSystemGenerator.getRandom(2, 4));
201 int probesNearMothership = getNumProbesForSystem(mothership.entity.getContainingLocation());
202 List<AddedEntity> added = addToSystem(mainSystem, Entities.DERELICT_SURVEY_PROBE, probesNearMothership);
203 all.addAll(added);
204
205
206 linkFractionToParent(mothership, added,
208 SpecialType.LOCATION_MOTHERSHIP);
209
210 // survey ships in mothership constellation
211 int surveyShipsNearMothership = (int) Math.round(StarSystemGenerator.getRandom(0, 3));
212 if (surveyShipsNearMothership > main.getSystems().size()) surveyShipsNearMothership = main.getSystems().size();
213 if (DEBUG) {
214 System.out.println(String.format("Adding %d survey ships near mothership", surveyShipsNearMothership));
215 }
216 List<AddedEntity> addedShips = addToConstellation(main, Entities.DERELICT_SURVEY_SHIP, surveyShipsNearMothership, false);
217 all.addAll(addedShips);
218
219 // probes in each system with survey ship
220 for (AddedEntity e : addedShips) {
221 int probesNearSurveyShip = (int) Math.round(StarSystemGenerator.getRandom(1, 3));
222 //int probesNearSurveyShip = getNumProbesForSystem(e.entity.getContainingLocation());
223 added = addProbes((StarSystemAPI) e.entity.getContainingLocation(), probesNearSurveyShip);
224 all.addAll(added);
225
226 linkFractionToParent(e, added,
228 SpecialType.LOCATION_SURVEY_SHIP);
229 }
230
231 linkFractionToParent(mothership, addedShips,
233 SpecialType.LOCATION_MOTHERSHIP);
234
235 //if (true) return;
236
237 constellations = getSortedAvailableConstellations(context, false, mothership.entity.getLocationInHyperspace(), null);
238 picker = new WeightedRandomPicker<Constellation>(StarSystemGenerator.random);
239 for (int i = constellations.size() - 7; i < constellations.size(); i++) {
240 if (i < 0) continue;
241 picker.add(constellations.get(i));
242 }
243
244 int numSurveyShipsInNearConstellations = (int) Math.round(StarSystemGenerator.getRandom(BRANCHES_PER_MOTHERSHIP_MIN, BRANCHES_PER_MOTHERSHIP_MAX));
245 if (DEBUG) {
246 System.out.println(String.format("Adding up to %d survey ships", numSurveyShipsInNearConstellations));
247 }
248 List<Constellation> constellationsForSurveyShips = new ArrayList<Constellation>();
249 for (int i = 0; i < numSurveyShipsInNearConstellations && !picker.isEmpty(); i++) {
250 constellationsForSurveyShips.add(picker.pickAndRemove());
251 }
252 List<AddedEntity> outerShips = new ArrayList<AddedEntity>();
253
254
255 for (Constellation c : constellationsForSurveyShips) {
256 context.majorThemes.put(c, Themes.DERELICTS);
257
258 if (DEBUG) {
259 System.out.println(" Picked for survey ship: [" + c.getNameWithType() + "]");
260 }
261
262 addedShips = addToConstellation(c, Entities.DERELICT_SURVEY_SHIP, 1, true);
263 if (addedShips.isEmpty()) continue;
264
265 all.addAll(addedShips);
266
267 AddedEntity ship = addedShips.get(0);
268 outerShips.addAll(addedShips);
269
270 //int probesNearSurveyShip = (int) Math.round(StarSystemGenerator.getRandom(1, 3));
271 int probesNearSurveyShip = getNumProbesForSystem(ship.entity.getContainingLocation());
272 added = addProbes((StarSystemAPI) ship.entity.getContainingLocation(), probesNearSurveyShip);
273 all.addAll(added);
274
275 linkFractionToParent(ship, added,
277 SpecialType.LOCATION_SURVEY_SHIP);
278
279 int probesInSameConstellation = (int) Math.round(StarSystemGenerator.getRandom(2, 5));
280 int max = c.getSystems().size() + 2;
281 if (probesInSameConstellation > max) probesInSameConstellation = max;
282
283 added = addToConstellation(c, Entities.DERELICT_SURVEY_PROBE, probesInSameConstellation, false);
284 all.addAll(added);
285
286 linkFractionToParent(ship, added,
288 SpecialType.LOCATION_SURVEY_SHIP);
289
290
291
292 List<Constellation> c2 = getSortedAvailableConstellations(context, false, c.getLocation(), constellationsForSurveyShips);
293 WeightedRandomPicker<Constellation> p2 = new WeightedRandomPicker<Constellation>(StarSystemGenerator.random);
294 //for (int i = 0; i < constellations.size() / 3 && i < 7; i++) {
295 for (int i = c2.size() - 3; i < c2.size(); i++) {
296 if (i < 0) continue;
297 p2.add(constellations.get(i));
298 }
299
300 int probeSystemsNearShip = (int) Math.round(StarSystemGenerator.getRandom(BRANCHES_PER_SHIP_MIN, BRANCHES_PER_SHIP_MAX));
301 int k = 0;
302 if (DEBUG) {
303 System.out.println(String.format("Adding probes to %d constellations near survey ship", probeSystemsNearShip));
304 }
305 List<AddedEntity> probes3 = new ArrayList<AddedEntity>();
306 while (k < probeSystemsNearShip && !p2.isEmpty()) {
307 Constellation pick = p2.pickAndRemove();
308 k++;
309 context.majorThemes.put(pick, Themes.NO_THEME);
310 int probesInConstellation = (int) Math.round(StarSystemGenerator.getRandom(1, 3));
311 probes3.addAll(addToConstellation(pick, Entities.DERELICT_SURVEY_PROBE, probesInConstellation, false));
312 }
313
314 all.addAll(probes3);
315 linkFractionToParent(ship, probes3,
317 SpecialType.LOCATION_MOTHERSHIP);
318 }
319
320 linkFractionToParent(mothership, outerShips,
322 SpecialType.LOCATION_MOTHERSHIP);
323
324
325
327 }
328
329 public static Set<String> interestingConditions = new HashSet<String>();
330 public static Set<String> interestingConditionsWithoutHabitable = new HashSet<String>();
331 public static Set<String> interestingConditionsWithRuins = new HashSet<String>();
332 static {
333 //interestingConditions.add(Conditions.VOLATILES_ABUNDANT);
334 interestingConditions.add(Conditions.VOLATILES_PLENTIFUL);
335 //interestingConditions.add(Conditions.ORE_RICH);
336 interestingConditions.add(Conditions.ORE_ULTRARICH);
337 interestingConditions.add(Conditions.RARE_ORE_RICH);
338 interestingConditions.add(Conditions.RARE_ORE_ULTRARICH);
339 interestingConditions.add(Conditions.FARMLAND_BOUNTIFUL);
340 interestingConditions.add(Conditions.FARMLAND_ADEQUATE);
341 //interestingConditions.add(Conditions.ORGANICS_ABUNDANT);
342 interestingConditions.add(Conditions.ORGANICS_PLENTIFUL);
343 interestingConditions.add(Conditions.HABITABLE);
344
346 interestingConditionsWithoutHabitable.remove(Conditions.HABITABLE);
347
349 interestingConditionsWithRuins.add(Conditions.RUINS_VAST);
350 interestingConditionsWithRuins.add(Conditions.RUINS_EXTENSIVE);
351 }
352
353
354
355 protected void assignRandomSpecials(List<AddedEntity> entities) {
356 Set<PlanetAPI> usedPlanets = new HashSet<PlanetAPI>();
357 Set<StarSystemAPI> usedSystems = new HashSet<StarSystemAPI>();
358
359 for (AddedEntity e : entities) {
360 if (hasSpecial(e.entity)) continue;
361
362 SurveyDataSpecialType type = null;
363
365 int min = 0;
366 int max = 0;
367 if (Entities.DERELICT_SURVEY_PROBE.equals(e.entityType)) {
368 min = HTPoints.LOW_MIN;
369 max = HTPoints.LOW_MAX;
370 } else if (Entities.DERELICT_SURVEY_SHIP.equals(e.entityType)) {
371 min = HTPoints.MEDIUM_MIN;
372 max = HTPoints.MEDIUM_MAX;
373 } else if (Entities.DERELICT_MOTHERSHIP.equals(e.entityType)) {
374 min = HTPoints.HIGH_MIN;
375 max = HTPoints.HIGH_MAX;
376 }
377 int points = min + StarSystemGenerator.random.nextInt(max - min + 1);
378 if (points > 0) {
379 TopographicDataSpecialData data = new TopographicDataSpecialData(points);
380 Misc.setSalvageSpecial(e.entity, data);
381 continue;
382 }
383 }
385 float p1 = 0.33f, p2 = 0.67f;
386 if (Entities.DERELICT_SURVEY_PROBE.equals(e.entityType)) {
387 p1 = 0.75f;
388 p2 = 1f;
389 } else if (Entities.DERELICT_SURVEY_SHIP.equals(e.entityType)) {
390 p1 = 0.25f;
391 p2 = 0.8f;
392 } else if (Entities.DERELICT_MOTHERSHIP.equals(e.entityType)) {
393 p1 = 0.1f;
394 p2 = 0.6f;
395 }
396
397 float r = StarSystemGenerator.random.nextFloat();
398 if (r < p1) {
399 type = SurveyDataSpecialType.PLANET_INTERESTING_PROPERTY;
400 } else if (r < p2) {
401 type = SurveyDataSpecialType.PLANET_SURVEY_DATA;
402 } else {
403 type = SurveyDataSpecialType.SYSTEM_PRELIMINARY_SURVEY;
404 }
405 }
406
407 //type = SpecialType.PLANET_SURVEY_DATA;
408
409 if (type == SurveyDataSpecialType.PLANET_INTERESTING_PROPERTY) {
410 PlanetAPI planet = findInterestingPlanet(e.entity.getConstellation().getSystems(), usedPlanets);
411 if (planet != null) {
412 String conditionId = getInterestingCondition(planet, false);
413 if (conditionId != null) {
414 SurveyDataSpecialData data = new SurveyDataSpecialData(SurveyDataSpecialType.PLANET_INTERESTING_PROPERTY);
415 data.entityId = planet.getId();
416 data.secondaryId = conditionId;
417 data.includeRuins = false;
418 Misc.setSalvageSpecial(e.entity, data);
419 usedPlanets.add(planet);
420 }
421
422// DomainSurveyDerelictSpecialData special = new DomainSurveyDerelictSpecialData(type);
423// special.entityId = planet.getId();
424// for (MarketConditionAPI mc : planet.getMarket().getConditions()) {
425// if (interestingConditions.contains(mc.getId())) {
426// special.secondaryId = mc.getId();
427// }
428// }
429// usedPlanets.add(planet);
430// e.entity.getMemoryWithoutUpdate().set(MemFlags.SALVAGE_SPECIAL_DATA, special);
431 }
432 } else if (type == SurveyDataSpecialType.PLANET_SURVEY_DATA) {
433 PlanetAPI planet = findInterestingPlanet(e.entity.getConstellation().getSystems(), usedPlanets);
434 if (planet != null) {
435 SurveyDataSpecialData data = new SurveyDataSpecialData(SurveyDataSpecialType.PLANET_SURVEY_DATA);
436 data.entityId = planet.getId();
437 data.includeRuins = false;
438 Misc.setSalvageSpecial(e.entity, data);
439 usedPlanets.add(planet);
440
441// DomainSurveyDerelictSpecialData special = new DomainSurveyDerelictSpecialData(type);
442// special.entityId = planet.getId();
443// usedPlanets.add(planet);
444// e.entity.getMemoryWithoutUpdate().set(MemFlags.SALVAGE_SPECIAL_DATA, special);
445 }
446 } else if (type == SurveyDataSpecialType.SYSTEM_PRELIMINARY_SURVEY) {
447 StarSystemAPI system = findNearbySystem(e.entity, usedSystems);
448 if (system != null) {
449 SurveyDataSpecialData data = new SurveyDataSpecialData(SurveyDataSpecialType.SYSTEM_PRELIMINARY_SURVEY);
450 data.entityId = system.getId();
451 Misc.setSalvageSpecial(e.entity, data);
452
453// DomainSurveyDerelictSpecialData special = new DomainSurveyDerelictSpecialData(type);
454// special.entityId = system.getId();
455// usedSystems.add(system);
456// e.entity.getMemoryWithoutUpdate().set(MemFlags.SALVAGE_SPECIAL_DATA, special);
457 }
458 }
459 }
460 }
461
462
463 public static StarSystemAPI findNearbySystem(SectorEntityToken from, Set<StarSystemAPI> exclude) {
464 return findNearbySystem(from, exclude, null, 10000f);
465 }
466
467 public static StarSystemAPI findNearbySystem(SectorEntityToken from, Set<StarSystemAPI> exclude, Random random, float maxRange) {
469
470 WeightedRandomPicker<StarSystemAPI> picker = new WeightedRandomPicker<StarSystemAPI>(random);
471
472 for (StarSystemAPI system : Global.getSector().getStarSystems()) {
473 if (exclude != null && exclude.contains(system)) continue;
474
475 float dist = Misc.getDistance(from.getLocationInHyperspace(), system.getLocation());
476 if (dist > maxRange) continue;
477 if (systemIsEmpty(system)) continue;
478
479 picker.add(system);
480 }
481
482 return picker.pick();
483 }
484
485
486 public static String getInterestingCondition(PlanetAPI planet, boolean includeRuins) {
487 if (planet == null) return null;
488
489 Set<String> conditions = interestingConditions;
490 if (includeRuins) conditions = interestingConditionsWithRuins;
491
492 for (MarketConditionAPI mc : planet.getMarket().getConditions()) {
493 if (conditions.contains(mc.getId())) {
494 return mc.getId();
495 }
496 }
497 return null;
498 }
499
500 public static PlanetAPI findInterestingPlanet(List<StarSystemAPI> systems, Set<PlanetAPI> exclude) {
501 return findInterestingPlanet(systems, exclude, true, false, null);
502 }
503 public static PlanetAPI findInterestingPlanet(List<StarSystemAPI> systems, Set<PlanetAPI> exclude, boolean includeKnown, boolean includeRuins, Random random) {
505
506 WeightedRandomPicker<PlanetAPI> planets = new WeightedRandomPicker<PlanetAPI>(random);
507
508 Set<String> conditions = interestingConditions;
509 if (includeRuins) conditions = interestingConditionsWithRuins;
510
511 for (StarSystemAPI system : systems) {
512 for (PlanetAPI planet : system.getPlanets()) {
513 if (planet.isStar()) continue;
514 if (exclude != null && exclude.contains(planet)) continue;
515 if (planet.getMarket() == null || !planet.getMarket().isPlanetConditionMarketOnly()) continue;
516 if (!includeKnown && planet.getMarket() != null && planet.getMarket().getSurveyLevel() == SurveyLevel.FULL) {
517 continue;
518 }
519 //if (planet.getMarket().getSurveyLevel() == SurveyLevel.FULL) continue;
520 for (MarketConditionAPI mc : planet.getMarket().getConditions()) {
521 if (conditions.contains(mc.getId())) {
522 if (mc.getId().equals(Conditions.HABITABLE) && planet.getMarket().getHazardValue() > 1.25f) {
523 continue;
524 }
525 planets.add(planet);
526 break;
527 }
528 }
529 }
530 }
531 return planets.pick();
532 }
533
534
535 protected int getNumProbesForSystem(LocationAPI system) {
536 int base = 1;
537 int planets = system.getPlanets().size();
538
539 if (planets <= 3) {
540 } else if (planets <= 5) {
541 base += 1;
542 } else if (planets <= 8) {
543 base += 2;
544 } else {
545 base += 3;
546 }
547
548 base += StarSystemGenerator.random.nextInt(2);
549
550 return base;
551 }
552 protected void linkFractionToParent(AddedEntity parent, List<AddedEntity> children, float p, SpecialType type) {
553
554 WeightedRandomPicker<AddedEntity> picker = new WeightedRandomPicker<AddedEntity>(StarSystemGenerator.random);
555 for (AddedEntity c : children) {
556 if (!hasSpecial(c.entity)) {
557 picker.add(c);
558 }
559 }
560
561 int extraLinks = (int) Math.max(1, Math.round(children.size() * p * (1f + StarSystemGenerator.random.nextFloat() * 0.5f)));
562 for (int i = 0; i < extraLinks && !picker.isEmpty(); i++) {
563 AddedEntity e = picker.pickAndRemove();
564 linkToParent(e.entity, parent.entity, type);
565 }
566 }
567
568// protected AddedEntity getClosest(AddedEntity from, List<AddedEntity> choices) {
569// float min = Float.MAX_VALUE;
570// AddedEntity result = null;
571// for (AddedEntity e : choices) {
572//
573// }
574//
575// return result;
576// }
577
578 protected void linkToParent(SectorEntityToken from, SectorEntityToken parent, SpecialType type) {
579 if (hasSpecial(from)) return;
580
581 DomainSurveyDerelictSpecialData special = new DomainSurveyDerelictSpecialData(type);
582 special.entityId = parent.getId();
583 from.getMemoryWithoutUpdate().set(MemFlags.SALVAGE_SPECIAL_DATA, special);
584 }
585
586 protected void linkToMothership(SectorEntityToken from, SectorEntityToken mothership) {
587 if (hasSpecial(from)) return;
588
589 DomainSurveyDerelictSpecialData special = new DomainSurveyDerelictSpecialData(SpecialType.LOCATION_MOTHERSHIP);
590 special.entityId = mothership.getId();
591 from.getMemoryWithoutUpdate().set(MemFlags.SALVAGE_SPECIAL_DATA, special);
592 }
593
594 public static boolean hasSpecial(SectorEntityToken entity) {
595 return entity.getMemoryWithoutUpdate().contains(MemFlags.SALVAGE_SPECIAL_DATA);
596 }
597
598 protected List<AddedEntity> addToConstellation(Constellation c, String type, int num, boolean biggestFirst) {
599 List<AddedEntity> result = new ArrayList<AddedEntity>();
600
601 WeightedRandomPicker<StarSystemAPI> picker = new WeightedRandomPicker<StarSystemAPI>(StarSystemGenerator.random);
602 picker.addAll(c.getSystems());
603
604 boolean first = true;
605 for (int i = 0; i < num; i++) {
606 StarSystemAPI system = picker.pick();
607 if (biggestFirst && first) system = c.getSystemWithMostPlanets();
608 first = false;
609
610 if (system == null) continue;
611
612 result.addAll(addToSystem(system, type, 1));
613 }
614
615 return result;
616 }
617
618 protected List<AddedEntity> addToSystem(StarSystemAPI system, String type, int num) {
619 List<AddedEntity> result = new ArrayList<AddedEntity>();
620 if (system == null) return result;
621
622 for (int i = 0; i < num; i++) {
623 AddedEntity e = null;
624 if (Entities.DERELICT_MOTHERSHIP.equals(type)) {
625 e = addMothership(system);
626 } else if (Entities.DERELICT_SURVEY_SHIP.equals(type)) {
627 e = addSurveyShip(system);
628 } else if (Entities.DERELICT_SURVEY_PROBE.equals(type)) {
629 result.addAll(addProbes(system, 1));
630 }
631 if (e != null) {
632 result.add(e);
633 }
634 }
635 return result;
636 }
637
638
639
640 protected AddedEntity addMothership(StarSystemAPI system) {
641 LinkedHashMap<LocationType, Float> weights = new LinkedHashMap<LocationType, Float>();
642 weights.put(LocationType.PLANET_ORBIT, 10f);
643 weights.put(LocationType.JUMP_ORBIT, 1f);
644 weights.put(LocationType.NEAR_STAR, 1f);
645 weights.put(LocationType.OUTER_SYSTEM, 5f);
646 weights.put(LocationType.IN_ASTEROID_BELT, 10f);
647 weights.put(LocationType.IN_RING, 10f);
648 weights.put(LocationType.IN_ASTEROID_FIELD, 10f);
649 weights.put(LocationType.STAR_ORBIT, 1f);
650 weights.put(LocationType.IN_SMALL_NEBULA, 1f);
651 weights.put(LocationType.L_POINT, 1f);
652 WeightedRandomPicker<EntityLocation> locs = getLocations(random, system, 100f, weights);
653
654// if (system.getName().toLowerCase().contains("valac")) {
655// for (int i = 0; i < 10; i++) {
656// //Random random = new Random(32895278947689263L);
657// StarSystemGenerator.random = new Random(32895278947689263L);
658// random = StarSystemGenerator.random;
659// locs = getLocations(random, system, 100f, weights);
660// EntityLocation loc = locs.pickAndRemove();
661// System.out.println("Location: " + loc.toString());
662// }
663// }
664
665 AddedEntity entity = addEntity(random, system, locs, Entities.DERELICT_MOTHERSHIP, Factions.DERELICT);
666 if (entity != null) {
667 system.addTag(Tags.THEME_INTERESTING);
668 system.addTag(Tags.THEME_DERELICT);
669 system.addTag(Tags.THEME_DERELICT_MOTHERSHIP);
670 }
671
672 if (DEBUG) {
673 if (entity != null) {
674 System.out.println(String.format(" Added mothership to %s", system.getNameWithLowercaseType()));
675 } else {
676 System.out.println(String.format(" Failed to add mothership to %s", system.getNameWithLowercaseType()));
677 }
678 }
679 return entity;
680 }
681
682
683 protected AddedEntity addCryosleeper(StarSystemAPI system, String name) {
684 LinkedHashMap<LocationType, Float> weights = new LinkedHashMap<LocationType, Float>();
685 weights.put(LocationType.PLANET_ORBIT, 10f);
686 weights.put(LocationType.JUMP_ORBIT, 1f);
687 weights.put(LocationType.NEAR_STAR, 1f);
688 weights.put(LocationType.OUTER_SYSTEM, 5f);
689 weights.put(LocationType.IN_ASTEROID_BELT, 5f);
690 weights.put(LocationType.IN_RING, 5f);
691 weights.put(LocationType.IN_ASTEROID_FIELD, 5f);
692 weights.put(LocationType.STAR_ORBIT, 5f);
693 weights.put(LocationType.IN_SMALL_NEBULA, 5f);
694 weights.put(LocationType.L_POINT, 10f);
695 WeightedRandomPicker<EntityLocation> locs = getLocations(random, system, 100f, weights);
696
697
698 AddedEntity entity = addEntity(random, system, locs, Entities.DERELICT_CRYOSLEEPER, Factions.DERELICT);
699 if (entity != null) {
700 system.addTag(Tags.THEME_INTERESTING);
701 system.addTag(Tags.THEME_DERELICT);
702 system.addTag(Tags.THEME_DERELICT_CRYOSLEEPER);
703
704 if (name != null) {
705 entity.entity.setName(entity.entity.getName() + " \"" + name + "\"");
706 //entity.entity.setName("Cryosleeper" + "\"" + name + "\"");
707 }
708 }
709
710 if (DEBUG) {
711 if (entity != null) {
712 System.out.println(String.format(" Added cryosleeper to %s", system.getNameWithLowercaseType()));
713 } else {
714 System.out.println(String.format(" Failed to add cryosleeper to %s", system.getNameWithLowercaseType()));
715 }
716 }
717 return entity;
718 }
719
720 protected AddedEntity addSurveyShip(StarSystemAPI system) {
721 LinkedHashMap<LocationType, Float> weights = new LinkedHashMap<LocationType, Float>();
722 weights.put(LocationType.PLANET_ORBIT, 10f);
723 weights.put(LocationType.JUMP_ORBIT, 1f);
724 weights.put(LocationType.NEAR_STAR, 1f);
725 weights.put(LocationType.OUTER_SYSTEM, 5f);
726 weights.put(LocationType.IN_ASTEROID_BELT, 10f);
727 weights.put(LocationType.IN_RING, 10f);
728 weights.put(LocationType.IN_ASTEROID_FIELD, 10f);
729 weights.put(LocationType.STAR_ORBIT, 1f);
730 weights.put(LocationType.IN_SMALL_NEBULA, 1f);
731 weights.put(LocationType.L_POINT, 1f);
732 WeightedRandomPicker<EntityLocation> locs = getLocations(random, system, 100f, weights);
733
734 AddedEntity entity = addEntity(random, system, locs, Entities.DERELICT_SURVEY_SHIP, Factions.DERELICT);
735
736 if (entity != null) {
737 system.addTag(Tags.THEME_INTERESTING);
738 system.addTag(Tags.THEME_DERELICT);
739 system.addTag(Tags.THEME_DERELICT_SURVEY_SHIP);
740 }
741
742 if (DEBUG) {
743 if (entity != null) {
744 System.out.println(String.format(" Added survey ship to %s", system.getNameWithLowercaseType()));
745 } else {
746 System.out.println(String.format(" Failed to add survey ship to %s", system.getNameWithLowercaseType()));
747 }
748 }
749 return entity;
750 }
751
752 protected List<AddedEntity> addProbes(StarSystemAPI system, int num) {
753 LinkedHashMap<LocationType, Float> weights = new LinkedHashMap<LocationType, Float>();
754 weights.put(LocationType.PLANET_ORBIT, 20f);
755 weights.put(LocationType.JUMP_ORBIT, 10f);
756 weights.put(LocationType.NEAR_STAR, 10f);
757 weights.put(LocationType.OUTER_SYSTEM, 5f);
758 weights.put(LocationType.IN_ASTEROID_BELT, 5f);
759 weights.put(LocationType.IN_RING, 5f);
760 weights.put(LocationType.IN_ASTEROID_FIELD, 5f);
761 weights.put(LocationType.STAR_ORBIT, 1f);
762 weights.put(LocationType.IN_SMALL_NEBULA, 1f);
763 weights.put(LocationType.L_POINT, 1f);
764 WeightedRandomPicker<EntityLocation> locs = getLocations(random, system, 100f, weights);
765
766 List<AddedEntity> result = new ArrayList<AddedEntity>();
767 for (int i = 0; i < num; i++) {
768 AddedEntity probe = addEntity(random, system, locs, Entities.DERELICT_SURVEY_PROBE, Factions.DERELICT);
769 if (probe != null) {
770 result.add(probe);
771
772 system.addTag(Tags.THEME_INTERESTING_MINOR);
773 system.addTag(Tags.THEME_DERELICT);
774 system.addTag(Tags.THEME_DERELICT_PROBES);
775 }
776
777 if (DEBUG) {
778 if (probe != null) {
779 System.out.println(String.format(" Added probe to %s", system.getNameWithLowercaseType()));
780 } else {
781 System.out.println(String.format(" Failed to add probe to %s", system.getNameWithLowercaseType()));
782 }
783 }
784 }
785 return result;
786 }
787
788
795 protected List<Constellation> getSortedAvailableConstellations(ThemeGenContext context, boolean emptyOk, final Vector2f sortFrom, List<Constellation> exclude) {
796 List<Constellation> constellations = new ArrayList<Constellation>();
797 for (Constellation c : context.constellations) {
798 if (context.majorThemes.containsKey(c)) continue;
799 if (!emptyOk && constellationIsEmpty(c)) continue;
800
801 constellations.add(c);
802 }
803
804 if (exclude != null) {
805 constellations.removeAll(exclude);
806 }
807
808 Collections.sort(constellations, new Comparator<Constellation>() {
809 public int compare(Constellation o1, Constellation o2) {
810 float d1 = Misc.getDistance(o1.getLocation(), sortFrom);
811 float d2 = Misc.getDistance(o2.getLocation(), sortFrom);
812 return (int) Math.signum(d2 - d1);
813 }
814 });
815 return constellations;
816 }
817
818
819 public static boolean constellationIsEmpty(Constellation c) {
820 for (StarSystemAPI s : c.getSystems()) {
821 if (!systemIsEmpty(s)) return false;
822 }
823 return true;
824 }
825 public static boolean systemIsEmpty(StarSystemAPI system) {
826 for (PlanetAPI p : system.getPlanets()) {
827 if (!p.isStar()) return false;
828 }
829 //system.getTerrainCopy().isEmpty()
830 return true;
831 }
832
833
834
835
836
837
838
839
840
841// public List<AddedEntity> generateForSystem(StarSystemAPI system, SystemGenData data) {
842// if (data == null) return new ArrayList<AddedEntity>();
843//
844// LinkedHashMap<LocationType, Float> weights = new LinkedHashMap<LocationType, Float>();
845// weights.put(LocationType.PLANET_ORBIT, 1f);
846// weights.put(LocationType.JUMP_ORBIT, 1f);
847// weights.put(LocationType.NEAR_STAR, 1f);
848// weights.put(LocationType.OUTER_SYSTEM, 1f);
849// weights.put(LocationType.IN_ASTEROID_BELT, 1f);
850// weights.put(LocationType.IN_RING, 1f);
851// weights.put(LocationType.IN_ASTEROID_FIELD, 1f);
852// weights.put(LocationType.STAR_ORBIT, 1f);
853// weights.put(LocationType.IN_SMALL_NEBULA, 1f);
854// weights.put(LocationType.L_POINT, 1f);
855// WeightedRandomPicker<EntityLocation> locs = getLocations(random, system, 100f, weights);
856//
857// List<AddedEntity> result = new ArrayList<AddedEntity>();
858// for (int i = 0; i < data.numProbes; i++) {
859// AddedEntity e = addEntity(system, locs, Entities.DERELICT_SURVEY_PROBE, Factions.DERELICT);
860// if (e != null) result.add(e);
861// }
862//
863// for (int i = 0; i < data.numSurveyShips; i++) {
864// AddedEntity e = addEntity(system, locs, Entities.DERELICT_SURVEY_SHIP, Factions.DERELICT);
865// if (e != null) result.add(e);
866// }
867//
868// for (int i = 0; i < data.numMotherships; i++) {
869// AddedEntity e = addEntity(system, locs, Entities.DERELICT_MOTHERSHIP, Factions.DERELICT);
870// if (e != null) result.add(e);
871// }
872//
873//
874// return result;
875//
876// }
877
878
879
880 @Override
881 public int getOrder() {
882 return 1000;
883 }
884
885
886
887
888
889}
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
static SectorAPI getSector()
Definition Global.java:59
static AddedEntity addEntity(Random random, StarSystemAPI system, WeightedRandomPicker< EntityLocation > locs, String type, String faction)
static WeightedRandomPicker< EntityLocation > getLocations(Random random, StarSystemAPI system, float minGap, LinkedHashMap< LocationType, Float > weights)
static StarSystemAPI findNearbySystem(SectorEntityToken from, Set< StarSystemAPI > exclude, Random random, float maxRange)
List< AddedEntity > addToSystem(StarSystemAPI system, String type, int num)
static PlanetAPI findInterestingPlanet(List< StarSystemAPI > systems, Set< PlanetAPI > exclude, boolean includeKnown, boolean includeRuins, Random random)
void generateForSector(ThemeGenContext context, float allowedUnusedFraction)
List< Constellation > getSortedAvailableConstellations(ThemeGenContext context, boolean emptyOk, final Vector2f sortFrom, List< Constellation > exclude)
void linkToParent(SectorEntityToken from, SectorEntityToken parent, SpecialType type)
void linkFractionToParent(AddedEntity parent, List< AddedEntity > children, float p, SpecialType type)
List< AddedEntity > addToConstellation(Constellation c, String type, int num, boolean biggestFirst)
void linkToMothership(SectorEntityToken from, SectorEntityToken mothership)
static StarSystemAPI findNearbySystem(SectorEntityToken from, Set< StarSystemAPI > exclude)
static PlanetAPI findInterestingPlanet(List< StarSystemAPI > systems, Set< PlanetAPI > exclude)
void addMothershipChain(ThemeGenContext context, List< AddedEntity > mothershipsSoFar)
static String getInterestingCondition(PlanetAPI planet, boolean includeRuins)