001package com.fs.starfarer.api.impl.campaign.procgen;
002
003import java.awt.Color;
004import java.util.ArrayList;
005import java.util.List;
006
007import com.fs.starfarer.api.campaign.CampaignTerrainAPI;
008import com.fs.starfarer.api.campaign.RingBandAPI;
009import com.fs.starfarer.api.campaign.SectorEntityToken;
010import com.fs.starfarer.api.campaign.StarSystemAPI;
011import com.fs.starfarer.api.impl.campaign.ids.Tags;
012import com.fs.starfarer.api.impl.campaign.ids.Terrain;
013import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator.GenContext;
014import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator.GenResult;
015import com.fs.starfarer.api.impl.campaign.terrain.RingSystemTerrainPlugin;
016import com.fs.starfarer.api.impl.campaign.terrain.BaseRingTerrain.RingParams;
017import com.fs.starfarer.api.util.WeightedRandomPicker;
018
019public class AccretionDiskGenPlugin implements TerrainGenPlugin {
020        
021        public static class TexAndIndex {
022                public String tex;
023                public int index;
024        }
025        
026        protected TexAndIndex getTexAndIndex(TerrainGenDataSpec data) {
027                TexAndIndex result = new TexAndIndex();
028                WeightedRandomPicker<Integer> indexPicker = new WeightedRandomPicker<Integer>(StarSystemGenerator.random);
029                
030                WeightedRandomPicker<String> ringSet = new WeightedRandomPicker<String>(StarSystemGenerator.random);
031                ringSet.add("ring_ice", 10f);
032                ringSet.add("ring_dust", 10f);
033                //ringSet.add("ring_special", 1f);
034                
035                String set = ringSet.pick();
036                
037                if (set.equals("ring_ice")) {
038                        result.tex = "rings_ice0";
039                        indexPicker.add(0);
040                        indexPicker.add(1);
041                } else if (set.equals("ring_dust")) {
042                        result.tex = "rings_dust0";
043                        indexPicker.add(0);
044                        indexPicker.add(1);
045                }
046                
047                result.index = indexPicker.pick();
048                
049                return result;
050        }
051        
052        
053        public GenResult generate(TerrainGenDataSpec terrainData, GenContext context) {
054                StarSystemAPI system = context.system;
055                SectorEntityToken parent = context.center;
056                if (context.parent != null) parent = context.parent;
057                
058                //float orbitRadius = context.currentRadius * (2f + 2f * StarSystemGenerator.random.nextFloat());
059                ///float orbitRadius = context.currentRadius * (2f + 2f * StarSystemGenerator.random.nextFloat());
060                float orbitRadius = context.currentRadius * (2f + 1f * StarSystemGenerator.random.nextFloat());
061                
062                float bandWidth = 256f;
063
064                //int numBands = (int) (2f + StarSystemGenerator.random.nextFloat() * 5f);
065                int numBands = 8;
066                
067                float spiralFactor = 3f + StarSystemGenerator.random.nextFloat() * 2f;
068                numBands += (int) spiralFactor;
069                
070                numBands = 12;
071//              boolean leaveRoomInMiddle = context.system.getStar() != null && 
072//                                                                      parent == context.system.getCenter() &&
073//                                                                      Misc.getDistance(context.system.getStar().getLocation(), parent.getLocation()) > 100;
074                for (float i = 0; i < numBands; i++) {
075//                      float radiusMult = 0.25f + 0.75f * (i + 1f) / (numBands);
076//                      radiusMult = 1f;
077                        //float radius = orbitRadius * radiusMult;
078                        float radius = orbitRadius - i * bandWidth * 0.25f - i * bandWidth * 0.1f;
079                        //float radius = orbitRadius - i * bandWidth / 2;
080                        
081                        TexAndIndex tex = getTexAndIndex(terrainData);
082                        float orbitDays = radius / (30f + 10f * StarSystemGenerator.random.nextFloat());
083                        Color color = StarSystemGenerator.getColor(terrainData.getMinColor(), terrainData.getMaxColor());
084                        //color = Color.white; 
085                        RingBandAPI visual = system.addRingBand(parent, "misc", tex.tex, 256f, tex.index, color, bandWidth,
086                                                                                                        radius + bandWidth / 2f, -orbitDays);
087                        
088                        spiralFactor = 2f + StarSystemGenerator.random.nextFloat() * 5f;
089                        visual.setSpiral(true);
090                        visual.setMinSpiralRadius(0);
091                        visual.setSpiralFactor(spiralFactor);
092                }
093        
094                
095                List<SectorEntityToken> rings = new ArrayList<SectorEntityToken>();
096                SectorEntityToken ring = system.addTerrain(Terrain.RING, new RingParams(orbitRadius, orbitRadius / 2f, parent, null));
097                ring.addTag(Tags.ACCRETION_DISK);
098                if (((CampaignTerrainAPI)ring).getPlugin() instanceof RingSystemTerrainPlugin) {
099                        ((RingSystemTerrainPlugin)((CampaignTerrainAPI)ring).getPlugin()).setNameForTooltip("Accretion Disk");
100                }
101                
102                ring.setCircularOrbit(parent, 0, 0, -100);
103                
104                rings.add(ring);
105                
106                GenResult result = new GenResult();
107                result.onlyIncrementByWidth = false;
108                result.orbitalWidth = orbitRadius;
109                result.entities.addAll(rings); 
110                return result;
111        }
112
113        public boolean wantsToHandle(TerrainGenDataSpec terrainData, GenContext context) {
114                return terrainData != null && (terrainData.getId().equals("accretion_disk"));
115        }
116
117}