Starsector API
Loading...
Searching...
No Matches
PlayerRelatedPirateBaseManager.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.intel.bases;
2
3import java.util.ArrayList;
4import java.util.Iterator;
5import java.util.LinkedHashSet;
6import java.util.List;
7import java.util.Random;
8import java.util.Set;
9
10import com.fs.starfarer.api.EveryFrameScript;
11import com.fs.starfarer.api.Global;
12import com.fs.starfarer.api.campaign.FactionAPI;
13import com.fs.starfarer.api.campaign.StarSystemAPI;
14import com.fs.starfarer.api.campaign.econ.MarketAPI;
15import com.fs.starfarer.api.impl.campaign.DebugFlags;
16import com.fs.starfarer.api.impl.campaign.ids.Conditions;
17import com.fs.starfarer.api.impl.campaign.ids.Factions;
18import com.fs.starfarer.api.impl.campaign.ids.Tags;
19import com.fs.starfarer.api.impl.campaign.intel.bases.PirateBaseIntel.PirateBaseTier;
20import com.fs.starfarer.api.impl.campaign.intel.events.PiracyRespiteScript;
21import com.fs.starfarer.api.util.IntervalUtil;
22import com.fs.starfarer.api.util.Misc;
23import com.fs.starfarer.api.util.WeightedRandomPicker;
24
26
27 public static final String KEY = "$core_PR_pirateBaseManager";
28
29
30 //public static int MIN_MONTHS_BEFORE_RAID = Global.getSettings().getInt("minMonthsBeforeFirstPirateRaidOnPlayerColony");
31
32 public static int MIN_TIMEOUT = Global.getSettings().getIntFromArray("playerRelatedPirateBaseCreationTimeoutMonths", 0);
33 public static int MAX_TIMEOUT = Global.getSettings().getIntFromArray("playerRelatedPirateBaseCreationTimeoutMonths", 1);
34
35 public static int MIN_TIMEOUT_DESTROYED = Global.getSettings().getIntFromArray("playerRelatedPirateBaseCreationTimeoutExtraAfterBaseDestroyed", 0);
36 public static int MAX_TIMEOUT_DESTROYED = Global.getSettings().getIntFromArray("playerRelatedPirateBaseCreationTimeoutExtraAfterBaseDestroyed", 1);
37
38
40 Object test = Global.getSector().getMemoryWithoutUpdate().get(KEY);
41 return (PlayerRelatedPirateBaseManager) test;
42 }
43
44
45 protected long start = 0;
46 //protected boolean sentFirstRaid = false;
47 protected IntervalUtil monthlyInterval = new IntervalUtil(20f, 40f);
48 protected int monthsPlayerColoniesExist = 0;
49 protected int baseCreationTimeout = 0;
50 protected Random random = new Random();
51
52 protected List<PirateBaseIntel> bases = new ArrayList<PirateBaseIntel>();
53
55 super();
56 Global.getSector().getMemoryWithoutUpdate().set(KEY, this);
57 start = Global.getSector().getClock().getTimestamp();
58 }
59
60
61 public void advance(float amount) {
62
63 for (PirateBaseIntel intel : bases) {
64 intel.advance(amount);
65 }
66
67 float days = Misc.getDays(amount);
68
70 days *= 100f;
71 }
72
73 monthlyInterval.advance(days);
74
75 if (monthlyInterval.intervalElapsed()) {
77
78 FactionAPI player = Global.getSector().getPlayerFaction();
79 List<MarketAPI> markets = Misc.getFactionMarkets(player);
80
81 Iterator<MarketAPI> iter = markets.iterator();
82 while (iter.hasNext()) {
83 if (iter.next().isHidden()) iter.remove();
84 }
85
86 if (markets.isEmpty()) {
87 return;
88 }
89
91
92// if (!sentFirstRaid) {
93// if (monthsPlayerColoniesExist >= MIN_MONTHS_BEFORE_RAID && !markets.isEmpty()) {
94// sendFirstRaid(markets);
95// baseCreationTimeout = MIN_TIMEOUT + random.nextInt(MAX_TIMEOUT - MIN_TIMEOUT + 1);
96// }
97// return;
98// }
99
100 if (baseCreationTimeout > 0) {
102 } else {
103 if (random.nextFloat() > 0.5f && PiracyRespiteScript.get() == null) {
105 }
106 }
107 }
108 }
109
110 protected void removeDestroyedBases() {
111 Iterator<PirateBaseIntel> iter = bases.iterator();
112 while (iter.hasNext()) {
113 PirateBaseIntel intel = iter.next();
114 if (intel.isEnded() && !intel.getMarket().isInEconomy()) {
115 iter.remove();
116
117// int baseTimeout = 3;
118// switch (intel.getTier()) {
119// case TIER_1_1MODULE: baseTimeout = 3; break;
120// case TIER_2_1MODULE: baseTimeout = 3; break;
121// case TIER_3_2MODULE: baseTimeout = 4; break;
122// case TIER_4_3MODULE: baseTimeout = 5; break;
123// case TIER_5_3MODULE: baseTimeout = 6; break;
124// }
125// baseCreationTimeout += baseTimeout + random.nextInt(baseTimeout + 1);
127 }
128 }
129 }
130
131 protected void addBasesAsNeeded() {
132 FactionAPI player = Global.getSector().getPlayerFaction();
133 List<MarketAPI> markets = Misc.getFactionMarkets(player);
134
135 Set<StarSystemAPI> systems = new LinkedHashSet<StarSystemAPI>();
136 for (MarketAPI curr : markets) {
137 StarSystemAPI system = curr.getStarSystem();
138 if (system != null) {
139 systems.add(system);
140 }
141 }
142 if (systems.isEmpty()) return;
143
144 float marketTotal = markets.size();
145 int numBases = (int) (marketTotal / 2);
146 if (numBases < 1) numBases = 1;
147 if (numBases > 2) numBases = 2;
148
149
150 if (bases.size() >= numBases) {
151 return;
152 }
153
154
155 StarSystemAPI initialTarget = null;
156 float bestWeight = 0f;
157 OUTER: for (StarSystemAPI curr : systems) {
158 float w = 0f;
159 for (MarketAPI m : Global.getSector().getEconomy().getMarkets(curr)) {
160 if (m.hasCondition(Conditions.PIRATE_ACTIVITY)) continue OUTER;
161 if (m.getFaction().isPlayerFaction()) {
162 w += m.getSize() * m.getSize();
163 }
164 }
165 if (w > bestWeight) {
166 bestWeight = w;
167 initialTarget = curr;
168 }
169 }
170
171 if (initialTarget == null) return;
172
173 StarSystemAPI target = pickSystemForPirateBase(initialTarget);
174 if (target == null) return;
175
176 PirateBaseTier tier = pickTier(target);
177
178 String factionId = pickPirateFaction();
179 if (factionId == null) return;
180
181 //factionId = Factions.HEGEMONY;
182
183 PirateBaseIntel intel = new PirateBaseIntel(target, factionId, tier);
184 if (intel.isDone()) {
185 intel = null;
186 return;
187 }
188
189 //intel.setTargetPlayerColoniesOnly(true);
190 // this is for raids: don't do it since raids are handled by HostileActivityEventIntel now
191 //intel.setForceTarget(initialTarget);
192 intel.updateTarget();
193 bases.add(intel);
194
196 }
197
198 public String pickPirateFaction() {
199 WeightedRandomPicker<String> picker = new WeightedRandomPicker<String>(random);
200 for (FactionAPI faction : Global.getSector().getAllFactions()) {
201 if (!faction.isHostileTo(Factions.PLAYER)) continue;
202
203 if (faction.getCustomBoolean(Factions.CUSTOM_MAKES_PIRATE_BASES)) {
204 picker.add(faction.getId(), 1f);
205 }
206 }
207 return picker.pick();
208 }
209
210// protected void sendFirstRaid(List<MarketAPI> markets) {
211// if (markets.isEmpty()) return;
212//
213//
214// WeightedRandomPicker<MarketAPI> picker = new WeightedRandomPicker<MarketAPI>(random);
215// picker.addAll(markets);
216// MarketAPI target = picker.pick();
217//
218// PirateBaseIntel closest = null;
219// float minDist = Float.MAX_VALUE;
220// for (IntelInfoPlugin p : Global.getSector().getIntelManager().getIntel(PirateBaseIntel.class)) {
221// PirateBaseIntel intel = (PirateBaseIntel) p;
222// if (intel.isEnding()) continue;
223//
224// float dist = Misc.getDistanceLY(intel.getMarket().getPrimaryEntity(), target.getPrimaryEntity());
225// if (dist < minDist && dist <= 15) {
226// minDist = dist;
227// closest = intel;
228// }
229// }
230//
231// if (closest != null && target != null) {
232// float raidFP = 120 + 30f * random.nextFloat();
235// closest.startRaid(target.getStarSystem(), raidFP);
236// sentFirstRaid = true;
237// }
238// }
239
240
241
242 protected PirateBaseTier pickTier(StarSystemAPI system) {
243 float max = 0f;
244 for (MarketAPI m : Global.getSector().getEconomy().getMarkets(system)) {
245 if (m.getFaction().isPlayerFaction()) {
246 max = Math.max(m.getSize(), max);
247 }
248 }
249 if (max >= 7) {
250 return PirateBaseTier.TIER_5_3MODULE;
251 } else if (max >= 6) {
252 return PirateBaseTier.TIER_4_3MODULE;
253 } else if (max >= 5) {
254 return PirateBaseTier.TIER_3_2MODULE;
255 } else if (max >= 4) {
256 return PirateBaseTier.TIER_2_1MODULE;
257 } else {
258 return PirateBaseTier.TIER_1_1MODULE;
259 }
260
261 }
262
263 protected StarSystemAPI pickSystemForPirateBase(StarSystemAPI initialTarget) {
264 WeightedRandomPicker<StarSystemAPI> veryFar = new WeightedRandomPicker<StarSystemAPI>(random);
265 WeightedRandomPicker<StarSystemAPI> far = new WeightedRandomPicker<StarSystemAPI>(random);
266 WeightedRandomPicker<StarSystemAPI> picker = new WeightedRandomPicker<StarSystemAPI>(random);
267
268 for (StarSystemAPI system : Global.getSector().getStarSystems()) {
269 if (system.hasPulsar()) continue;
270
271 float days = Global.getSector().getClock().getElapsedDaysSince(system.getLastPlayerVisitTimestamp());
272 if (days < 180f) continue;
273
274 if (system.getCenter().getMemoryWithoutUpdate().contains(PirateBaseManager.RECENTLY_USED_FOR_BASE)) continue;
275
276 float weight = 0f;
277 if (system.hasTag(Tags.THEME_MISC_SKIP)) {
278 weight = 1f;
279 } else if (system.hasTag(Tags.THEME_MISC)) {
280 weight = 3f;
281 } else if (system.hasTag(Tags.THEME_REMNANT_NO_FLEETS)) {
282 weight = 3f;
283 } else if (system.hasTag(Tags.THEME_REMNANT_DESTROYED)) {
284 weight = 3f;
285 } else if (system.hasTag(Tags.THEME_RUINS)) {
286 weight = 5f;
287 } else if (system.hasTag(Tags.THEME_CORE_UNPOPULATED)) {
288 //weight = 1f;
289 weight = 0f;
290 }
291 if (weight <= 0f) continue;
292
293 float usefulStuff = system.getCustomEntitiesWithTag(Tags.OBJECTIVE).size() +
294 system.getCustomEntitiesWithTag(Tags.STABLE_LOCATION).size();
295 if (usefulStuff <= 0) continue;
296
297 if (Misc.getMarketsInLocation(system).size() > 0) continue;
298
299 float dist = Misc.getDistance(initialTarget.getLocation(), system.getLocation());
300
301 float distMult = 100000f / dist;
302 distMult *= distMult;
303
304 if (dist > 30000f) {
305 veryFar.add(system, weight * usefulStuff * distMult);
306 } else if (dist > 10000f) {
307 far.add(system, weight * usefulStuff * distMult);
308 } else {
309 picker.add(system, weight * usefulStuff * distMult);
310 }
311 }
312
313 if (picker.isEmpty()) {
314 picker.addAll(far);
315 }
316 if (picker.isEmpty()) {
317 picker.addAll(veryFar);
318 }
319
320 return picker.pick();
321 }
322
323
324 public boolean isDone() {
325 return false;
326 }
327
328
329 public boolean runWhilePaused() {
330 return false;
331 }
332
333}
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
static SettingsAPI getSettings()
Definition Global.java:51
static SectorAPI getSector()
Definition Global.java:59
int getIntFromArray(String key, int index)