001package com.fs.starfarer.api.impl.campaign.procgen; 002 003import com.fs.starfarer.api.campaign.SectorEntityToken; 004import com.fs.starfarer.api.campaign.StarSystemAPI; 005import com.fs.starfarer.api.impl.campaign.ids.Terrain; 006import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator.GenContext; 007import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator.GenResult; 008import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator.LagrangePointType; 009import com.fs.starfarer.api.impl.campaign.terrain.AsteroidFieldTerrainPlugin.AsteroidFieldParams; 010import com.fs.starfarer.api.util.WeightedRandomPicker; 011 012public class AsteroidFieldGenPlugin implements TerrainGenPlugin { 013 014 public static final float WIDTH_PLANET = 200f; 015 public static final float WIDTH_STAR = 400f; 016 017 public GenResult generate(TerrainGenDataSpec terrainData, GenContext context) { 018 if (context.lagrangeParent == null || context.lagrangePointType == null) return null; 019 020 //System.out.println("GENERATING L-POINT NEBULA AT " + context.star.getId()); 021 022 SectorEntityToken parent = context.center; 023 if (context.parent != null) parent = context.parent; 024 if (context.lagrangeParent != null) parent = context.center; 025 026 if (parent == null) return null; 027 028 WeightedRandomPicker<Integer> sizePicker = new WeightedRandomPicker<Integer>(StarSystemGenerator.random); 029 for (int i = 5; i <= 11; i++) { 030 sizePicker.add(i, 20 - i); 031 } 032 033 int size = sizePicker.pick(); 034 float radius = size * 100f; 035 036 float maxRadius = (context.currentRadius - parent.getRadius()) * 0.5f; 037 if (radius > maxRadius) radius = maxRadius; 038 if (radius < 400) radius = 400; 039 040 float area = radius * radius * 3.14f; 041 int count = (int) (area / 80000f); 042 if (count < 10) count = 10; 043 if (count > 100) count = 100; 044 045 046 StarSystemAPI system = context.system; 047 float orbitRadius = context.currentRadius + radius; 048 049 float orbitDays = orbitRadius / (20f + StarSystemGenerator.random.nextFloat() * 5f); 050 float angle = StarSystemGenerator.random.nextFloat() * 360f; 051 if (context.lagrangeParent != null) { 052 orbitRadius = context.lagrangeParent.orbitRadius; 053 orbitDays = context.lagrangeParent.orbitDays; 054 float angleOffset = -StarSystemGenerator.LAGRANGE_OFFSET; 055 if (context.lagrangePointType == LagrangePointType.L5) angleOffset = StarSystemGenerator.LAGRANGE_OFFSET; 056 angle = context.lagrangeParent.orbitAngle + angleOffset; 057 } 058 059 SectorEntityToken field = system.addTerrain(Terrain.ASTEROID_FIELD, 060 new AsteroidFieldParams( 061 radius, // min radius 062 radius + 100f, // max radius 063 count, // min asteroid count 064 count, // max asteroid count 065 4f, // min asteroid radius 066 16f, // max asteroid radius 067 null)); // null for default name 068 069 field.setCircularOrbit(parent, angle, orbitRadius, orbitDays); 070 071 CategoryGenDataSpec cat = context.gen.pickCategory(context, StarSystemGenerator.COL_IN_ASTEROIDS, true); 072 if (cat != null) { 073 float prevRadius = context.currentRadius; 074 WeightedRandomPicker<EntityGenDataSpec> picker = context.gen.getPickerForCategory(cat, context, 075 StarSystemGenerator.COL_IN_ASTEROIDS); 076 if (StarSystemGenerator.DEBUG) { 077 picker.print(" Picking from category " + cat.getCategory() + 078 ", orbit index " + (context.parent != null ? context.parentOrbitIndex : context.orbitIndex)); 079 } 080 EntityGenDataSpec pick = picker.pick(); 081 if (StarSystemGenerator.DEBUG) { 082 if (pick == null) { 083 System.out.println(" Nothing to pick"); 084 System.out.println(); 085 } else { 086 System.out.println(" Picked: " + pick.getId()); 087 System.out.println(); 088 } 089 } 090 if (pick instanceof PlanetGenDataSpec) { 091 PlanetGenDataSpec planetData = (PlanetGenDataSpec) pick; 092 //context.currentRadius = prevRadius + width * 0.1f + i * (width * 0.8f) / maxPlanets; 093 context.currentRadius = orbitRadius; 094 context.parentRadiusOverride = 100f / StarSystemGenerator.MOON_RADIUS_MAX_FRACTION_OF_PARENT; 095 GenResult result = context.gen.addPlanet(context, planetData, true, false); 096 if (result != null && !result.entities.isEmpty()) { 097 context.gen.getAllEntitiesAdded().put(result.entities.get(0), result.entities); 098 if (context.lagrangeParent != null && !result.entities.isEmpty()) { 099 context.gen.getLagrangeParentMap().put(result.entities.get(0), context.lagrangeParent.planet); 100 } 101 } 102 103 // not necessary to set orbit, as the lagrangeParent is set in the context so 104 // addPlanet() does it correctly 105// if (!context.generatedPlanets.isEmpty()) { 106// GeneratedPlanet last = context.generatedPlanets.get(context.generatedPlanets.size() - 1); 107// //last.planet.setRadius(last.planet.getRadius() * 0.75f); 108// last.planet.setCircularOrbit(parent, angle, orbitRadius, orbitDays); 109// } 110 } 111 context.parentRadiusOverride = -1; 112 context.currentRadius = prevRadius; 113 } 114 115 116 GenResult result = new GenResult(); 117 result.onlyIncrementByWidth = false; 118 result.orbitalWidth = radius * 2f; 119 result.entities.add(field); 120 return result; 121 } 122 123 public boolean wantsToHandle(TerrainGenDataSpec terrainData, GenContext context) { 124 return terrainData != null && terrainData.getId().equals("asteroid_field"); 125 } 126 127}