001package com.fs.starfarer.api.impl.campaign.fleets;
002
003import org.lwjgl.util.vector.Vector2f;
004
005import com.fs.starfarer.api.Global;
006import com.fs.starfarer.api.campaign.CampaignFleetAPI;
007import com.fs.starfarer.api.campaign.FleetAssignment;
008import com.fs.starfarer.api.campaign.LocationAPI;
009import com.fs.starfarer.api.campaign.SectorEntityToken;
010import com.fs.starfarer.api.campaign.StarSystemAPI;
011import com.fs.starfarer.api.campaign.econ.MarketAPI;
012import com.fs.starfarer.api.impl.campaign.fleets.FleetFactory.MercType;
013import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteData;
014import com.fs.starfarer.api.impl.campaign.ids.Factions;
015import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
016import com.fs.starfarer.api.impl.campaign.ids.Tags;
017import com.fs.starfarer.api.util.Misc;
018import com.fs.starfarer.api.util.WeightedRandomPicker;
019
020/**
021 * Unused.
022 * @author Alex Mosolov
023 *
024 * Copyright 2018 Fractal Softworks, LLC
025 */
026public class PirateFleetManager extends BaseLimitedFleetManager {
027
028        @Override
029        protected int getMaxFleets() {
030                return (int) Global.getSettings().getFloat("maxPirateFleets");
031        }
032
033        @Override
034        protected CampaignFleetAPI spawnFleet() {
035                StarSystemAPI target = pickTargetSystem();
036                if (target == null || true) return null;
037                
038                WeightedRandomPicker<MercType> picker = new WeightedRandomPicker<MercType>();
039                picker.add(MercType.SCOUT, 10f); 
040                picker.add(MercType.BOUNTY_HUNTER, 10f); 
041                picker.add(MercType.PRIVATEER, 10f); 
042                picker.add(MercType.PATROL, 10f); 
043                picker.add(MercType.ARMADA, 3f); 
044                
045                MercType type = picker.pick();
046                
047                
048                float combat = 0f;
049                float tanker = 0f;
050                float freighter = 0f;
051                String fleetType = type.fleetType;
052                switch (type) {
053                case SCOUT:
054                        combat = Math.round(1f + (float) Math.random() * 2f);
055                        break;
056                case PRIVATEER:
057                case BOUNTY_HUNTER:
058                        combat = Math.round(3f + (float) Math.random() * 2f);
059                        break;
060                case PATROL:
061                        combat = Math.round(9f + (float) Math.random() * 3f);
062                        break;
063                case ARMADA:
064                        combat = Math.round(12f + (float) Math.random() * 8f);
065                        break;
066                }
067                
068                FleetParamsV3 params = new FleetParamsV3(
069                                null, 
070                                target.getLocation(),
071                                Factions.PIRATES, // quality will always be reduced by non-market-faction penalty, which is what we want 
072                                null,
073                                fleetType,
074                                combat, // combatPts
075                                freighter, // freighterPts 
076                                tanker, // tankerPts
077                                0f, // transportPts
078                                0f, // linerPts
079                                0f, // utilityPts
080                                0f // qualityMod
081                                );
082//              if (route != null) {
083//                      params.timestamp = route.getTimestamp();
084//              }
085                //params.random = random;
086                CampaignFleetAPI fleet = FleetFactoryV3.createFleet(params);
087                if (fleet == null || fleet.isEmpty()) return null;
088                
089                
090                fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_PIRATE, true);
091                
092                MarketAPI source = Misc.getSourceMarket(fleet);
093                if (source == null) return null;
094                
095                CampaignFleetAPI player = Global.getSector().getPlayerFleet();
096                boolean spawnAtSource = true;
097                if (player != null) {
098                        float sourceToPlayer = Misc.getDistance(player.getLocation(), source.getLocationInHyperspace());
099                        float targetToPlayer = Misc.getDistance(player.getLocation(), target.getLocation());
100                        spawnAtSource = sourceToPlayer < targetToPlayer;
101                }
102                
103                if (spawnAtSource) {
104                        source.getPrimaryEntity().getContainingLocation().addEntity(fleet);
105                        fleet.setLocation(source.getPrimaryEntity().getLocation().x, source.getPrimaryEntity().getLocation().y);
106                        
107                        fleet.addAssignment(FleetAssignment.ORBIT_AGGRESSIVE, source.getPrimaryEntity(), 2f + (float) Math.random() * 2f,
108                                                                "orbiting " + source.getName());
109                } else {
110                        Vector2f loc = Misc.pickHyperLocationNotNearPlayer(target.getLocation(), Global.getSettings().getMaxSensorRangeHyper() + 500f);
111                        Global.getSector().getHyperspace().addEntity(fleet);
112                        fleet.setLocation(loc.x, loc.y);
113                }
114                
115                
116                Vector2f dest = Misc.getPointAtRadius(target.getLocation(), 1500);
117                LocationAPI hyper = Global.getSector().getHyperspace();
118                SectorEntityToken token = hyper.createToken(dest.x, dest.y);
119                
120                fleet.addAssignment(FleetAssignment.GO_TO_LOCATION, token, 1000,
121                                "traveling to the " + target.getBaseName() + " star system");
122
123                if ((float) Math.random() > 0.75f) {
124                        fleet.addAssignment(FleetAssignment.RAID_SYSTEM, target.getHyperspaceAnchor(), 20,
125                                        "raiding around the " + target.getBaseName() + " star system");
126                } else {
127                        fleet.addAssignment(FleetAssignment.RAID_SYSTEM, target.getCenter(), 20,
128                                        "raiding the " + target.getBaseName() + " star system");
129                }
130                fleet.addAssignment(FleetAssignment.GO_TO_LOCATION, source.getPrimaryEntity(), 1000,
131                                        "returning to " + source.getName());
132                fleet.addAssignment(FleetAssignment.ORBIT_PASSIVE, source.getPrimaryEntity(), 2f + 2f * (float) Math.random(),
133                                        "offloading ill-gotten goods");
134                fleet.addAssignment(FleetAssignment.GO_TO_LOCATION_AND_DESPAWN, source.getPrimaryEntity(), 1000);
135                
136                return fleet;
137        }
138
139        
140        protected StarSystemAPI pickTargetSystem() {
141                WeightedRandomPicker<StarSystemAPI> picker = new WeightedRandomPicker<StarSystemAPI>();
142                for (StarSystemAPI system : Global.getSector().getStarSystems()) {
143                        float mult = Misc.getSpawnChanceMult(system.getLocation());
144                        
145                        if (system.hasTag(Tags.SYSTEM_CUT_OFF_FROM_HYPER)) {
146                                continue;
147                        }
148                        
149                        // want: large, unstable
150                        float weight = 0f;
151                        float bounties = 0;
152                        for (MarketAPI market : Misc.getMarketsInLocation(system)) {
153                                if (market.getFactionId().equals(Factions.PIRATES)) continue;
154                                //weight += market.getSize() * (15f - market.getStabilityValue());
155                                float w = 11f - market.getStabilityValue() + market.getSize();
156                                if (w > weight) weight = w;
157//                              if (market.hasCondition(Conditions.EVENT_SYSTEM_BOUNTY)) {
158//                                      bounties++;
159//                              }
160                        }
161                        
162                        weight *= (bounties + 1);
163                        weight *= mult;
164                        
165                        picker.add(system, weight);
166                }
167                return picker.pick();
168        }
169
170        
171        public static CampaignFleetAPI createPirateFleet(int combatPoints, RouteData route, Vector2f locInHyper) {
172                float combat = combatPoints;
173                float tanker = 0f;
174                float freighter = 0f;
175                
176                MercType type = MercType.SCOUT;
177                if (combat >= 18f) type = MercType.ARMADA;
178                if (combat >= 12f) type = MercType.PATROL;
179                if (combat >= 6f) {
180                        if ((float) Math.random() < 0.5f) {
181                                type = MercType.PRIVATEER;
182                        } else {
183                                type = MercType.BOUNTY_HUNTER;
184                        }
185                }
186                
187                combat *= 5f;
188                
189                String fleetType = type.fleetType;
190                
191                FleetParamsV3 params = new FleetParamsV3(
192                                route != null ? route.getMarket() : null, 
193                                locInHyper,
194                                Factions.PIRATES, // quality will always be reduced by non-market-faction penalty, which is what we want 
195                                route != null ? route.getQualityOverride() : null,
196                                fleetType,
197                                combat, // combatPts
198                                freighter, // freighterPts 
199                                tanker, // tankerPts
200                                0f, // transportPts
201                                0f, // linerPts
202                                0f, // utilityPts
203                                0f // qualityMod
204                                );
205                if (route != null) {
206                        params.timestamp = route.getTimestamp();
207                }
208                //params.random = random;
209                CampaignFleetAPI fleet = FleetFactoryV3.createFleet(params);
210                
211                if (fleet == null || fleet.isEmpty()) return null;
212                
213                fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_PIRATE, true);
214                fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_ALLOW_LONG_PURSUIT, true);
215                
216                MarketAPI source = Misc.getSourceMarket(fleet);
217                if (source == null) return null;
218                
219                return fleet;
220        }
221}
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236