Starsector API
Loading...
Searching...
No Matches
WarSimScript.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.command;
2
3import java.util.ArrayList;
4import java.util.HashSet;
5import java.util.LinkedHashSet;
6import java.util.List;
7import java.util.Set;
8
9import com.fs.starfarer.api.EveryFrameScript;
10import com.fs.starfarer.api.Global;
11import com.fs.starfarer.api.campaign.CampaignFleetAPI;
12import com.fs.starfarer.api.campaign.FactionAPI;
13import com.fs.starfarer.api.campaign.SectorEntityToken;
14import com.fs.starfarer.api.campaign.StarSystemAPI;
15import com.fs.starfarer.api.campaign.ai.CampaignFleetAIAPI.ActionType;
16import com.fs.starfarer.api.campaign.econ.MarketAPI;
17import com.fs.starfarer.api.campaign.listeners.ObjectiveEventListener;
18import com.fs.starfarer.api.impl.campaign.MilitaryResponseScript;
19import com.fs.starfarer.api.impl.campaign.MilitaryResponseScript.MilitaryResponseParams;
20import com.fs.starfarer.api.impl.campaign.fleets.EconomyFleetRouteManager;
21import com.fs.starfarer.api.impl.campaign.fleets.RouteManager;
22import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.OptionalFleetData;
23import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteData;
24import com.fs.starfarer.api.impl.campaign.ids.Factions;
25import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
26import com.fs.starfarer.api.impl.campaign.ids.Tags;
27import com.fs.starfarer.api.impl.campaign.intel.events.HostileActivityEventIntel;
28import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.Objectives;
29import com.fs.starfarer.api.impl.campaign.tutorial.TutorialMissionIntel;
30import com.fs.starfarer.api.plugins.BuildObjectiveTypePicker;
31import com.fs.starfarer.api.plugins.BuildObjectiveTypePicker.BuildObjectiveParams;
32import com.fs.starfarer.api.util.CountingMap;
33import com.fs.starfarer.api.util.Misc;
34import com.fs.starfarer.api.util.TimeoutTracker;
35import com.fs.starfarer.api.util.WeightedRandomPicker;
36
38
39 public static enum LocationDanger {
40 NONE(0.01f),
41 MINIMAL(0.1f),
42 LOW(0.2f),
43 MEDIUM(0.3f),
44 HIGH(0.5f),
45 EXTREME(0.8f),
46 ;
47
48 public static LocationDanger [] vals = values();
49
50 public float enemyStrengthFraction;
51 private LocationDanger(float enemyStrengthFraction) {
52 this.enemyStrengthFraction = enemyStrengthFraction;
53 }
54
55 public LocationDanger next() {
56 int index = this.ordinal() + 1;
57 if (index >= vals.length) index = vals.length - 1;
58 return vals[index];
59 }
60 public LocationDanger prev() {
61 int index = this.ordinal() - 1;
62 if (index < 0) index = 0;
63 return vals[index];
64 }
65
66 }
67
68
69
70
71
72 public static final String KEY = "$core_warSimScript";
73
74 public static final float CHECK_DAYS = 10f;
75 public static final float CHECK_PROB = 0.5f;
76
77
78 public static WarSimScript getInstance() {
80 return (WarSimScript) test;
81 }
82
84
85 protected List<StarSystemAPI> queue = new ArrayList<StarSystemAPI>();
86
87 public WarSimScript() {
90
92 String sid = getStarSystemTimeoutId(system);
93 timeouts.add(sid, 2f + (float) Math.random() * 3f);
94 }
95 }
96
97 protected Object readResolve() {
98 if (timeouts == null) {
100 }
101 return this;
102 }
103
104 public void advance(float amount) {
105 //if (true) return;
106
108 return;
109 }
110
111 float days = Misc.getDays(amount);
112
113 timeouts.advance(days);
114
115 if (queue.isEmpty()) {
117 }
118
119 if (!queue.isEmpty()) {
120 StarSystemAPI curr = queue.remove(0);
121 processStarSystem(curr);
122 }
123 }
124
125 public void processStarSystem(StarSystemAPI system) {
126 String sid = getStarSystemTimeoutId(system);
127 if (timeouts.contains(sid)) return;
128 timeouts.add(sid, 2f + (float) Math.random() * 3f);
129
131
132 boolean inSpawnRange = RouteManager.isPlayerInSpawnRange(system.getCenter());
133
134 List<FactionAPI> factions = new ArrayList<FactionAPI>(str.keySet());
135
136// if (system.getName().toLowerCase().contains("old milix")) {
137// System.out.println("wefwefwe");
138// }
139
140// if (system.isCurrentLocation()) {
141// System.out.println("ff23f23f32");
142// }
143
145 List<FactionAPI> contenders = new ArrayList<FactionAPI>();
146
147 // figure out if anyone that doesn't own it thinks they should own it
148 for (FactionAPI faction : factions) {
149 if (wantsToOwnObjective(faction, str, obj)) {
150 contenders.add(faction);
151 String id = getControlTimeoutId(obj, faction);
152 if (!timeouts.contains(id)) {
153 addObjectiveActionResponse(obj, faction, obj.getFaction());
154 }
155 } else if (faction == obj.getFaction()) {
156 contenders.add(faction);
157 }
158 }
159
160 if (!inSpawnRange) {
161 String id = getControlSimTimeoutId(obj);
162 if (timeouts.contains(id)) continue;
163
164 timeouts.add(id, 10f + (float) Math.random() * 30f);
165
167 float max = 0f;
168 for (FactionAPI faction : contenders) {
169 float curr = str.getCount(faction) + getStationStrength(faction, system, obj);
170 if (curr > max) {
171 max = curr;
172 }
173 }
174 if (max <= 0) continue;
175
176 for (FactionAPI faction : contenders) {
177 float curr = str.getCount(faction) + getStationStrength(faction, system, obj);
178 float w = (curr / max) - 0.5f;
179 picker.add(faction, w);
180 }
181
182 FactionAPI winner = picker.pick();
183 if (winner != null && winner != obj.getFaction()) {
184 Objectives o = new Objectives(obj);
185 o.control(winner.getId());
186 }
187 }
188 }
189
190
192 if (sLoc.hasTag(Tags.NON_CLICKABLE)) continue;
193 if (sLoc.hasTag(Tags.FADING_OUT_AND_EXPIRING)) continue;
194 if (!inSpawnRange) {
195 String id = getBuildSimTimeoutId(sLoc);
196 if (timeouts.contains(id)) continue;
197
198 timeouts.add(id, 20f + (float) Math.random() * 20f);
199
201 float max = 0f;
202 for (FactionAPI faction : factions) {
203 float curr = str.getCount(faction) + getStationStrength(faction, system, sLoc);
204 if (curr > max) {
205 max = curr;
206 }
207 }
208 if (max <= 0) continue;
209
210 for (FactionAPI faction : factions) {
211 float curr = str.getCount(faction) + getStationStrength(faction, system, sLoc);
212 float w = (curr / max) - 0.5f;
213 picker.add(faction, w);
214 }
215
216 FactionAPI winner = picker.pick();
217 if (winner != null && winner != sLoc.getFaction()) {
218 BuildObjectiveParams params = new BuildObjectiveParams();
219 params.faction = winner;
220 params.fleet = null;
221 params.stableLoc = sLoc;
223 String type = null;
224 if (pick != null) {
225 type = pick.pickObjectiveToBuild(params);
226 }
227 if (type != null) {
228 Objectives o = new Objectives(sLoc);
229 o.build(type, winner.getId());
230 }
231 }
232 }
233 }
234 }
235
247 if (o.getFaction() == faction) return false;
248 if (!o.getFaction().isHostileTo(faction) && !o.getFaction().isNeutralFaction()) {
249// for (MarketAPI curr : Misc.getMarketsInLocation(o.getContainingLocation())) {
250// if (curr.getFaction() == o.getFaction() &&
251// !curr.getFaction().isNeutralFaction() &&
252// !curr.getFaction().isPlayerFaction()) {
253// return false;
254// }
255// }
256// return true;
257
258 boolean ownerHasColonyInSystem = false;
260 if (curr.getFaction() == o.getFaction() &&
261 !curr.getFaction().isNeutralFaction()) {
262 ownerHasColonyInSystem = true;
263 break;
264 }
265 }
266 if (ownerHasColonyInSystem) return false;
267 return true;
268 }
269
270 float minDist = Float.MAX_VALUE;
271 MarketAPI closest = null;
272 boolean haveInSystemMarkets = false;
274 float dist = Misc.getDistance(market.getPrimaryEntity(), o);
275 if (dist < minDist) {
276 minDist = dist;
277 closest = market;
278 }
279 if (faction == market.getFaction()) {
280 haveInSystemMarkets = true;
281 }
282 }
283
284 if (closest != null && closest.getFaction() == faction) {
285 return true;
286 }
287
288 // pirate-like factions will try to pick up objectives that are far away from any markets
290 if (minDist > 8000) {
291 return true;
292 }
293 }
294
295 if (!haveInSystemMarkets && closest != null && !closest.getFaction().isHostileTo(faction)) {
296 return false;
297 }
298
299 int maxStr = 0;
300 FactionAPI strongest = null;
301 for (FactionAPI curr : str.keySet()) {
302 int s = str.getCount(curr);
303 if (s > maxStr) {
304 maxStr = s;
305 strongest = curr;
306 }
307 }
308
309 return strongest == faction;
310 }
311
312
313
315 addObjectiveActionResponse(objective, from, to);
316 }
317
318
319 public void reportObjectiveDestroyed(SectorEntityToken objective, SectorEntityToken stableLocation, FactionAPI enemy) {
320 String id = getBuildSimTimeoutId(stableLocation);
321 timeouts.add(id, 40f + (float) Math.random() * 20f, 100f);
322
323 addObjectiveActionResponse(objective, objective.getFaction(), null);
324 }
325
326
327 protected String getStarSystemTimeoutId(StarSystemAPI system) {
328 String id = "starsystem_" + system.getId();
329 return id;
330 }
331
332 protected String getBuildSimTimeoutId(SectorEntityToken objective) {
333 String id = "sim_build_" + objective.getId();
334 return id;
335 }
336
337 protected String getControlSimTimeoutId(SectorEntityToken objective) {
338 String id = "sim_changedhands_" + objective.getId();
339 return id;
340 }
341
342 protected String getControlTimeoutId(SectorEntityToken objective, FactionAPI faction) {
343 String id = faction.getId() + "_" + objective.getId();
344 return id;
345 }
346
347 protected void addObjectiveActionResponse(SectorEntityToken objective, FactionAPI faction, FactionAPI enemy) {
348 if (faction.isNeutralFaction()) return;
349 if (faction.getCustomBoolean(Factions.CUSTOM_NO_WAR_SIM)) return;
350
351 if (enemy != null && enemy.isNeutralFaction()) return;
352 if (enemy != null && !faction.isHostileTo(enemy)) return;
353
354 String id = getControlTimeoutId(objective, faction);
355 if (timeouts.contains(id)) return;
356
357 if (isAlreadyFightingFor(objective, faction)) { // an MRS from some other source, such as a raid
358 return;
359 }
360
361 MilitaryResponseParams params = new MilitaryResponseParams(ActionType.HOSTILE,
362 objective.getId(),
363 faction,
364 objective,
365 0.4f,
366 20f + (float) Math.random() * 20f);
368 objective.getContainingLocation().addScript(script);
369
370 timeouts.add(id, params.responseDuration * 2f);
371 }
372
373
374
375
376 public boolean isDone() {
377 return false;
378 }
379
380 public boolean runWhilePaused() {
381 return false;
382 }
383
384
385
386
389
390 Set<FactionAPI> factions = new LinkedHashSet<FactionAPI>();
391// if (system.getName().startsWith("Askonia")) {
392// System.out.println("wefewfew");
393// }
394
395 for (CampaignFleetAPI fleet : system.getFleets()) {
396 if (fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.MEMORY_KEY_TRADE_FLEET)) continue;
397 if (fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.MEMORY_KEY_SMUGGLER)) continue;
398 factions.add(fleet.getFaction());
399 }
400
401 for (RouteData route : RouteManager.getInstance().getRoutesInLocation(system)) {
402 String id = route.getFactionId();
403 if (id == null) continue;
404 FactionAPI faction = Global.getSector().getFaction(id);
405 factions.add(faction);
406 }
407
408 for (FactionAPI faction : factions) {
409 if (faction.getCustomBoolean(Factions.CUSTOM_NO_WAR_SIM)) continue;
410
411 int strength = (int) getFactionStrength(faction, system);
412 if (strength > 0) {
413 result.add(faction, strength);
414 }
415 }
416 return result;
417 }
418
419
420
421 public static float getRelativeEnemyStrength(String factionId, StarSystemAPI system) {
422 float enemyStrength = getEnemyStrength(factionId, system);
423 float factionStrength = getFactionStrength(factionId, system);
424 float f = enemyStrength / Math.max(1f, factionStrength + enemyStrength);
425 return f;
426 }
427
428 public static float getRelativeFactionStrength(String factionId, StarSystemAPI system) {
429 float enemyStrength = getEnemyStrength(factionId, system);
430 float factionStrength = getFactionStrength(factionId, system);
431 float f = factionStrength / Math.max(1f, factionStrength + enemyStrength);
432 return f;
433 }
434
435 public static float getEnemyStrength(String factionId, StarSystemAPI system) {
436 return getEnemyStrength(Global.getSector().getFaction(factionId), system, false);
437 }
438 public static float getEnemyStrength(FactionAPI faction, StarSystemAPI system) {
439 return getEnemyStrength(faction, system, false);
440 }
441 public static float getEnemyStrength(String factionId, StarSystemAPI system, boolean assumeHostileToPlayer) {
442 return getEnemyStrength(Global.getSector().getFaction(factionId), system, assumeHostileToPlayer);
443 }
444 public static float getEnemyStrength(FactionAPI faction, StarSystemAPI system, boolean assumeHostileToPlayer) {
445 float enemyStr = 0;
446 Set<String> seen = new HashSet<String>();
448 seen.add(Factions.PIRATES);
449 }
450
451
452 for (MarketAPI target : Misc.getMarketsInLocation(system)) {
453 if (!(assumeHostileToPlayer && target.getFaction().isPlayerFaction())) {
454 if (!target.getFaction().isHostileTo(faction)) continue;
455 }
456
457 if (seen.contains(target.getFactionId())) continue;
458 seen.add(target.getFactionId());
459 enemyStr += WarSimScript.getFactionStrength(target.getFaction(), system);
460 }
461
462 if (faction.isPlayerFaction()) {
464 //HostileActivityIntel intel = HostileActivityIntel.get(system);
465 if (intel != null) {
466 enemyStr += intel.getVeryApproximateFPStrength(system);
467 }
468 }
469
470 return enemyStr;
471 }
472
473 public static float getFactionStrength(String factionId, StarSystemAPI system) {
474 return getFactionStrength(Global.getSector().getFaction(factionId), system);
475 }
476 public static float getFactionStrength(FactionAPI faction, StarSystemAPI system) {
477 float strength = 0f;
478
479// if (system.getName().toLowerCase().contains("naraka") && Factions.PIRATES.equals(faction.getId())) {
480// System.out.println("wefwefwe");
481// }
482
483 Set<CampaignFleetAPI> seenFleets = new HashSet<CampaignFleetAPI>();
484 for (CampaignFleetAPI fleet : system.getFleets()) {
485 if (fleet.getFaction() != faction) continue;
486 if (fleet.isStationMode()) continue;
487 if (fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.MEMORY_KEY_TRADE_FLEET)) continue;
488 if (fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.MEMORY_KEY_SMUGGLER)) continue;
489
490 if (fleet.isPlayerFleet()) continue;
491
492// if (EconomyFleetRouteManager.FACTION_STRENGTH_CHECK_EXCLUDE_PIRATES &&
493// fleet.getFaction().getId().equals(Factions.PIRATES)) {
494// continue;
495// }
496
497 strength += fleet.getEffectiveStrength();
498
499 seenFleets.add(fleet);
500 }
501
502 for (RouteData route : RouteManager.getInstance().getRoutesInLocation(system)) {
503 if (route.getActiveFleet() != null && seenFleets.contains(route.getActiveFleet())) continue;
504
505 OptionalFleetData data = route.getExtra();
506 if (data == null) continue;
507 if (route.getFactionId() == null) continue;
508 if (!faction.getId().equals(route.getFactionId())) continue;
509
510// if (EconomyFleetRouteManager.FACTION_STRENGTH_CHECK_EXCLUDE_PIRATES &&
511// route.getFactionId().equals(Factions.PIRATES)) {
512// continue;
513// }
514
515 strength += data.getStrengthModifiedByDamage();
516 }
517
518 return strength;
519 }
520
521
522 public static float getStationStrength(FactionAPI faction, StarSystemAPI system, SectorEntityToken from) {
523 float strength = 0f;
524
525 for (CampaignFleetAPI fleet : system.getFleets()) {
526 if (!fleet.isStationMode()) continue;
527 if (fleet.getFaction() != faction) continue;
528
529 float maxDist = Misc.getBattleJoinRange() * 3f;
530
531 float dist = Misc.getDistance(from, fleet);
532 if (dist < maxDist) {
533 strength += fleet.getEffectiveStrength();
534 }
535 }
536
537 return strength;
538 }
539
541 return timeouts;
542 }
543
544
545 public static void removeFightOrdersFor(SectorEntityToken target, FactionAPI faction) {
547 if (s instanceof MilitaryResponseScript) {
549 if (script.getParams() != null && script.getParams().target == target &&
550 script.getParams().faction == faction) {
551 script.forceDone();
552 }
553 }
554 }
555 }
556
557 public static void setNoFightingForObjective(SectorEntityToken objective, FactionAPI faction, float timeout) {
558 removeFightOrdersFor(objective, faction);
559 if (timeout > 0) {
561 String id = wss.getControlTimeoutId(objective, faction);
562 wss.timeouts.add(id, timeout);
563 }
564 }
565
566 public static void removeNoFightingTimeoutForObjective(SectorEntityToken objective, FactionAPI faction) {
568 String id = wss.getControlTimeoutId(objective, faction);
569 wss.timeouts.remove(id);
570 }
571
572 public static boolean isAlreadyFightingFor(SectorEntityToken objective, FactionAPI faction) {
573 for (EveryFrameScript s : objective.getContainingLocation().getScripts()) {
574 if (s instanceof MilitaryResponseScript) {
576 if (script.getParams() != null && script.getParams().target == objective &&
577 script.getParams().faction == faction) {
578 return true;
579 }
580 }
581 }
582 return false;
583
584 }
585
586 public static LocationDanger getDangerFor(FactionAPI faction, StarSystemAPI system) {
587 if (system == null) return LocationDanger.NONE;
588 return getDangerFor(getFactionStrength(faction, system), getEnemyStrength(faction, system));
589 }
590 public static LocationDanger getDangerFor(String factionId, StarSystemAPI system) {
591 if (system == null) return LocationDanger.NONE;
592 return getDangerFor(getFactionStrength(factionId, system), getEnemyStrength(factionId, system));
593 }
594 public static LocationDanger getDangerFor(float factionStrength, float enemyStrength) {
595 if (enemyStrength < 100) return LocationDanger.NONE;
596
597 float f = enemyStrength / Math.max(1f, factionStrength + enemyStrength);
598 for (LocationDanger level : LocationDanger.vals) {
599 float test = level.enemyStrengthFraction + (level.next().enemyStrengthFraction - level.enemyStrengthFraction) * 0.5f;
600 if (level == LocationDanger.NONE) test = LocationDanger.NONE.enemyStrengthFraction;
601 if (test >= f) {
602 return level;
603 }
604 }
605 return LocationDanger.EXTREME;
606 }
607}
608
609
610
611
612
613
static SectorAPI getSector()
Definition Global.java:65
static LocationDanger getDangerFor(FactionAPI faction, StarSystemAPI system)
static float getFactionStrength(String factionId, StarSystemAPI system)
static float getRelativeFactionStrength(String factionId, StarSystemAPI system)
String getControlSimTimeoutId(SectorEntityToken objective)
static float getEnemyStrength(FactionAPI faction, StarSystemAPI system)
static float getStationStrength(FactionAPI faction, StarSystemAPI system, SectorEntityToken from)
static float getFactionStrength(FactionAPI faction, StarSystemAPI system)
String getControlTimeoutId(SectorEntityToken objective, FactionAPI faction)
void addObjectiveActionResponse(SectorEntityToken objective, FactionAPI faction, FactionAPI enemy)
void reportObjectiveChangedHands(SectorEntityToken objective, FactionAPI from, FactionAPI to)
static void removeNoFightingTimeoutForObjective(SectorEntityToken objective, FactionAPI faction)
static float getEnemyStrength(String factionId, StarSystemAPI system, boolean assumeHostileToPlayer)
static float getEnemyStrength(FactionAPI faction, StarSystemAPI system, boolean assumeHostileToPlayer)
static CountingMap< FactionAPI > getFactionStrengths(StarSystemAPI system)
static void setNoFightingForObjective(SectorEntityToken objective, FactionAPI faction, float timeout)
static LocationDanger getDangerFor(float factionStrength, float enemyStrength)
static float getRelativeEnemyStrength(String factionId, StarSystemAPI system)
static void removeFightOrdersFor(SectorEntityToken target, FactionAPI faction)
static boolean isAlreadyFightingFor(SectorEntityToken objective, FactionAPI faction)
void reportObjectiveDestroyed(SectorEntityToken objective, SectorEntityToken stableLocation, FactionAPI enemy)
static LocationDanger getDangerFor(String factionId, StarSystemAPI system)
boolean wantsToOwnObjective(FactionAPI faction, CountingMap< FactionAPI > str, SectorEntityToken o)
String getBuildSimTimeoutId(SectorEntityToken objective)
static float getEnemyStrength(String factionId, StarSystemAPI system)
static boolean isPlayerInSpawnRange(SectorEntityToken from)
List< RouteData > getRoutesInLocation(LocationAPI location)
static final String FADING_OUT_AND_EXPIRING
Definition Tags.java:341
void add(K key, int quantity)
static List< MarketAPI > getMarketsInLocation(LocationAPI location, String factionId)
Definition Misc.java:936
static float getDistance(SectorEntityToken from, SectorEntityToken to)
Definition Misc.java:599
static float getDays(float amount)
Definition Misc.java:4663
static float getBattleJoinRange()
Definition Misc.java:2227
boolean isHostileTo(FactionAPI other)
< T > T pickPlugin(Class< T > c, Object params)
List< SectorEntityToken > getEntitiesWithTag(String tag)
void addScript(EveryFrameScript script)
List< EveryFrameScript > getScripts()
List< CampaignFleetAPI > getFleets()
GenericPluginManagerAPI getGenericPlugins()
FactionAPI getFaction(String factionId)
ListenerManagerAPI getListenerManager()
List< StarSystemAPI > getStarSystemsWithMarkets()
void set(String key, Object value)
String pickObjectiveToBuild(BuildObjectiveParams params)