001package com.fs.starfarer.api.impl.campaign.ghosts;
002
003import java.util.List;
004import java.util.Random;
005
006import org.lwjgl.util.vector.Vector2f;
007
008import com.fs.starfarer.api.Global;
009import com.fs.starfarer.api.campaign.CampaignFleetAPI;
010import com.fs.starfarer.api.campaign.CampaignTerrainAPI;
011import com.fs.starfarer.api.campaign.LocationAPI;
012import com.fs.starfarer.api.impl.campaign.terrain.HyperspaceTerrainPlugin;
013import com.fs.starfarer.api.impl.campaign.velfield.SlipstreamTerrainPlugin2;
014import com.fs.starfarer.api.util.Misc;
015import com.fs.starfarer.api.util.WeightedRandomPicker;
016
017public class BaseSensorGhostCreator implements SensorGhostCreator {
018        
019        public List<SensorGhost> createGhost(SensorGhostManager manager) {
020                return null;
021        }
022
023        public float getFrequency(SensorGhostManager manager) {
024                return 10f;
025        }
026
027        public String getId() {
028                return getClass().getSimpleName();
029        }
030
031        public float getTimeoutDaysOnSuccessfulCreate(SensorGhostManager manager) {
032                return 10f + manager.getRandom().nextFloat() * 10f;
033        }
034        
035        
036        public static Vector2f findClearHyperspaceArea(Vector2f from, float minRange, float maxRange, float radius, Random random) {
037                return findHyperspaceArea(from, minRange, maxRange, radius, random, true, 0f);
038        }
039        public static Vector2f findDeepHyperspaceArea(Vector2f from, float minRange, float maxRange, float radius, Random random) {
040                return findHyperspaceArea(from, minRange, maxRange, radius, random, false, 0f);
041        }
042        public static Vector2f findHyperspaceArea(Vector2f from, float minRange, float maxRange, float radius, Random random, boolean clear, float noSlipstreamRange) {
043                if (random == null) random = Misc.random;
044                
045                CampaignTerrainAPI terrain = Misc.getHyperspaceTerrain();
046                if (terrain == null) return null;
047                
048                HyperspaceTerrainPlugin plugin = (HyperspaceTerrainPlugin) terrain.getPlugin();
049                
050                int[][] tiles = plugin.getTiles();
051                float perTile = plugin.getTileSize();
052                int areaSize = (int) Math.ceil(radius / perTile);
053                
054                
055                Vector2f best = null;
056                float bestScore = 0f;
057                
058                float total = (areaSize + areaSize + 1) * (areaSize + areaSize + 1);
059                if (total < 1f) total = 1f;
060                for (int k = 0; k < 20; k++) {
061                        Vector2f test = Misc.getPointWithinRadiusUniform(from, minRange, maxRange, random);
062                        int [] coords = plugin.getTile(test);
063                        if (coords == null) continue;
064                        
065                        if (noSlipstreamRange > 0) {
066                                if (Misc.isInsideSlipstream(test, noSlipstreamRange)) continue;
067                        }
068                        
069                        float count = 0f;
070                        for (int i = coords[0] - areaSize; i <= coords[0] + areaSize; i++) {
071                                if (i < 0) continue;
072                                if (i >= tiles.length) continue;
073                                for (int j = coords[1] - areaSize; j < coords[1] + areaSize; j++) {
074                                        if (j < 0) continue;
075                                        if (j >= tiles[0].length) continue;
076                                
077                                        int texIndex = tiles[i][j];
078                                        if (clear) {
079                                                if (texIndex <= 0) {
080                                                        count++;
081                                                }
082                                        } else {
083                                                if (texIndex > 0) {
084                                                        count++;
085                                                }
086                                        }
087                                }
088                        }
089                        float score = count / total;
090                        if (score >= 0.75f && score > bestScore) {
091                                best = test;
092                                bestScore = score;
093                        }
094                }
095                
096                return best;
097        }
098        
099        public static SlipstreamTerrainPlugin2 pickNearbySlipstream(float radius, Random random) {
100                return pickNearbySlipstream(radius, Global.getSector().getHyperspace(), random);
101        }
102        public static SlipstreamTerrainPlugin2 pickNearbySlipstream(float radius, LocationAPI location, Random random) {
103                WeightedRandomPicker<SlipstreamTerrainPlugin2> picker = new WeightedRandomPicker<SlipstreamTerrainPlugin2>(random);
104                CampaignFleetAPI pf = Global.getSector().getPlayerFleet();
105                Vector2f loc = pf.getLocation();
106                
107                for (CampaignTerrainAPI ter : location.getTerrainCopy()) {
108                        if (ter.getPlugin() instanceof SlipstreamTerrainPlugin2) {
109                                SlipstreamTerrainPlugin2 plugin = (SlipstreamTerrainPlugin2) ter.getPlugin();
110                                if (plugin.containsPoint(loc, radius)) {
111                                        float w = 1f;
112                                        if (plugin.isPreventedFromAffecting(pf)) {
113                                                w *= 0.25f; // more likely to pick the slipstream the player is in, if there is one
114                                        }
115                                        picker.add(plugin, w);
116                                }
117                        }
118                }
119                return picker.pick();
120        }
121        
122        // moved to Misc
123//      public static boolean isInsideSlipstream(Vector2f loc, float radius) {
124//              return isInsideSlipstream(loc, radius, Global.getSector().getHyperspace());
125//      }
126//      public static boolean isInsideSlipstream(Vector2f loc, float radius, LocationAPI location) {
127//              for (CampaignTerrainAPI ter : location.getTerrainCopy()) {
128//                      if (ter.getPlugin() instanceof SlipstreamTerrainPlugin2) {
129//                              SlipstreamTerrainPlugin2 plugin = (SlipstreamTerrainPlugin2) ter.getPlugin();
130//                              if (plugin.containsPoint(loc, radius)) {
131//                                      return true;
132//                              }
133//                      }
134//              }
135//              return false;
136//      }
137
138        public boolean canSpawnWhilePlayerInOrNearSlipstream() {
139                return false;
140        }
141        
142        public boolean canSpawnWhilePlayerInAbyss() {
143                return false;
144        }
145
146        public boolean canSpawnWhilePlayerOutsideAbyss() {
147                return true;
148        }
149}
150
151
152
153
154
155