1package com.fs.starfarer.api.impl.campaign.procgen.themes;
4import java.util.ArrayList;
5import java.util.Collections;
6import java.util.Comparator;
9import org.lwjgl.util.vector.Vector2f;
11import com.fs.starfarer.api.Global;
12import com.fs.starfarer.api.campaign.AICoreOfficerPlugin;
13import com.fs.starfarer.api.campaign.CampaignFleetAPI;
14import com.fs.starfarer.api.campaign.CargoAPI;
15import com.fs.starfarer.api.campaign.CustomCampaignEntityAPI;
16import com.fs.starfarer.api.campaign.InteractionDialogAPI;
17import com.fs.starfarer.api.campaign.JumpPointAPI;
18import com.fs.starfarer.api.campaign.JumpPointAPI.JumpDestination;
19import com.fs.starfarer.api.campaign.OrbitAPI;
20import com.fs.starfarer.api.campaign.PlanetAPI;
21import com.fs.starfarer.api.campaign.SectorEntityToken;
22import com.fs.starfarer.api.campaign.StarSystemAPI;
23import com.fs.starfarer.api.characters.PersonAPI;
24import com.fs.starfarer.api.combat.BattleCreationContext;
25import com.fs.starfarer.api.fleet.FleetMemberAPI;
26import com.fs.starfarer.api.fleet.FleetMemberType;
27import com.fs.starfarer.api.impl.campaign.FleetEncounterContext;
28import com.fs.starfarer.api.impl.campaign.FleetInteractionDialogPluginImpl.BaseFIDDelegate;
29import com.fs.starfarer.api.impl.campaign.FleetInteractionDialogPluginImpl.FIDConfig;
30import com.fs.starfarer.api.impl.campaign.FleetInteractionDialogPluginImpl.FIDConfigGen;
31import com.fs.starfarer.api.impl.campaign.fleets.FleetFactoryV3;
32import com.fs.starfarer.api.impl.campaign.ids.Abilities;
33import com.fs.starfarer.api.impl.campaign.ids.Commodities;
34import com.fs.starfarer.api.impl.campaign.ids.Entities;
35import com.fs.starfarer.api.impl.campaign.ids.Factions;
36import com.fs.starfarer.api.impl.campaign.ids.FleetTypes;
37import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
38import com.fs.starfarer.api.impl.campaign.ids.Tags;
39import com.fs.starfarer.api.impl.campaign.procgen.Constellation;
40import com.fs.starfarer.api.impl.campaign.procgen.DefenderDataOverride;
41import com.fs.starfarer.api.impl.campaign.procgen.NameAssigner;
42import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator;
43import com.fs.starfarer.api.impl.campaign.procgen.themes.RemnantSeededFleetManager.RemnantFleetInteractionConfigGen;
44import com.fs.starfarer.api.impl.campaign.procgen.themes.SalvageSpecialAssigner.SpecialCreationContext;
45import com.fs.starfarer.api.util.Misc;
46import com.fs.starfarer.api.util.WeightedRandomPicker;
51 public static enum RemnantSystemType {
58 private String beaconFlag;
59 private RemnantSystemType(String tag, String beaconFlag) {
61 this.beaconFlag = beaconFlag;
63 public String getTag() {
66 public String getBeaconFlag() {
86 if (total <= 0)
return;
90 if (num > total) num = (int) total;
93 int numDestroyed = (int) (num * (0.23f + 0.1f *
random.nextFloat()));
94 if (numDestroyed < 1) numDestroyed = 1;
95 int numSuppressed = (int) (num * (0.23f + 0.1f *
random.nextFloat()));
96 if (numSuppressed < 1) numSuppressed = 1;
98 float suppressedStationMult = 0.5f;
99 int suppressedStations = (int) Math.ceil(numSuppressed * suppressedStationMult);
102 for (
int i = 0; i < numSuppressed; i++) {
103 if (i < suppressedStations) {
104 addSuppressedStation.
add(
true, 1f);
106 addSuppressedStation.
add(
false, 1f);
111 Collections.reverse(constellations);
114 if (total < num / (1f - skipProb)) {
115 skipProb = 1f - (num / total);
119 List<StarSystemData> remnantSystems =
new ArrayList<StarSystemData>();
121 if (
DEBUG) System.out.println(
"\n\n\n");
122 if (
DEBUG) System.out.println(
"Generating remnant systems");
127 for (
int i = 0; i < num && i < constellations.size(); i++) {
129 if (
random.nextFloat() < skipProb) {
130 if (
DEBUG) System.out.println(
"Skipping constellation " + c.
getName());
135 List<StarSystemData> systems =
new ArrayList<StarSystemData>();
143 int numMain = 1 +
random.nextInt(2);
144 if (numMain > mainCandidates.size()) numMain = mainCandidates.size();
146 if (
DEBUG) System.out.println(
"Skipping constellation " + c.
getName() +
", no suitable main candidates");
150 RemnantSystemType type = RemnantSystemType.RESURGENT;
151 if (numUsed < numDestroyed) {
152 type = RemnantSystemType.DESTROYED;
153 }
else if (numUsed < numDestroyed + numSuppressed) {
154 type = RemnantSystemType.SUPPRESSED;
163 if (
DEBUG) System.out.println(
"Generating " + numMain +
" main systems in " + c.
getName());
164 for (
int j = 0; j < numMain; j++) {
165 StarSystemData data = mainCandidates.get(j);
170 if (type != RemnantSystemType.DESTROYED) {
174 data.system.
addTag(type.getTag());
175 remnantSystems.add(data);
182 if (type == RemnantSystemType.DESTROYED) {
185 }
else if (type == RemnantSystemType.SUPPRESSED) {
194 int maxFleets = 2 +
random.nextInt(3);
196 station, 1f, 0, maxFleets, 25f, 6, 12);
201 }
else if (type == RemnantSystemType.RESURGENT) {
204 int maxFleets = 8 +
random.nextInt(5);
206 station, 1f, 0, maxFleets, 15f, 8, 24);
212 for (StarSystemData data : systems) {
213 int index = mainCandidates.indexOf(data);
214 if (index >= 0 && index < numMain)
continue;
218 if (type == RemnantSystemType.DESTROYED) {
226 data.system.addTag(type.getTag());
227 remnantSystems.add(data);
229 if (
random.nextFloat() < 0.5f) {
231 data.system.addScript(fleets);
243 SpecialCreationContext specialContext =
new SpecialCreationContext();
249 if (
DEBUG) System.out.println(
"Finished generating remnant systems\n\n\n\n\n");
256 for (StarSystemData data : systemData) {
268 for (AddedEntity added : data.generated) {
269 if (added.entityType ==
null)
continue;
295 if (min < 1) min = 1;
296 if (max < 1) max = 1;
298 if (
random.nextFloat() < prob) {
308 if (
DEBUG) System.out.println(
" Generating secondary remnant system in " + data.system.
getName());
309 boolean special = data.isBlackHole() || data.isNebula() || data.isPulsar();
314 if (
random.nextFloat() < 0.5f)
return;
316 if (!data.resourceRich.isEmpty()) {
320 if (!special && !data.habitable.isEmpty()) {
347 public void populateMain(StarSystemData data, RemnantSystemType type) {
349 if (
DEBUG) System.out.println(
" Generating remnant center in " + data.system.
getName());
355 if (
DEBUG) System.out.println(
" Added warning beacon");
357 int maxHabCenters = 1 +
random.nextInt(3);
359 HabitationLevel level = HabitationLevel.LOW;
360 if (maxHabCenters == 2) level = HabitationLevel.MEDIUM;
361 if (maxHabCenters >= 3) level = HabitationLevel.HIGH;
367 float probRelay = 1f;
368 float probMining = 0.5f;
369 float probResearch = 0.25f;
426 List<StarSystemData> result =
new ArrayList<StarSystemData>();
428 for (StarSystemData data : systems) {
429 if (data.isBlackHole() || data.isNebula() || data.isPulsar())
continue;
431 if (data.planets.size() >= 3 || data.habitable.size() >= 1) {
442 Collections.sort(systems,
new Comparator<StarSystemData>() {
443 public int compare(StarSystemData o1, StarSystemData o2) {
446 return (
int) Math.signum(s2 - s1);
455 total += data.planets.size() * 1f;
456 total += data.habitable.size() * 2f;
457 total += data.resourceRich.size() * 0.25f;
467 float minRange = 600;
469 float closestRange = Float.MAX_VALUE;
480 if (dist < minRange + point.
getRadius())
continue;
482 if (dist < closestRange) {
483 closestPoint = point;
498 if (closestPoint ==
null) {
505 float radius = closestRange;
507 if (closestPoint.
getOrbit() !=
null) {
515 beaconLoc.scale(radius);
516 Vector2f.add(beaconLoc, anchor.
getLocation(), beaconLoc);
521 Color glowColor =
new Color(255,200,0,255);
522 Color pingColor =
new Color(255,200,0,255);
523 if (type == RemnantSystemType.SUPPRESSED) {
524 glowColor =
new Color(250,155,0,255);
525 pingColor =
new Color(250,155,0,255);
526 }
else if (type == RemnantSystemType.RESURGENT) {
527 glowColor =
new Color(250,55,0,255);
528 pingColor =
new Color(250,125,0,255);
557 List<Constellation> constellations =
new ArrayList<Constellation>();
562 constellations.add(c);
565 if (exclude !=
null) {
566 constellations.removeAll(exclude);
569 Collections.sort(constellations,
new Comparator<Constellation>() {
573 return (
int) Math.signum(d2 - d1);
576 return constellations;
588 if (!p.isStar())
return false;
596 public List<CampaignFleetAPI>
addBattlestations(StarSystemData data,
float chanceToAddAny,
int min,
int max,
598 List<CampaignFleetAPI> result =
new ArrayList<CampaignFleetAPI>();
599 if (
random.nextFloat() >= chanceToAddAny)
return result;
601 int num = min +
random.nextInt(max - min + 1);
602 if (
DEBUG) System.out.println(
" Adding " + num +
" battlestations");
603 for (
int i = 0; i < num; i++) {
607 String type = stationTypes.
pick();
638 boolean damaged = type.toLowerCase().contains(
"damaged");
681 new RemnantStationInteractionConfigGen());
691 public static class RemnantStationInteractionConfigGen
implements FIDConfigGen {
692 public FIDConfig createConfig() {
693 FIDConfig config =
new FIDConfig();
695 config.alwaysAttackVsAttack =
true;
696 config.leaveAlwaysAvailable =
true;
697 config.showFleetAttitude =
false;
698 config.showTransponderStatus =
false;
699 config.showEngageText =
false;
702 config.delegate =
new BaseFIDDelegate() {
704 new RemnantFleetInteractionConfigGen().createConfig().delegate.
705 postPlayerSalvageGeneration(dialog, context, salvage);
710 bcc.aiRetreatAllowed =
false;
711 bcc.objectivesAllowed =
false;
static FactoryAPI getFactory()
static SectorAPI getSector()
void modifyFlat(String source, float value)
static CampaignFleetAPI createEmptyFleet(String factionId, String fleetType, MarketAPI market)
static final String TRANSPONDER
static final String ALPHA_CORE
static final String ORBITAL_HABITAT_REMNANT
static final String WEAPONS_CACHE_REMNANT
static final String WARNING_BEACON
static final String WEAPONS_CACHE_SMALL_REMNANT
static final String EQUIPMENT_CACHE_SMALL
static final String EQUIPMENT_CACHE
static final String SUPPLY_CACHE_SMALL
static final String WRECK
static final String STATION_RESEARCH_REMNANT
static final String SUPPLY_CACHE
static final String STATION_MINING_REMNANT
static final String TRITACHYON
static final String HEGEMONY
static final String NEUTRAL
static final String REMNANTS
static final String INDEPENDENT
static final String BATTLESTATION
static final String MEMORY_KEY_NO_JUMP
static final String FLEET_INTERACTION_DIALOG_CONFIG_OVERRIDE_GEN
static final String MEMORY_KEY_MAKE_ALLOW_DISENGAGE
static final String MEMORY_KEY_MAKE_AGGRESSIVE
List< StarSystemAPI > getSystems()
static boolean isNameSpecial(StarSystemAPI system)
void assignSpecialNames(NamingTreeNode curr)
static float getNormalRandom(float min, float max)
void addShipGraveyard(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker< String > factions)
static StarSystemData computeSystemData(StarSystemAPI system)
static AddedEntity setEntityLocation(SectorEntityToken entity, EntityLocation loc, String type)
static EntityLocation pickCommonLocation(Random random, StarSystemAPI system, float gap, boolean allowStarOrbit, Set< SectorEntityToken > exclude)
void addResearchStations(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker< String > stationTypes)
List< AddedEntity > addObjectives(StarSystemData data, float prob)
void addCaches(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker< String > cacheTypes)
void addDerelictShips(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker< String > factions)
static void convertOrbitWithSpin(SectorEntityToken entity, float spin)
AddedEntity addInactiveGate(StarSystemData data, float prob, float probDebris, float probShips, WeightedRandomPicker< String > factions)
WeightedRandomPicker< String > createStringPicker(Object ... params)
void addHabCenters(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker< String > stationTypes)
void addDebrisFields(StarSystemData data, float chanceToAddAny, int min, int max)
AddedEntity addStation(EntityLocation loc, StarSystemData data, String customEntityId, String factionId)
void addMiningStations(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker< String > stationTypes)
static void addCommanderSkills(PersonAPI commander, CampaignFleetAPI fleet, FleetParamsV3 params, int numSkills, Random random)
static void integrateAndAdaptCoreForAIFleet(FleetMemberAPI member)
static final int MAX_CONSTELLATIONS_WITH_REMNANTS
static float CONSTELLATION_SKIP_PROB
static boolean systemIsEmpty(StarSystemAPI system)
float getMainCenterScore(StarSystemData data)
void generateForSector(ThemeGenContext context, float allowedUnusedFraction)
List< StarSystemData > getSortedSystemsSuitedToBePopulated(List< StarSystemData > systems)
void addDefenders(List< StarSystemData > systemData)
static void addRemnantStationInteractionConfig(CampaignFleetAPI fleet)
List< CampaignFleetAPI > addBattlestations(StarSystemData data, float chanceToAddAny, int min, int max, WeightedRandomPicker< String > stationTypes)
static final int MIN_CONSTELLATIONS_WITH_REMNANTS
static boolean constellationIsEmpty(Constellation c)
void populateMain(StarSystemData data, RemnantSystemType type)
List< Constellation > getSortedAvailableConstellations(ThemeGenContext context, boolean emptyOk, final Vector2f sortFrom, List< Constellation > exclude)
void populateNonMain(StarSystemData data)
static CustomCampaignEntityAPI addBeacon(StarSystemAPI system, RemnantSystemType type)
static void assignSpecials(SectorEntityToken entity)
List< Constellation > constellations
Map< Constellation, String > majorThemes
static final String REMNANTS
static void setDefenderOverride(SectorEntityToken entity, DefenderDataOverride override)
static void setWarningBeaconColors(SectorEntityToken beacon, Color glow, Color ping)
static AICoreOfficerPlugin getAICoreOfficerPlugin(String commodityId)
static Vector2f getUnitVectorAtDegreeAngle(float degrees)
static float getDistance(SectorEntityToken from, SectorEntityToken to)
static float getAngleInDegrees(Vector2f v)
OrbitAPI createCircularOrbitPointingDown(SectorEntityToken focus, float angle, float orbitRadius, float orbitDays)
FleetMemberAPI createFleetMember(FleetMemberType type, String variantOrWingId)
PersonAPI createPerson(String aiCoreId, String factionId, Random random)
void setName(String name)
void setStationMode(Boolean stationMode)
void setCommander(PersonAPI commander)
FleetMemberAPI getFlagship()
void setAI(CampaignFleetAIAPI campaignFleetAI)
FleetDataAPI getFleetData()
void addFleetMember(FleetMemberAPI member)
List< JumpDestination > getDestinations()
List getEntities(Class implementedClassOrInterface)
void addScript(EveryFrameScript script)
List< PlanetAPI > getPlanets()
void addEntity(SectorEntityToken entity)
CustomCampaignEntityAPI addCustomEntity(String id, String name, String type, String factionId)
LocationAPI getHyperspace()
LocationAPI getContainingLocation()
StatBonus getDetectedRangeMod()
void setCircularOrbitPointingDown(SectorEntityToken focus, float angle, float orbitRadius, float orbitDays)
void setOrbit(OrbitAPI orbit)
MemoryAPI getMemoryWithoutUpdate()
AbilityPlugin getAbility(String id)
void addAbility(String id)
SectorEntityToken getHyperspaceAnchor()
void set(String key, Object value)
void setCaptain(PersonAPI commander)
RepairTrackerAPI getRepairTracker()