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