Starsector API
Loading...
Searching...
No Matches
RouteManager.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.fleets;
2
3import java.util.ArrayList;
4import java.util.Iterator;
5import java.util.LinkedHashMap;
6import java.util.List;
7import java.util.Map;
8import java.util.Random;
9
10import org.lwjgl.util.vector.Vector2f;
11
12import com.fs.starfarer.api.Global;
13import com.fs.starfarer.api.campaign.BattleAPI;
14import com.fs.starfarer.api.campaign.CampaignEventListener.FleetDespawnReason;
15import com.fs.starfarer.api.campaign.CampaignFleetAPI;
16import com.fs.starfarer.api.campaign.LocationAPI;
17import com.fs.starfarer.api.campaign.SectorEntityToken;
18import com.fs.starfarer.api.campaign.SectorEntityToken.VisibilityLevel;
19import com.fs.starfarer.api.campaign.StarSystemAPI;
20import com.fs.starfarer.api.campaign.econ.MarketAPI;
21import com.fs.starfarer.api.campaign.listeners.FleetEventListener;
22import com.fs.starfarer.api.util.Misc;
23
24public class RouteManager implements FleetEventListener {
25 public static final String KEY = "$core_routeManager";
26
27 public static float IN_OUT_PHASE_DAYS = 3f;
28 public static float IN_OUT_PHASE_FRACTION = 0.2f;
29
30// public static float DAYS_SINCE_SEEN_BEFORE_DESPAWN = 60f;
31// public static float DESPAWN_DIST_LY = 4.6f;
32// public static float SPAWN_DIST_LY = 3.5f;
33
34 public static float DAYS_SINCE_SEEN_BEFORE_DESPAWN_IF_FAR = 30f;
35 public static float DAYS_SINCE_SEEN_BEFORE_DESPAWN_IF_CLOSE = 60f;
36 public static float DESPAWN_DIST_LY_FAR = 4f;
37 public static float DESPAWN_DIST_LY_CLOSE = 3f;
38 public static float SPAWN_DIST_LY = 1.6f;
39
40
41 public static class OptionalFleetData {
42 public Float strength; // extremely approximate, in fleet points but modified by quality and doctrine
43 public Float quality;
44 public Float fp; // actual fleet points
45 public String factionId;
46 public String fleetType;
47 public Float damage; // 0 to 1, how much damage the fleet has sustained. spawner should use that info.
48
49 public OptionalFleetData() {
50 }
51 public OptionalFleetData(MarketAPI market) {
52 this(market, market.getFactionId());
53 }
54 public OptionalFleetData(MarketAPI market, String factionId) {
55 quality = Misc.getShipQuality(market, factionId);
56 this.factionId = factionId;
57 }
58
59 public float getStrengthModifiedByDamage() {
60 if (strength == null) return 0f;
61 float str = strength;
62 if (damage != null) {
63 str *= Math.max(0, 1f - damage);
64 }
65 return str;
66 }
67 }
68
69 public static class RouteSegment {
70 public Integer id; // generally ought to be unique within the route, but doesn't have to be
71 public float elapsed = 0f;
72 public float daysMax;
73 public SectorEntityToken from;
74 public SectorEntityToken to;
75 public Object custom;
76
77 public RouteSegment(Integer id, float daysMax, SectorEntityToken from) {
78 this(id, daysMax, from, null, null);
79 }
80 public RouteSegment(float daysMax, SectorEntityToken from) {
81 this(null, daysMax, from, null, null);
82 }
83 public RouteSegment(Integer id, float daysMax, SectorEntityToken from, Object custom) {
84 this(id, daysMax, from, null, custom);
85 }
86 public RouteSegment(float daysMax, SectorEntityToken from, Object custom) {
87 this(null, daysMax, from, null, custom);
88 }
89 public RouteSegment(Integer id, float daysMax, SectorEntityToken from, SectorEntityToken to) {
90 this(id, daysMax, from, to, null);
91 }
92 public RouteSegment(Integer id, SectorEntityToken from, SectorEntityToken to) {
93 this(id, 0f, from, to, null);
94 if (from.getContainingLocation() != to.getContainingLocation()) {
95 float dist = Misc.getDistance(from.getLocationInHyperspace(), to.getLocationInHyperspace());
96 daysMax = dist / 1500f + IN_OUT_PHASE_DAYS * 2f;
97 } else {
98 float dist = Misc.getDistance(from.getLocation(), to.getLocation());
99 daysMax = dist / 1500f;
100 }
101 }
102 public RouteSegment(float daysMax, SectorEntityToken from, SectorEntityToken to) {
103 this(null, daysMax, from, to, null);
104 }
105 public RouteSegment(Integer id, float daysMax, SectorEntityToken from, SectorEntityToken to, Object custom) {
106 this.id = id;
107 this.daysMax = daysMax;
108 this.from = from;
109 this.to = to;
110 this.custom = custom;
111 }
112
113 public LocationAPI getCurrentContainingLocation() {
114 LocationAPI loc = null;
115 if (from != null && to == null) {
116 loc = from.getContainingLocation();
117 } else if (from == null && to != null) {
118 loc = to.getContainingLocation();
119 } else {
120 if (from.getContainingLocation() == to.getContainingLocation()) {
121 loc = from.getContainingLocation();
122 } else {
123 if (getLeaveProgress() < 1) {
124 loc = from.getContainingLocation();
125 } else if (getTransitProgress() < 1) {
126 loc = Global.getSector().getHyperspace();
127 } else {
128 loc = to.getContainingLocation();
129 }
130 }
131 }
132 return loc;
133 }
134
135 public LocationAPI getContainingLocationFrom() {
136 if (from == null) return null;
137 return from.getContainingLocation();
138
139 }
140 public LocationAPI getContainingLocationTo() {
141 if (to == null) return null;
142 return to.getContainingLocation();
143 }
144
145 public boolean isTravel() {
146 return to != null;
147 }
148
149 public boolean isInSystem() {
150 if (to == null && from != null && from.getContainingLocation() != null && !from.getContainingLocation().isHyperspace()) return true;
151
152 if (!from.getContainingLocation().isHyperspace() &&
153 from.getContainingLocation() == to.getContainingLocation()) {
154 return true;
155 }
156 return false;
157 }
158
159 public boolean isFromSystemCenter() {
160 return from != null && from.getContainingLocation() instanceof StarSystemAPI &&
161 ((StarSystemAPI)from.getContainingLocation()).getCenter() == from;
162 }
163
164 public boolean isToSystemCenter() {
165 return to != null && to.getContainingLocation() instanceof StarSystemAPI &&
166 ((StarSystemAPI)to.getContainingLocation()).getCenter() == to;
167 }
168
169 public boolean hasLeaveSystemPhase() {
170 if (isInSystem()) return false;
171 if (isFromSystemCenter()) return false;
172 if (from != null && from.getContainingLocation().isHyperspace()) return false;
173 return true;
174 }
175 public boolean hasEnterSystemPhase() {
176 if (isInSystem()) return false;
177 if (isToSystemCenter()) return false;
178 if (to != null && to.getContainingLocation().isHyperspace()) return false;
179 return true;
180 }
181
182 public float getProgress() {
183 if (daysMax <= 0f) return 1f;
184 return elapsed / daysMax;
185 }
186
187 public float getEnterProgress() {
188 float dur = Math.min(daysMax * IN_OUT_PHASE_FRACTION, IN_OUT_PHASE_DAYS);
189 float f = 1f - Math.max(0, daysMax - elapsed) / dur;
190 if (f > 1) f = 1;
191 if (f < 0) f = 0;
192 return f;
193 }
194 public float getLeaveProgress() {
195 float dur = Math.min(daysMax * IN_OUT_PHASE_FRACTION, IN_OUT_PHASE_DAYS);
196 float f = elapsed / dur;
197 if (f > 1) f = 1;
198 if (f < 0) f = 0;
199 return f;
200 }
201 public float getTransitProgress() {
202 float dur = Math.min(daysMax * IN_OUT_PHASE_FRACTION, IN_OUT_PHASE_DAYS);
203 float max = daysMax;
204 float e = elapsed;
205 if (hasEnterSystemPhase()) {
206 max -= dur;
207 }
208 if (hasLeaveSystemPhase()) {
209 max -= dur;
210 e -= dur;
211 }
212 float f = e / max;
213 if (f > 1) f = 1;
214 if (f < 0) f = 0;
215 return f;
216 }
217
218 public SectorEntityToken getDestination() {
219 if (to != null) return to;
220 return from;
221 }
222
223 public SectorEntityToken getFrom() {
224 return from;
225 }
226 public int getId() {
227 if (id == null) return 0;
228 return id;
229 }
230
231
232 }
233
234
235 public static interface RouteFleetSpawner {
236 CampaignFleetAPI spawnFleet(RouteData route);
237 boolean shouldCancelRouteAfterDelayCheck(RouteData route);
238 boolean shouldRepeat(RouteData route);
239 void reportAboutToBeDespawnedByRouteManager(RouteData route);
240 }
241
242 public static class RouteData {
243 protected OptionalFleetData extra = null;
244 protected float delay = 0f;
245 protected String source;
246 protected MarketAPI market;
247 protected Long seed;
248 protected long timestamp;
249 protected List<RouteSegment> segments = new ArrayList<RouteSegment>();
250 protected CampaignFleetAPI activeFleet = null;
251 protected float daysSinceSeenByPlayer = 1000f;
252 protected float elapsed = 0f;
253 protected Object custom;
254 protected RouteSegment current;
255 protected RouteFleetSpawner spawner;
256 //protected Boolean suspended = null;
266 public RouteData(String source, MarketAPI market, Long seed, OptionalFleetData extra) {
267 this.source = source;
268 this.market = market;
269 this.seed = seed;
270 this.extra = extra;
271 }
272 public OptionalFleetData getExtra() {
273 return extra;
274 }
275 public void setExtra(OptionalFleetData extra) {
276 this.extra = extra;
277 }
278 public MarketAPI getMarket() {
279 return market;
280 }
281 public void goToAtLeastNext(RouteSegment from) {
282 int index = segments.indexOf(current);
283 int indexFrom = segments.indexOf(from);
284 if (indexFrom < 0) return;
285 if (indexFrom < index) return;
286
287 if (indexFrom < segments.size() - 1) {
288 current = segments.get(indexFrom + 1);
289 } else {
290 current.elapsed = current.daysMax;
291 }
292 }
293
294 public void expire() {
295 if (!segments.isEmpty()) {
296 current = segments.get(segments.size() - 1);
297 }
298 if (current != null) {
299 current.elapsed = current.daysMax;
300 }
301 }
302
303// public boolean isSuspended() {
304// return suspended != null && suspended == false;
305// }
306// /**
307// * Set to true to prevent route points from changing the "current" assignment.
308// * Useful when fleet is active and so route point advancement should be handled directly based on
309// * what the fleet does.
310// * @param suspended
311// */
312// public void setSuspended(boolean suspended) {
313// if (!suspended) {
314// this.suspended = null;
315// } else {
316// this.suspended = suspended;
317// }
318// }
319 public Random getRandom(int level) {
320 if (seed == null) return new Random();
321 return Misc.getRandom(seed, level);
322 }
323 public String getFactionId() {
324 if (extra == null || extra.factionId == null) {
325 if (market != null) return market.getFactionId();
326 return null;
327 }
328 return extra.factionId;
329 }
330 public Float getQualityOverride() {
331 if (extra == null) return null;
332 return extra.quality;
333 }
334 public long getTimestamp() {
335 return timestamp;
336 }
337 public void setTimestamp(long timestamp) {
338 this.timestamp = timestamp;
339 }
340 public Random getRandom() {
341 Random random = new Random();
342 if (getSeed() != null) {
343 random = new Random(getSeed());
344 }
345 return random;
346 }
347
348 public Long getSeed() {
349 return seed;
350 }
351 public RouteSegment addSegment(RouteSegment segment) {
352 if (segments.isEmpty()) current = segment;
353 segments.add(segment);
354 return segment;
355 }
356 public List<RouteSegment> getSegments() {
357 return segments;
358 }
359 public void setCurrent(RouteSegment current) {
360 this.current = current;
361 }
362 public CampaignFleetAPI getActiveFleet() {
363 return activeFleet;
364 }
365 public float getDaysSinceSeenByPlayer() {
366 return daysSinceSeenByPlayer;
367 }
368 public float getElapsed() {
369 return elapsed;
370 }
371 public Object getCustom() {
372 return custom;
373 }
374 public RouteSegment getCurrent() {
375 return current;
376 }
377 public Integer getCurrentSegmentId() {
378 if (current == null) return 0;
379 return current.getId();
380 }
381 public int getCurrentIndex() {
382 return segments.indexOf(current);
383 }
384 public RouteFleetSpawner getSpawner() {
385 return spawner;
386 }
387 public String getSource() {
388 return source;
389 }
390
391 public Vector2f getInterpolatedHyperLocation() {
392 //if (true) return new Vector2f();
393 if (current == null) return new Vector2f(100000000f, 0);
394
395 if (current.isInSystem() || current.getContainingLocationTo() == null || current.to == null) {
396 return current.from.getLocationInHyperspace();
397 }
398
399 //float p = current.elapsed / current.daysMax;
400 float p = current.getTransitProgress();
401
402
403 Vector2f from = current.getContainingLocationFrom().getLocation();
404 if (current.getContainingLocationFrom().isHyperspace()) {
405 from = current.getFrom().getLocation();
406 }
407 Vector2f to = current.getContainingLocationTo().getLocation();
408 if (current.getContainingLocationTo().isHyperspace()) {
409 to = current.to.getLocation();
410 }
411
412// Vector2f interpLoc = Misc.interpolateVector(current.getContainingLocationFrom().getLocation(),
413// current.getContainingLocationTo().getLocation(),
414// p);
415 Vector2f interpLoc = Misc.interpolateVector(from, to, p);
416 return interpLoc;
417 }
418
419
420 public boolean isExpired() {
421 if (segments.indexOf(current) == segments.size() - 1 && current.elapsed >= current.daysMax) {
422 return true;
423 }
424 return false;
425 }
426 public void setCustom(Object custom) {
427 this.custom = custom;
428 }
429 public float getDelay() {
430 return delay;
431 }
432 public void setDelay(float delay) {
433 this.delay = delay;
434 }
435
436 }
437
438 public static RouteManager getInstance() {
439 Object test = Global.getSector().getMemoryWithoutUpdate().get(KEY);
440 if (test instanceof RouteManager) {
441 return (RouteManager) test;
442 }
443
444 RouteManager manager = new RouteManager();
445 Global.getSector().getMemoryWithoutUpdate().set(KEY, manager);
446 return manager;
447 }
448
449 protected List<RouteData> routes = new ArrayList<RouteData>();
450 protected transient Map<String, List<RouteData>> sourceToRoute = new LinkedHashMap<String, List<RouteData>>();
451
452
453 Object readResolve() {
454 sourceToRoute = new LinkedHashMap<String, List<RouteData>>();
455 for (RouteData route : routes) {
456 addToMap(route);
457 }
458 return this;
459 }
460 protected transient Map<LocationAPI, List<RouteData>> routesByLocation = null;
461
462 public List<RouteData> getRoutesInLocation(LocationAPI location) {
463 if (routesByLocation == null) {
464 routesByLocation = new LinkedHashMap<LocationAPI, List<RouteData>>();
465 for (RouteData route : routes) {
466// if (route.getSource().startsWith("FGI")) {
467// System.out.println("fewefwefw");
468// }
469 RouteSegment current = route.current;
470 if (current == null) continue;
471
472 LocationAPI loc = null;
473 if (current.from != null && current.to == null) {
474 loc = current.from.getContainingLocation();
475 } else if (current.from == null && current.to != null) {
476 loc = current.to.getContainingLocation();
477 } else {
478 if (current.from.getContainingLocation() == current.to.getContainingLocation()) {
479 loc = current.from.getContainingLocation();
480 } else {
481 if (current.getLeaveProgress() < 1) {
482 loc = current.from.getContainingLocation();
483 } else if (current.getTransitProgress() < 1) {
484 loc = Global.getSector().getHyperspace();
485 } else {
486 loc = current.to.getContainingLocation();
487 }
488 }
489 }
490
491 if (loc != null) {
492 List<RouteData> list = routesByLocation.get(loc);
493 if (list == null) {
494 list = new ArrayList<RouteData>();
495 routesByLocation.put(loc, list);
496 }
497 list.add(route);
498 }
499 }
500 }
501
502 List<RouteData> list = routesByLocation.get(location);
503 if (list == null) list = new ArrayList<RouteData>();
504 return list;
505 }
506
507
508 public RouteData addRoute(String source, MarketAPI market, Long seed, OptionalFleetData extra, RouteFleetSpawner spawner) {
509 return addRoute(source, market, seed, extra, spawner, null);
510 }
511
512 @Deprecated public void removeRote(RouteData route) {
513 removeRoute(route);
514 }
515 public void removeRoute(RouteData route) {
516 routes.remove(route);
517 removeFromMap(route);
518 }
519
520 public RouteData addRoute(String source, MarketAPI market, Long seed, OptionalFleetData extra, RouteFleetSpawner spawner, Object custom) {
521 routesByLocation = null;
522
523 RouteData route = new RouteData(source, market, seed, extra);
524 route.spawner = spawner;
525 route.custom = custom;
526 route.timestamp = Global.getSector().getClock().getTimestamp();
527 routes.add(route);
528 addToMap(route);
529 //routes.clear();
530 return route;
531 }
532
533 public int getNumRoutesFor(String source) {
534 if (!sourceToRoute.containsKey(source)) return 0;
535 return sourceToRoute.get(source).size();
536 }
537
538 public void addToMap(RouteData route) {
539 if (route.source == null) return;
540
541 List<RouteData> forSource = getRoutesForSource(route.source);
542 forSource.add(route);
543 }
544
545 public void removeFromMap(RouteData route) {
546 routesByLocation = null;
547
548 if (route.source == null) return;
549
550 List<RouteData> forSource = getRoutesForSource(route.source);
551 forSource.remove(route);
552 if (forSource.isEmpty()) {
553 sourceToRoute.remove(route.source);
554 }
555 }
556
557 public List<RouteData> getRoutesForSource(String source) {
558 List<RouteData> forSource = sourceToRoute.get(source);
559 if (forSource == null) {
560 forSource = new ArrayList<RouteData>();
561 sourceToRoute.put(source, forSource);
562 }
563 return forSource;
564 }
565
566 public RouteData getRoute(String source, CampaignFleetAPI fleet) {
567 List<RouteData> forSource = sourceToRoute.get(source);
568 if (forSource == null) {
569 forSource = new ArrayList<RouteData>();
570 sourceToRoute.put(source, forSource);
571 }
572 for (RouteData data : forSource) {
573 if (data.activeFleet == fleet) return data;
574 }
575 return null;
576 }
577
578
579 public void advance(float amount) {
580 float days = Global.getSector().getClock().convertToDays(amount);
581// sourceToRoute.get("salvage_aegea")
582// int empty = 0;
583// int total = 0;
584// for (RouteData curr : routes) {
585// total++;
586// //if (curr.activeFleet != null && curr.activeFleet.getFleetData().getMembersListCopy().isEmpty()) {
587// if (curr.activeFleet != null && !curr.activeFleet.isAlive()) {
588// //if (curr.activeFleet != null) {
589// empty++;
590// }
591// }
592// System.out.println("Empty: " + empty + ", total: " + total);
593// System.out.println("Routes: " + routes.size());
594
595 routesByLocation = null;
596
597 advanceRoutes(days);
599 }
600
601 protected void spawnAndDespawn() {
602 CampaignFleetAPI player = Global.getSector().getPlayerFleet();
603 if (player == null) return;
604
605 //System.out.println("Num routes: " + routes.size());
606 int add = 0;
607 int sub = 0;
608 for (RouteData data : new ArrayList<RouteData>(routes)) {
609 if (data.activeFleet != null && data.activeFleet.getContainingLocation() == player.getContainingLocation()) {
610 VisibilityLevel level = data.activeFleet.getVisibilityLevelToPlayerFleet();
611 if ((level == VisibilityLevel.COMPOSITION_AND_FACTION_DETAILS ||
612 level == VisibilityLevel.COMPOSITION_DETAILS) &&
613 data.activeFleet.wasMousedOverByPlayer()) {
614 data.daysSinceSeenByPlayer = 0f;
615 }
616 }
617
618// if (shouldDespawn(data)) {
619// System.out.println("wfwefwe");
620// }
621 if (shouldDespawn(data)) {
622 //shouldDespawn(data);
623 data.spawner.reportAboutToBeDespawnedByRouteManager(data);
624 data.activeFleet.despawn(FleetDespawnReason.PLAYER_FAR_AWAY, null);
625 if (data.activeFleet.getContainingLocation() != null) {
626 data.activeFleet.getContainingLocation().removeEntity(data.activeFleet);
627 }
628 data.activeFleet = null;
629 sub++;
630
631 //System.out.println("Despawn index: " + routes.indexOf(data));
632 continue;
633 }
634
635// if (shouldSpawn(data)) {
636// System.out.println("wefwef23f23");
637// }
638 if (shouldSpawn(data)) {
639 //shouldSpawn(data);
640 data.activeFleet = data.spawner.spawnFleet(data);
641 if (data.activeFleet != null) {
642 data.activeFleet.addEventListener(this);
643 add++;
644 } else {
645 data.expire();
646 }
647
648// Vector2f interpLoc = data.getInterpolatedHyperLocation();
649// float distLY = Misc.getDistanceLY(interpLoc, player.getLocationInHyperspace());
650// float distLYActual = Misc.getDistanceLY(data.activeFleet.getLocation(), player.getLocationInHyperspace());
651// System.out.println("Dist: " + distLY + ", actual: " + distLYActual);
652 //System.out.println("Spawn index: " + routes.indexOf(data));
653 continue;
654 }
655
656 }
657
658// System.out.println("Add: " + add + ", sub: " + sub);
659// System.out.println("Total: " + Global.getSector().getHyperspace().getFleets().size());
660 }
661
662 protected boolean shouldSpawn(RouteData data) {
663 if (data.delay > 0) return false;
664 if (data.activeFleet != null) return false;
665 //if (true) return true;
666
667// int index = data.getSegments().indexOf(data.getCurrent());
668// if (index <= 0 || data.getCurrent().elapsed < 8f) return false;
669 //if (index <= 3 || data.getCurrent().elapsed < 1f) return false;
670// if (index < 5) return false;
671
672 Vector2f interpLoc = data.getInterpolatedHyperLocation();
673
674 CampaignFleetAPI player = Global.getSector().getPlayerFleet();
675 float distLY = Misc.getDistanceLY(interpLoc, player.getLocationInHyperspace());
676 if (distLY < SPAWN_DIST_LY) return true;
677
678 return false;
679 }
680
681 public static boolean isPlayerInSpawnRange(SectorEntityToken from) {
682 float distLY = Misc.getDistanceLY(from.getLocationInHyperspace(), Global.getSector().getPlayerFleet().getLocationInHyperspace());
683 if (distLY < SPAWN_DIST_LY) return true;
684 return false;
685 }
686
687
688 protected boolean shouldDespawn(RouteData data) {
689 if (data.activeFleet == null) return false;
690 if (data.daysSinceSeenByPlayer < DAYS_SINCE_SEEN_BEFORE_DESPAWN_IF_FAR) return false;
691 if (data.activeFleet.getBattle() != null) return false;
692 if (data.activeFleet.isNoAutoDespawn()) return false;
693
694 //if (true) return false;
695
696 CampaignFleetAPI player = Global.getSector().getPlayerFleet();
697 float distLY = Misc.getDistanceLY(data.activeFleet.getLocationInHyperspace(), player.getLocationInHyperspace());
698
699 if (distLY > DESPAWN_DIST_LY_FAR) return true;
700 if (distLY > DESPAWN_DIST_LY_CLOSE &&
701 data.daysSinceSeenByPlayer > DAYS_SINCE_SEEN_BEFORE_DESPAWN_IF_CLOSE) return true;
702
703 return false;
704 }
705
706 protected void advanceRoutes(float days) {
707
708// int count = 0;
709// for (RouteData curr : routes) {
710// if (curr.activeFleet != null) {
711// count++;
712// }
713// }
714// System.out.println("Active: " + count);
715
716 Iterator<RouteData> iter = routes.iterator();
717 while (iter.hasNext()) {
718 RouteData route = iter.next();
719 //if (route.isSuspended()) continue;
720 boolean delay = route.delay > 0;
721 if (delay) {
722 route.delay -= days;
723 if (route.delay < 0) route.delay = 0;
724 if (route.delay > 0) continue;
725
726 if (route.spawner.shouldCancelRouteAfterDelayCheck(route)) {
727 iter.remove();
728 removeFromMap(route);
729 continue;
730 }
731
732 route.timestamp = Global.getSector().getClock().getTimestamp();
733 }
734
735 if (route.current == null && route.segments.isEmpty()) {
736 iter.remove();
737 removeFromMap(route);
738 continue;
739 }
740
741 if (route.current == null) route.current = route.segments.get(0);
742
743 route.current.elapsed += days;
744 route.daysSinceSeenByPlayer += days;
745 route.elapsed += days;
746
747 if (route.getActiveFleet() != null) continue;
748
749 //if (route.isSuspended()) continue;
750
751 if (route.current.elapsed >= route.current.daysMax) {
752 int index = route.segments.indexOf(route.current);
753 if (index < route.segments.size() - 1) {
754 route.current = route.segments.get(index + 1);
755 } else {
756 if (route.spawner.shouldRepeat(route)) {
757 route.current = null;
758 for (RouteSegment segment : route.segments) {
759 segment.elapsed = 0f;
760 }
761 } else {
762 removeFromMap(route);
763 iter.remove();
764 }
765 }
766 }
767 }
768 }
769
770
771
772 public void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param) {
773 if (reason == FleetDespawnReason.PLAYER_FAR_AWAY) {
774 return;
775 }
776 //((CampaignFleetAPI)fleet).getName()
777 boolean found = false;
778 for (RouteData curr : routes) {
779 if (curr.activeFleet != null && curr.activeFleet == fleet) {
780 if (reason == FleetDespawnReason.PLAYER_FAR_AWAY) {
781 //curr.setSuspended(false);
782 } else {
783 routes.remove(curr);
784 removeFromMap(curr);
785 found = true;
786 }
787 break;
788 }
789 }
790
791// this can happen when route expires while fleet is active
792// if (!found) {
793// System.out.println("NOT FOUND FLEET BEING REMOVED");
794// }
795
796 }
797
798 public void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle) {
799
800 }
801
802}
803
804
static SectorAPI getSector()
Definition Global.java:59
static boolean isPlayerInSpawnRange(SectorEntityToken from)
RouteData addRoute(String source, MarketAPI market, Long seed, OptionalFleetData extra, RouteFleetSpawner spawner)
List< RouteData > getRoutesInLocation(LocationAPI location)
RouteData addRoute(String source, MarketAPI market, Long seed, OptionalFleetData extra, RouteFleetSpawner spawner, Object custom)
transient Map< String, List< RouteData > > sourceToRoute
void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param)
void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle)
RouteData getRoute(String source, CampaignFleetAPI fleet)
transient Map< LocationAPI, List< RouteData > > routesByLocation