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}