1package com.fs.starfarer.api.impl.campaign.procgen.themes;
3import java.util.ArrayList;
4import java.util.Collections;
5import java.util.Comparator;
6import java.util.HashSet;
7import java.util.LinkedHashMap;
9import java.util.Random;
12import org.lwjgl.util.vector.Vector2f;
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.Commodities;
22import com.fs.starfarer.api.impl.campaign.ids.Conditions;
23import com.fs.starfarer.api.impl.campaign.ids.Entities;
24import com.fs.starfarer.api.impl.campaign.ids.Factions;
25import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
26import com.fs.starfarer.api.impl.campaign.ids.Tags;
27import com.fs.starfarer.api.impl.campaign.intel.events.ht.HTPoints;
28import com.fs.starfarer.api.impl.campaign.procgen.Constellation;
29import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator;
30import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.DomainSurveyDerelictSpecial.DomainSurveyDerelictSpecialData;
31import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.DomainSurveyDerelictSpecial.SpecialType;
32import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.SurveyDataSpecial.SurveyDataSpecialData;
33import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.SurveyDataSpecial.SurveyDataSpecialType;
34import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.TopographicDataSpecial.TopographicDataSpecialData;
35import com.fs.starfarer.api.plugins.SurveyPlugin;
36import com.fs.starfarer.api.util.Misc;
37import com.fs.starfarer.api.util.WeightedRandomPicker;
53 public static class SystemGenData {
54 public int numMotherships;
55 public int numSurveyShips;
68 if (total <= 0)
return;
72 float perChain = 1 + avg1 + (avg1 * avg2);
74 float num = total / perChain;
78 if (num > 1 && num < 2) {
81 num = Math.round(num);
84 List<AddedEntity> mothershipsSoFar =
new ArrayList<AddedEntity>();
86 for (
int i = 0; i < num; i++) {
109 boolean hasHab =
false;
110 for (
PlanetAPI planet : system.getPlanets()) {
111 if (planet.isStar())
continue;
112 if (planet.getSpec().isPulsar())
continue OUTER;
113 hasHab |= planet.getMarket() !=
null && planet.getMarket().hasCondition(
Conditions.
HABITABLE);
118 if (!hasHab || numPlanets < 3) {
132 if (cryoSystems.
isEmpty() || cryoSystems.
getItems().size() < numCryo + 1) {
133 cryoSystems.
addAll(backup);
138 cryosleeperNames.
add(
"Calypso");
139 cryosleeperNames.
add(
"Tantalus");
140 while (added < numCryo && !cryoSystems.
isEmpty()) {
152 List<AddedEntity> all =
new ArrayList<AddedEntity>();
155 Vector2f center =
new Vector2f();
156 for (AddedEntity e : mothershipsSoFar) {
157 Vector2f.add(center, e.entity.getLocationInHyperspace(), center);
159 center.scale(1f / (
float)(mothershipsSoFar.size() + 1f));
163 for (
int i = 0; i < constellations.size() / 3; i++) {
164 picker.
add(constellations.get(i));
168 if (main ==
null)
return;
174 constellations.remove(main);
179 if (mainSystem ==
null)
return;
191 if (mothership ==
null)
return;
210 SpecialType.LOCATION_MOTHERSHIP);
214 if (surveyShipsNearMothership > main.
getSystems().size()) surveyShipsNearMothership = main.
getSystems().size();
216 System.out.println(String.format(
"Adding %d survey ships near mothership", surveyShipsNearMothership));
219 all.addAll(addedShips);
222 for (AddedEntity e : addedShips) {
230 SpecialType.LOCATION_SURVEY_SHIP);
235 SpecialType.LOCATION_MOTHERSHIP);
241 for (
int i = constellations.size() - 7; i < constellations.size(); i++) {
243 picker.
add(constellations.get(i));
248 System.out.println(String.format(
"Adding up to %d survey ships", numSurveyShipsInNearConstellations));
250 List<Constellation> constellationsForSurveyShips =
new ArrayList<Constellation>();
251 for (
int i = 0; i < numSurveyShipsInNearConstellations && !picker.
isEmpty(); i++) {
254 List<AddedEntity> outerShips =
new ArrayList<AddedEntity>();
261 System.out.println(
" Picked for survey ship: [" + c.getNameWithType() +
"]");
265 if (addedShips.isEmpty())
continue;
267 all.addAll(addedShips);
269 AddedEntity ship = addedShips.get(0);
270 outerShips.addAll(addedShips);
279 SpecialType.LOCATION_SURVEY_SHIP);
282 int max = c.getSystems().size() + 2;
283 if (probesInSameConstellation > max) probesInSameConstellation = max;
290 SpecialType.LOCATION_SURVEY_SHIP);
297 for (
int i = c2.size() - 3; i < c2.size(); i++) {
299 p2.
add(constellations.get(i));
305 System.out.println(String.format(
"Adding probes to %d constellations near survey ship", probeSystemsNearShip));
307 List<AddedEntity> probes3 =
new ArrayList<AddedEntity>();
308 while (k < probeSystemsNearShip && !p2.
isEmpty()) {
319 SpecialType.LOCATION_MOTHERSHIP);
324 SpecialType.LOCATION_MOTHERSHIP);
358 Set<PlanetAPI> usedPlanets =
new HashSet<PlanetAPI>();
359 Set<StarSystemAPI> usedSystems =
new HashSet<StarSystemAPI>();
361 for (AddedEntity e : entities) {
364 SurveyDataSpecialType type =
null;
381 TopographicDataSpecialData data =
new TopographicDataSpecialData(points);
387 float pNothing = 0.1f;
398 type = SurveyDataSpecialType.PLANET_SURVEY_DATA;
404 if (type == SurveyDataSpecialType.PLANET_SURVEY_DATA) {
406 if (planet !=
null) {
407 SurveyDataSpecialData data =
new SurveyDataSpecialData(SurveyDataSpecialType.PLANET_SURVEY_DATA);
408 data.entityId = planet.
getId();
409 data.includeRuins =
false;
411 usedPlanets.add(planet);
433 if (exclude !=
null && exclude.contains(system))
continue;
436 if (dist > maxRange)
continue;
442 return picker.
pick();
447 if (planet ==
null)
return null;
453 if (conditions.contains(mc.getId())) {
476 for (
PlanetAPI planet : system.getPlanets()) {
477 if (planet.isStar())
continue;
478 if (exclude !=
null && exclude.contains(planet))
continue;
479 if (planet.getMarket() ==
null || !planet.getMarket().isPlanetConditionMarketOnly())
continue;
480 if (!includeKnown && planet.getMarket() !=
null && planet.getMarket().getSurveyLevel() == SurveyLevel.FULL) {
489 if (!(classIV || classV || planet.getMarket().getHazardValue() <= 1f))
continue;
493 if (conditions.contains(mc.getId())) {
497 if (classIV) w *= 0.5f;
499 planets.
add(planet, w);
502 return planets.
pick();
511 }
else if (planets <= 5) {
513 }
else if (planets <= 8) {
523 protected void linkFractionToParent(AddedEntity parent, List<AddedEntity> children,
float p, SpecialType type) {
526 for (AddedEntity c : children) {
532 int extraLinks = (int) Math.max(1, Math.round(children.size() * p * (1f +
StarSystemGenerator.
random.nextFloat() * 0.5f)));
533 for (
int i = 0; i < extraLinks && !picker.
isEmpty(); i++) {
552 DomainSurveyDerelictSpecialData special =
new DomainSurveyDerelictSpecialData(type);
553 special.entityId = parent.
getId();
560 DomainSurveyDerelictSpecialData special =
new DomainSurveyDerelictSpecialData(SpecialType.LOCATION_MOTHERSHIP);
561 special.entityId = mothership.
getId();
570 List<AddedEntity> result =
new ArrayList<AddedEntity>();
575 boolean first =
true;
576 for (
int i = 0; i < num; i++) {
581 if (system ==
null)
continue;
590 List<AddedEntity> result =
new ArrayList<AddedEntity>();
591 if (system ==
null)
return result;
593 for (
int i = 0; i < num; i++) {
594 AddedEntity e =
null;
612 LinkedHashMap<LocationType, Float> weights =
new LinkedHashMap<LocationType, Float>();
613 weights.put(LocationType.PLANET_ORBIT, 10f);
614 weights.put(LocationType.JUMP_ORBIT, 1f);
615 weights.put(LocationType.NEAR_STAR, 1f);
616 weights.put(LocationType.OUTER_SYSTEM, 5f);
617 weights.put(LocationType.IN_ASTEROID_BELT, 10f);
618 weights.put(LocationType.IN_RING, 10f);
619 weights.put(LocationType.IN_ASTEROID_FIELD, 10f);
620 weights.put(LocationType.STAR_ORBIT, 1f);
621 weights.put(LocationType.IN_SMALL_NEBULA, 1f);
622 weights.put(LocationType.L_POINT, 1f);
637 if (entity !=
null) {
644 if (entity !=
null) {
655 LinkedHashMap<LocationType, Float> weights =
new LinkedHashMap<LocationType, Float>();
656 weights.put(LocationType.PLANET_ORBIT, 10f);
657 weights.put(LocationType.JUMP_ORBIT, 1f);
658 weights.put(LocationType.NEAR_STAR, 1f);
659 weights.put(LocationType.OUTER_SYSTEM, 5f);
660 weights.put(LocationType.IN_ASTEROID_BELT, 5f);
661 weights.put(LocationType.IN_RING, 5f);
662 weights.put(LocationType.IN_ASTEROID_FIELD, 5f);
663 weights.put(LocationType.STAR_ORBIT, 5f);
664 weights.put(LocationType.IN_SMALL_NEBULA, 5f);
665 weights.put(LocationType.L_POINT, 10f);
670 if (entity !=
null) {
676 entity.entity.
setName(entity.entity.
getName() +
" \"" + name +
"\"");
682 if (entity !=
null) {
692 LinkedHashMap<LocationType, Float> weights =
new LinkedHashMap<LocationType, Float>();
693 weights.put(LocationType.PLANET_ORBIT, 10f);
694 weights.put(LocationType.JUMP_ORBIT, 1f);
695 weights.put(LocationType.NEAR_STAR, 1f);
696 weights.put(LocationType.OUTER_SYSTEM, 5f);
697 weights.put(LocationType.IN_ASTEROID_BELT, 10f);
698 weights.put(LocationType.IN_RING, 10f);
699 weights.put(LocationType.IN_ASTEROID_FIELD, 10f);
700 weights.put(LocationType.STAR_ORBIT, 1f);
701 weights.put(LocationType.IN_SMALL_NEBULA, 1f);
702 weights.put(LocationType.L_POINT, 1f);
707 if (entity !=
null) {
714 if (entity !=
null) {
724 LinkedHashMap<LocationType, Float> weights =
new LinkedHashMap<LocationType, Float>();
725 weights.put(LocationType.PLANET_ORBIT, 20f);
726 weights.put(LocationType.JUMP_ORBIT, 10f);
727 weights.put(LocationType.NEAR_STAR, 10f);
728 weights.put(LocationType.OUTER_SYSTEM, 5f);
729 weights.put(LocationType.IN_ASTEROID_BELT, 5f);
730 weights.put(LocationType.IN_RING, 5f);
731 weights.put(LocationType.IN_ASTEROID_FIELD, 5f);
732 weights.put(LocationType.STAR_ORBIT, 1f);
733 weights.put(LocationType.IN_SMALL_NEBULA, 1f);
734 weights.put(LocationType.L_POINT, 1f);
737 List<AddedEntity> result =
new ArrayList<AddedEntity>();
738 for (
int i = 0; i < num; i++) {
767 List<Constellation> constellations =
new ArrayList<Constellation>();
772 constellations.add(c);
775 if (exclude !=
null) {
776 constellations.removeAll(exclude);
779 Collections.sort(constellations,
new Comparator<Constellation>() {
783 return (
int) Math.signum(d2 - d1);
786 return constellations;
798 if (!p.isStar())
return false;
static SettingsAPI getSettings()
static SectorAPI getSector()
static final String SURVEY_DATA_5
static final String SURVEY_DATA_4
static final String FARMLAND_BOUNTIFUL
static final String ORGANICS_PLENTIFUL
static final String RUINS_EXTENSIVE
static final String FARMLAND_ADEQUATE
static final String ORE_ULTRARICH
static final String RARE_ORE_ULTRARICH
static final String RUINS_VAST
static final String VOLATILES_PLENTIFUL
static final String RARE_ORE_RICH
static final String HABITABLE
static final String DERELICT_MOTHERSHIP
static final String DERELICT_CRYOSLEEPER
static final String DERELICT_SURVEY_PROBE
static final String DERELICT_SURVEY_SHIP
static final String DERELICT
static final String SALVAGE_SPECIAL_DATA
List< StarSystemAPI > getSystems()
StarSystemAPI getSystemWithMostPlanets()
static float getRandom(float min, float max)
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)
static final float SALVAGE_SPECIAL_FRACTION
AddedEntity addCryosleeper(StarSystemAPI system, String name)
static Set< String > interestingConditionsWithRuins
static boolean constellationIsEmpty(Constellation c)
void generateForSector(ThemeGenContext context, float allowedUnusedFraction)
AddedEntity addMothership(StarSystemAPI system)
List< Constellation > getSortedAvailableConstellations(ThemeGenContext context, boolean emptyOk, final Vector2f sortFrom, List< Constellation > exclude)
void linkToParent(SectorEntityToken from, SectorEntityToken parent, SpecialType type)
static Set< String > interestingConditions
static final float TOPOGRAPHIC_DATA_FRACTION
static final int BRANCHES_PER_SHIP_MIN
int getNumProbesForSystem(LocationAPI system)
static final int BRANCHES_PER_SHIP_MAX
void linkFractionToParent(AddedEntity parent, List< AddedEntity > children, float p, SpecialType type)
static final float BASE_LINK_FRACTION
static Set< String > interestingConditionsWithoutHabitable
List< AddedEntity > addToConstellation(Constellation c, String type, int num, boolean biggestFirst)
static boolean hasSpecial(SectorEntityToken entity)
void linkToMothership(SectorEntityToken from, SectorEntityToken mothership)
static final int BRANCHES_PER_MOTHERSHIP_MIN
AddedEntity addSurveyShip(StarSystemAPI system)
static StarSystemAPI findNearbySystem(SectorEntityToken from, Set< StarSystemAPI > exclude)
static final int BRANCHES_PER_MOTHERSHIP_MAX
List< AddedEntity > addProbes(StarSystemAPI system, int num)
static PlanetAPI findInterestingPlanet(List< StarSystemAPI > systems, Set< PlanetAPI > exclude)
void assignRandomSpecials(List< AddedEntity > entities)
void addMothershipChain(ThemeGenContext context, List< AddedEntity > mothershipsSoFar)
static boolean systemIsEmpty(StarSystemAPI system)
static String getInterestingCondition(PlanetAPI planet, boolean includeRuins)
List< Constellation > constellations
Map< Constellation, String > majorThemes
static final String NO_THEME
static final String DERELICTS
static float getDistance(SectorEntityToken from, SectorEntityToken to)
static void setSalvageSpecial(SectorEntityToken entity, Object data)
void addAll(Collection< T > items)
Object getNewPluginInstance(String id)
List< PlanetAPI > getPlanets()
String getNameWithLowercaseType()
List< StarSystemAPI > getStarSystems()
LocationAPI getContainingLocation()
void setName(String name)
Vector2f getLocationInHyperspace()
MemoryAPI getMemoryWithoutUpdate()
List< MarketConditionAPI > getConditions()
boolean contains(String key)
void set(String key, Object value)
String getSurveyDataType(PlanetAPI planet)