Starsector API
Loading...
Searching...
No Matches
LuddicPathCellsIntel.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.intel.bases;
2
3import java.awt.Color;
4import java.util.ArrayList;
5import java.util.Collections;
6import java.util.Comparator;
7import java.util.Iterator;
8import java.util.List;
9import java.util.Random;
10import java.util.Set;
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.FactionAPI;
17import com.fs.starfarer.api.campaign.SectorEntityToken;
18import com.fs.starfarer.api.campaign.comm.IntelInfoPlugin;
19import com.fs.starfarer.api.campaign.econ.Industry;
20import com.fs.starfarer.api.campaign.econ.MarketAPI;
21import com.fs.starfarer.api.campaign.listeners.FleetEventListener;
22import com.fs.starfarer.api.impl.campaign.DebugFlags;
23import com.fs.starfarer.api.impl.campaign.econ.RecentUnrest;
24import com.fs.starfarer.api.impl.campaign.fleets.EconomyFleetAssignmentAI;
25import com.fs.starfarer.api.impl.campaign.fleets.EconomyFleetAssignmentAI.EconomyRouteData;
26import com.fs.starfarer.api.impl.campaign.fleets.EconomyFleetRouteManager;
27import com.fs.starfarer.api.impl.campaign.fleets.RouteLocationCalculator;
28import com.fs.starfarer.api.impl.campaign.fleets.RouteManager;
29import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.OptionalFleetData;
30import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteData;
31import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteFleetSpawner;
32import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteSegment;
33import com.fs.starfarer.api.impl.campaign.ids.Conditions;
34import com.fs.starfarer.api.impl.campaign.ids.Factions;
35import com.fs.starfarer.api.impl.campaign.ids.FleetTypes;
36import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
37import com.fs.starfarer.api.impl.campaign.ids.Tags;
38import com.fs.starfarer.api.impl.campaign.intel.BaseIntelPlugin;
39import com.fs.starfarer.api.impl.campaign.rulecmd.HA_CMD;
40import com.fs.starfarer.api.ui.Alignment;
41import com.fs.starfarer.api.ui.SectorMapAPI;
42import com.fs.starfarer.api.ui.TooltipMakerAPI;
43import com.fs.starfarer.api.util.IntervalUtil;
44import com.fs.starfarer.api.util.Misc;
45import com.fs.starfarer.api.util.WeightedRandomPicker;
46
47public class LuddicPathCellsIntel extends BaseIntelPlugin implements RouteFleetSpawner, FleetEventListener {
48
49 public static String USED_PLANETBUSTER_KEY = "$core_lpUsedPlanetbuster";
50
51 public static float INCIDENT_PROB = Global.getSettings().getFloat("luddicPathCellsIncidentProbabilityPerMonth");
52 public static float MIN_WARNING_DAYS = Global.getSettings().getFloat("luddicPathCellsIncidentWarningMinDays");
53
54// public static float DISRUPTION_MIN = 90;
55// public static float DISRUPTION_RANGE = 60;
56
57 public static float MIN_SABOTAGE = Global.getSettings().getFloatFromArray("luddicPathSabotageDays", 0);
58 public static float MAX_SABOTAGE = Global.getSettings().getFloatFromArray("luddicPathSabotageDays", 1);
59
60
61 public static Object UPDATE_DISSOLVED = new Object();
62 public static Object UPDATE_DISRUPTED = new Object();
63
64 public static Object INCIDENT_PREP = new Object();
65 public static Object INCIDENT_PREVENTED = new Object();
66 public static Object INCIDENT_HAPPENED = new Object();
67
68
69 public static enum IncidentType {
70 REDUCED_STABILITY,
71 INDUSTRY_SABOTAGE,
72 PLANETBUSTER,
73 }
74
75 protected boolean sleeper = false;
76 protected float sleeperTimeout = 0f;
77
78 protected MarketAPI market;
79
80 protected IntervalUtil incidentTracker = new IntervalUtil(20f, 40f);
81 protected Random random = new Random();
82
83 protected int numIncidentAttempts = 0;
84
85 protected float incidentDelay = 0f;
86 protected IncidentType incidentType = null;
87 protected RouteData smuggler = null;
88
89 protected IncidentType prevIncident = null;
90 protected boolean prevIncidentSucceeded = false;
91 protected float sincePrevIncident = 0f;
92 protected Object prevIncidentData = null;
93
94 protected float inertiaTime = 0f; // time the cell has existed despite not being a priority for the LP to maintain
95
96
97 public LuddicPathCellsIntel(MarketAPI market, boolean sleeper) {
98 this.market = market;
99 this.sleeper = sleeper;
100
101 if (!market.isPlayerOwned()) {
102 setPostingLocation(market.getPrimaryEntity());
103 }
104
105 if (!market.hasCondition(Conditions.PATHER_CELLS)) {
106 market.addCondition(Conditions.PATHER_CELLS, this);
107 }
108
109 Global.getSector().addScript(this);
110
111 if (market.isPlayerOwned() || DebugFlags.PATHER_BASE_DEBUG) {
112 Global.getSector().getIntelManager().addIntel(this);
113 } else {
114 Global.getSector().getIntelManager().queueIntel(this);
115 }
116 }
117
118 public static LuddicPathBaseIntel getClosestBase(MarketAPI market) {
119 List<IntelInfoPlugin> bases = Global.getSector().getIntelManager().getIntel(LuddicPathBaseIntel.class);
120 float minDist = Float.MAX_VALUE;
121 LuddicPathBaseIntel closest = null;
122 for (IntelInfoPlugin curr : bases) {
124 float dist = Misc.getDistance(intel.getMarket().getLocationInHyperspace(), market.getLocationInHyperspace());
125 if (dist < minDist) {
126 minDist = dist;
127 closest = intel;
128 }
129 }
130 return closest;
131 }
132
133 public static List<LuddicPathCellsIntel> getCellsForBase(LuddicPathBaseIntel base, boolean includeSleeper) {
134 List<LuddicPathCellsIntel> result = new ArrayList<LuddicPathCellsIntel>();
135
136 List<IntelInfoPlugin> cells = Global.getSector().getIntelManager().getIntel(LuddicPathCellsIntel.class);
137 for (IntelInfoPlugin curr : cells) {
139 if (!includeSleeper && intel.isSleeper()) continue;
140 if (getClosestBase(intel.getMarket()) == base) {
141 result.add(intel);
142 }
143 }
144 return result;
145 }
146
148 if (market == null) return null;
149 List<IntelInfoPlugin> cells = Global.getSector().getIntelManager().getIntel(LuddicPathCellsIntel.class);
150 for (IntelInfoPlugin curr : cells) {
152 if (intel.getMarket() == market) return intel;
153 }
154 return null;
155 }
156
157
158 public MarketAPI getMarket() {
159 return market;
160 }
161
162 @Override
163 public boolean canMakeVisibleToPlayer(boolean playerInRelayRange) {
164 return super.canMakeVisibleToPlayer(playerInRelayRange);
165 }
166
167 @Override
168 protected void notifyEnded() {
169 super.notifyEnded();
170 Global.getSector().removeScript(this);
171 }
172
173
174 @Override
175 protected void notifyEnding() {
176 super.notifyEnding();
177
178 if (market.hasCondition(Conditions.PATHER_CELLS)) {
179 market.removeCondition(Conditions.PATHER_CELLS);
180 }
181 }
182
183
184 public void makeSleeper() {
185 makeSleeper(-1);
186 }
187 public void makeSleeper(float sleeperTimeout) {
188 if (sleeperTimeout >= 0) {
189 this.sleeperTimeout = sleeperTimeout;
190 }
191 sleeper = true;
192 }
193 public void makeActiveIfPossible() {
194 if (sleeperTimeout <= 0) {
195 sleeper = false;
196 }
197 }
198
199
200 @Override
201 protected void advanceImpl(float amount) {
202 super.advanceImpl(amount);
203
204 float days = Misc.getDays(amount);
205
206 inertiaTime += days;
207
208 if (sleeperTimeout > 0) {
209 sleeperTimeout -= days;
210 if (sleeperTimeout < 0) {
211 sleeperTimeout = 0;
212 }
213 }
214
215 if (!market.isInEconomy()) {
217 return;
218 }
219
220 if (isSleeper()) return;
221
222 // incidents handled through HostileActivityEventIntel now
223 // not anymore since the change from Hostile Activity -> Colony Crises
224 //if (market.isPlayerOwned()) return;
225
227 days *= 200f;
228 }
229
230 if (prevIncident != null) {
231 float mult = 1f;
233 mult = 1f / 20f;
234 }
235 sincePrevIncident += days * mult;
236 if (sincePrevIncident >= 180f) {
238 prevIncident = null;
239 prevIncidentData = null;
240 prevIncidentSucceeded = false;
241 }
242 }
243// if (market.isPlayerOwned()) {
244// System.out.println("wefwefwe");
245// }
246 if (incidentType == null && prevIncident == null) {
247 incidentTracker.advance(days);
248 if (incidentTracker.intervalElapsed() && random.nextFloat() < INCIDENT_PROB) {
251 }
252 } else if (incidentType != null) {
253 if (incidentDelay > 0 && smuggler == null) {
254 incidentDelay -= days;
255 }
256
257 if (smuggler == null && incidentDelay <= 0) {
259 }
260// if(market.isPlayerOwned()) {
261// System.out.println("efwwefew");
262// }
263// smuggler.getActiveFleet().getLocation()
264// smuggler.getActiveFleet().getContainingLocation()
265 if (smuggler != null) {
266 RouteSegment segment = smuggler.getCurrent();
267 if (segment != null && segment.getId() == EconomyFleetRouteManager.ROUTE_TRAVEL_SRC) {
268// if(market.isPlayerOwned()) {
269// System.out.println("efwwefew");
270// }
271 doIncident();
272 }
273 }
274 }
275 }
276
277
278 protected void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode) {
279
280 Color h = Misc.getHighlightColor();
281 Color g = Misc.getGrayColor();
282 float pad = 3f;
283 float opad = 10f;
284
285 float initPad = pad;
286 if (mode == ListInfoMode.IN_DESC) initPad = opad;
287
288 Color tc = getBulletColorForMode(mode);
289
290 bullet(info);
291 boolean isUpdate = getListInfoParam() != null;
292
293 if (mode != ListInfoMode.IN_DESC) {
294 addMarketToList(info, market, initPad, tc);
295 initPad = 0f;
296 }
297 //info.addPara(market., initPad)
298
299 if (isUpdate) {
302 info.addPara("Incident averted by local security forces", initPad);
303 } else {
304 switch (prevIncident) {
305 case INDUSTRY_SABOTAGE:
306 Industry ind = (Industry) prevIncidentData;
307 String days = getDays(ind.getDisruptedDays());
308 String daysStr = getDaysString(ind.getDisruptedDays());
309 info.addPara(ind.getCurrentName() + " operations disrupted for %s " + daysStr, initPad, tc, h, days);
310 break;
311 case REDUCED_STABILITY:
312 info.addPara("Stability reduced by %s", initPad, tc, h, "" + (Integer) prevIncidentData);
313 break;
314 case PLANETBUSTER:
315 info.addPara("Colony destroyed by planetbuster", initPad, tc);
316 break;
317 }
318 }
319 }
320 }
321
322 unindent(info);
323 }
324
325 @Override
326 public void createIntelInfo(TooltipMakerAPI info, ListInfoMode mode) {
327 Color c = getTitleColor(mode);
328 info.addPara(getName(), c, 0f);
329 addBulletPoints(info, mode);
330 }
331
332 public void addInterestInfo(TooltipMakerAPI info, float width, float height) {
333 Color h = Misc.getHighlightColor();
334 float opad = 10f;
335
336 info.addSectionHeading("Pather interest", getFactionForUIColors().getBaseUIColor(),
337 getFactionForUIColors().getDarkUIColor(), Alignment.MID, opad);
338
339 info.addPara("The following activity is attracting Pather interest, whether due to AI core use or the inherent nature of the industry:", opad);
340
341 List<Industry> industries = new ArrayList<Industry>(market.getIndustries());
342 Iterator<Industry> iter = industries.iterator();
343 while (iter.hasNext()) {
344 if (iter.next().isHidden()) {
345 iter.remove();
346 }
347 }
348 Collections.sort(industries, new Comparator<Industry>() {
349 public int compare(Industry o1, Industry o2) {
350 float s1 = o1.getPatherInterest();
351 float s2 = o2.getPatherInterest();
352 return (int) Math.signum(s2 - s1);
353 }
354 });
355 String indent = " ";
356 float initPad = 5f;
357 boolean added = false;
358
359 String aiCoreId = market.getAdmin().getAICoreId();
360 if (aiCoreId != null) {
361 int s = (int) Math.round(LuddicPathBaseManager.AI_CORE_ADMIN_INTEREST);
362 if (market.getAdmin().getMemoryWithoutUpdate().getBoolean(MemFlags.SUSPECTED_AI)) {
363 info.addPara(indent + "Suspected AI core administrator (%s)", initPad, h, "" + s);
364 } else {
365 info.addPara(indent + "AI core administrator (%s)", initPad, h, "" + s);
366 }
367 initPad = 3f;
368 added = true;
369 }
370
371 for (Industry ind : industries) {
372 //float score = LuddicPathBaseManager.getLuddicPathMarketInterest(market);
373 float score = ind.getPatherInterest();
374 if (score > 0) {
375 int s = (int) Math.round(score);
376 info.addPara(indent + ind.getCurrentName() + " (%s)", initPad, h, "" + s);
377 initPad = 3f;
378 added = true;
379 }
380 }
381
382
383
384 if (!added) {
385 info.addPara(indent + "None", initPad);
386 }
387
388
389 }
390
391
392 @Override
393 public void createSmallDescription(TooltipMakerAPI info, float width, float height) {
394 Color h = Misc.getHighlightColor();
395 Color g = Misc.getGrayColor();
396 Color tc = Misc.getTextColor();
397 float pad = 3f;
398 float opad = 10f;
399
400 if (width > 0) { // it's 0 when called from market condition tooltip
401 info.addImage(getFactionForUIColors().getLogo(), width, 128, opad);
402 }
403
404 if (isEnding()) {
405 info.addPara("The Pather cells " +
406 market.getOnOrAt() + " " + market.getName() + " have been dissolved.", opad);
407 } else if (isSleeper() && sleeperTimeout <= 0) {
408 info.addPara("There are indications that sleeper Luddic Path cells are being organized " +
409 market.getOnOrAt() + " " + market.getName() + ".", opad);
410 info.addPara("The Pathers have not made any significant moves, but are apparently preparing " +
411 "to do so if whatever activity they object to - industrial development, or the suspected " +
412 "use of AI cores, and other such - continues.", opad);
413 } else {
414 info.addPara("There are active Luddic Path cells " +
415 market.getOnOrAt() + " " + market.getName() + ".", opad);
416// info.addPara("They are engaged in planning acts of terror and industrial sabotage, but " +
417// "need material support - smuggled in from the nearest Pather base - to carry them off."
418// + " The cells also provide intel to Pather fleets operating in-system.", opad);
419 info.addPara("They are engaged in planning acts of terror and industrial sabotage, but " +
420 "are unlikely to carry them off unless the overal level of hostile activity in the system "
421 + "provides sufficient cover."
422 + " The cells also provide intel to Pather fleets operating in-system.", opad);
423
424 if (sleeperTimeout > 0) {
425 int daysNum = (int) Math.round(sleeperTimeout);
426 if (daysNum < 1) daysNum = 1;
427 String days = getDaysString(daysNum);
428 info.addPara("However, the base supporting these cells is no longer operational. " +
429 "It is projected that establishing a new support network will take at least " +
430 "%s " + days + ", provided another base exists.", opad,
431 h,
432 "" + daysNum);
433 } else {
435 if (base != null) {
436 if (base.isPlayerVisible()) {
437 info.addPara("The Pather base at the " + base.getMarket().getStarSystem().getNameWithLowercaseType() +
438 " is providing support to these cells.", opad);
439 } else {
440 info.addPara("You do not know the location of the Pather base providing support to these cells.", opad);
441 }
442
443 info.addPara("If the base is destroyed, it will take some time to organize " +
444 "support from another base, and both ground and fleet operations will be disrupted.", opad);
445 }
446 }
447 }
448
449 if (!isEnding()) {
450 info.addSectionHeading("Impact", getFactionForUIColors().getBaseUIColor(),
451 getFactionForUIColors().getDarkUIColor(), Alignment.MID, opad);
452
453 if (!isSleeper()) {
454 float stability = LuddicPathCells.STABLITY_PENALTY;
455// info.addPara("%s stability. Possibility of various acts of terror and sabotage, " +
456// "if smugglers from a Luddic Path base are able to provide material support.",
457// opad, h,
458// "-" + (int)stability);
459 info.addPara("%s stability.",
460 opad, h,
461 "-" + (int)stability);
462 } else {
463 if (sleeperTimeout <= 0) { // only show for actual sleeper cells, not "disrupted" active cells
464 info.addPara("No perceptible impact on operations as of yet.", opad);
465 } else {
466 info.addPara("No impact on operations due to lack of material support.", opad);
467 }
468 }
469
470 //addInterestInfo(info, width, height);
471 }
472
473 if (prevIncident != null || incidentType == IncidentType.PLANETBUSTER) {
474 info.addSectionHeading("Recent events", getFactionForUIColors().getBaseUIColor(),
475 getFactionForUIColors().getDarkUIColor(), Alignment.MID, opad);
476
478 if (incidentType == IncidentType.PLANETBUSTER) {
479 info.addPara("There are indications that the Pather cells are preparing to sneak " +
480 "a planetbuster onto " + market.getName() + ". " +
481 "If they succeed, the colony will effectively be destroyed.", opad);
482 } else if (prevIncident != null) {
483 switch (prevIncident) {
484 case INDUSTRY_SABOTAGE:
485 if (prevIncidentData instanceof Industry) {
486 Industry ind = (Industry) prevIncidentData;
487 if (ind.getDisruptedDays() > 2) {
488 String days = getDays(ind.getDisruptedDays());
489 String daysStr = getDaysString(ind.getDisruptedDays());
490 info.addPara("The Pather cells have conducted a successful act of sabotage, " +
491 "disrupting " + ind.getCurrentName() + " operations for %s " + daysStr + ".",
492 opad, h, days);
493 }
494 }
495 break;
496 case REDUCED_STABILITY:
497 info.addPara("The Pather cells have conducted low-level attacks on various " +
498 "industrial, military, and civilian targets, reducing stability by %s.",
499 opad, h, "" + (Integer) prevIncidentData);
500 break;
501 case PLANETBUSTER:
502 info.addPara("The Pather cells have smuggled a planetbuster onto " + market.getName() +
503 " and detonated it. The colony has been effectively destroyed.", opad);
504 break;
505 }
506 }
507 } else {
508 if (prevIncident != null) {
509 switch (prevIncident) {
510 case INDUSTRY_SABOTAGE:
511 if (prevIncidentData instanceof Industry) {
512 Industry ind = (Industry) prevIncidentData;
513 info.addPara("An attempted act of sabotage against " +
514 ind.getCurrentName() + " operations was averted by the local security forces.",
515 opad);
516 }
517 break;
518 case REDUCED_STABILITY:
519 info.addPara("Multiple planned attacks against various industrial, " +
520 "military, and civilian targets " +
521 " were averted by the local security forces.",
522 opad);
523 break;
524 case PLANETBUSTER:
525 info.addPara("The Pather cells have smuggled a planetbuster onto " + market.getName() +
526 ", but the local security forces were able to locate and disarm it, thereby " +
527 "saving the colony.", opad);
528 break;
529 }
530 }
531 }
532
533 addBulletPoints(info, ListInfoMode.IN_DESC);
534 }
535
536 if (!isEnding()) {
537 addInterestInfo(info, width, height);
538 }
539 }
540
541 public List<ArrowData> getArrowData(SectorMapAPI map) {
542 if (sleeperTimeout > 0) return null;
543
545 if (base == null || !base.isPlayerVisible()) return null;
546
547 List<ArrowData> result = new ArrayList<ArrowData>();
548
549
550 SectorEntityToken entityFrom = base.getMapLocation(map);
551 if (map != null) {
552 SectorEntityToken iconEntity = map.getIntelIconEntity(base);
553 if (iconEntity != null) {
554 entityFrom = iconEntity;
555 }
556 }
557
558 ArrowData arrow = new ArrowData(entityFrom, market.getPrimaryEntity());
559 arrow.color = getFactionForUIColors().getBaseUIColor();
560 result.add(arrow);
561
562 return result;
563 }
564
565 @Override
566 public String getIcon() {
567 if (isSleeper()) {
568 return Global.getSettings().getSpriteName("intel", "sleeper_cells");
569 }
570 return Global.getSettings().getSpriteName("intel", "active_cells");
571 }
572
573 @Override
574 public Set<String> getIntelTags(SectorMapAPI map) {
575 Set<String> tags = super.getIntelTags(map);
576 tags.add(Factions.LUDDIC_PATH);
577
578 if (market.isPlayerOwned() && !isSleeper()) {
579 tags.add(Tags.INTEL_COLONIES);
580 }
581
582 return tags;
583 }
584
585 public String getSortString() {
586 String base = Misc.ucFirst(getFactionForUIColors().getPersonNamePrefix());
587 if (sleeper) {
588 return base + " D"; // so it goes after "Luddic Path Base"
589 }
590 return base + " C"; // so it goes after "Luddic Path Base"
591 }
592
593 public String getName() {
594 String base = "Luddic Path Cells";
595
596 if (isSendingUpdate()) {
599 return base + " - Incident";
600 } else {
601 return base + " - Incident Averted";
602 }
603 }
604 }
605
606 if (isEnding()) {
607 return base + " - Dissolved";
608 }
609 if (sleeperTimeout > 0) {
610 return base + " - Disrupted";
611 }
612 if (isSleeper()) {
613 return base + " - Sleeper";
614 } else {
615 return base + " - Active";
616 }
617 }
618
619 @Override
620 public FactionAPI getFactionForUIColors() {
621 return Global.getSector().getFaction(Factions.LUDDIC_PATH);
622 }
623
624 public String getSmallDescriptionTitle() {
625 return getName();
626 }
627
628 @Override
629 public SectorEntityToken getMapLocation(SectorMapAPI map) {
630 return market.getPrimaryEntity();
631 }
632
633
634 @Override
635 public String getCommMessageSound() {
636 return super.getCommMessageSound();
637 }
638
639 public boolean isSleeper() {
640 if (Factions.PLAYER.equals(market.getFactionId())) {
641 if (HA_CMD.playerHasPatherAgreement()) {
642 return true;
643 }
644 }
645 return sleeper;
646 }
647
648 public void setSleeper(boolean sleeper) {
649 this.sleeper = sleeper;
650 }
651
652 public float getSleeperTimeout() {
653 return sleeperTimeout;
654 }
655
657 this.sleeperTimeout = sleeperTimeout;
658 }
659
660
661 public String getRouteSourceId() {
662 return EconomyFleetRouteManager.SOURCE_ID;
663 //return "pather_cells_smuggler";
664 }
665
666
667 public void prepareIncident() {
669 //if (incidentType != null) return;
671 if (base == null) return;
672
673 WeightedRandomPicker<IncidentType> types = new WeightedRandomPicker<IncidentType>(random);
674
675 types.add(IncidentType.REDUCED_STABILITY, 10f);
676 if (numIncidentAttempts >= 3 || !market.isPlayerOwned()) {
677 types.add(IncidentType.INDUSTRY_SABOTAGE, 10f);
678 }
679
680// if (numIncidentAttempts >= 10 && market.getSize() >= 5 &&
681// !Global.getSector().getMemory().is(USED_PLANETBUSTER_KEY, true)) {
682// types.add(IncidentType.PLANETBUSTER, 5f);
683// }
684
685 incidentType = types.pick();
686 //incidentType = IncidentType.REDUCED_STABILITY;
688
689
690 if (incidentType == IncidentType.PLANETBUSTER) {
691 incidentDelay = MIN_WARNING_DAYS * 4f + random.nextFloat() * 30f;
692 Global.getSector().getMemoryWithoutUpdate().set(USED_PLANETBUSTER_KEY, true, 1500f);
693 }
694
695// if (market.isPlayerOwned()) {
696// sendUpdateIfPlayerHasIntel(INCIDENT_PREP, false);
697// }
698 }
699
700 public void beginIncident() {
702 if (base == null) {
704 return;
705 }
706
707 sendSmuggler(base);
708 }
709
710 public void abortIncident() {
711 incidentDelay = 0;
712 incidentType = null;
713 if (smuggler != null && smuggler.getActiveFleet() != null) {
714 smuggler.getActiveFleet().removeEventListener(this);
715 }
716 smuggler = null;
717 }
718
719 protected boolean checkSuccess() {
720 float pSuccess = 1f - market.getStabilityValue() * 0.075f;
721 return random.nextFloat() < pSuccess;
722 }
723
724 public void doIncident() {
725 if (incidentType == null) return;
726
727 prevIncidentData = null;
728
729 boolean success = checkSuccess();
730
731 if (incidentType == IncidentType.REDUCED_STABILITY) {
732 if (success) {
733 RecentUnrest.get(market).add(3,
734 Misc.ucFirst(Global.getSector().getFaction(Factions.LUDDIC_PATH).getPersonNamePrefix()) + " sabotage");
736 }
737 } else if (incidentType == IncidentType.INDUSTRY_SABOTAGE) {
738 WeightedRandomPicker<Industry> picker = new WeightedRandomPicker<Industry>(random);
739 for (Industry ind : market.getIndustries()) {
740 if (!ind.canBeDisrupted()) continue;
741 picker.add(ind, ind.getPatherInterest());
742 }
743 Industry target = picker.pick();
744 if (target == null) {
746 return;
747 }
748
749 prevIncidentData = target;
750 if (success) {
751 float disruptionDur = MIN_SABOTAGE + random.nextFloat() * (MAX_SABOTAGE - MIN_SABOTAGE);
752 target.setDisrupted(disruptionDur, true);
753 }
754 } else if (incidentType == IncidentType.PLANETBUSTER) {
755 // ??? turn into lava planet, remove market, etc
756 }
757
760 prevIncidentSucceeded = success;
761
762
763 if (DebugFlags.SEND_UPDATES_WHEN_NO_COMM || Global.getSector().getIntelManager().isPlayerInRangeOfCommRelay()
764 || market.isPlayerOwned()) {
765 if (market.isPlayerOwned() ||
766 incidentType == IncidentType.INDUSTRY_SABOTAGE ||
767 incidentType == IncidentType.PLANETBUSTER) {
769 }
770 }
771
773 }
774
775
776 protected void sendSmuggler(LuddicPathBaseIntel base) {
777 String sid = getRouteSourceId();
778
779 SectorEntityToken from = base.getMarket().getPrimaryEntity();
780 SectorEntityToken to = getMarket().getPrimaryEntity();
781
782 EconomyRouteData data = new EconomyRouteData();
783 data.from = base.getMarket();
784 data.to = market;
785 data.smuggling = true;
786 data.cargoCap = 400;
787 data.fuelCap = 200;
788
789 OptionalFleetData extra = new OptionalFleetData(data.from);
790 extra.fleetType = FleetTypes.TRADE_SMUGGLER;
791
792 RouteData route = RouteManager.getInstance().addRoute(sid, base.getMarket(), Misc.genRandomSeed(), extra, this, data);
793 extra.strength = 50f;
794 extra.strength = Misc.getAdjustedStrength(extra.strength, base.getMarket());
795
796
797 float orbitDays = 3f + random.nextFloat() * 3f;
798 float travelDays = RouteLocationCalculator.getTravelDays(from, to);
799 if (DebugFlags.PATHER_BASE_DEBUG) travelDays *= 0.1f;
800
801 route.addSegment(new RouteSegment(EconomyFleetRouteManager.ROUTE_SRC_LOAD, orbitDays, from));
802 route.addSegment(new RouteSegment(EconomyFleetRouteManager.ROUTE_TRAVEL_DST, travelDays, from, to));
803 route.addSegment(new RouteSegment(EconomyFleetRouteManager.ROUTE_DST_UNLOAD, orbitDays * 0.5f, to));
804 route.addSegment(new RouteSegment(EconomyFleetRouteManager.ROUTE_DST_LOAD, orbitDays * 0.5f, to));
805 route.addSegment(new RouteSegment(EconomyFleetRouteManager.ROUTE_TRAVEL_SRC, travelDays, to, from));
806 route.addSegment(new RouteSegment(EconomyFleetRouteManager.ROUTE_SRC_UNLOAD, orbitDays, from));
807
808 smuggler = route;
809 }
810
811 public void reportAboutToBeDespawnedByRouteManager(RouteData route) {
812
813 }
814
815 public boolean shouldCancelRouteAfterDelayCheck(RouteData route) {
816 return false;
817 }
818
819 public boolean shouldRepeat(RouteData route) {
820 return false;
821 }
822
823 public CampaignFleetAPI spawnFleet(RouteData route) {
824 Random random = new Random();
825 if (route.getSeed() != null) {
826 random = new Random(route.getSeed());
827 }
828
829 CampaignFleetAPI fleet = EconomyFleetRouteManager.createTradeRouteFleet(route, random);
830 if (fleet == null) return null;;
831
832 fleet.getMemoryWithoutUpdate().set(MemFlags.FLEET_DO_NOT_IGNORE_PLAYER, true);
833 fleet.getMemoryWithoutUpdate().set(MemFlags.FLEET_IGNORES_OTHER_FLEETS, true);
834 fleet.addEventListener(this);
835 fleet.addScript(new EconomyFleetAssignmentAI(fleet, route));
836 return fleet;
837 }
838
839 public void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle) {
840 if (smuggler == null || smuggler.getActiveFleet() == null) return;
841
842 CampaignFleetAPI active = smuggler.getActiveFleet();
843 if (!battle.isInvolved(active)) return;
844
845 if (battle.getSideFor(active) != battle.getSideFor(primaryWinner)) {
847 }
848 }
849
850 public void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param) {
851 if (smuggler != null && fleet == smuggler.getActiveFleet()) {
853 }
854 }
855
856 public float getInertiaTime() {
857 return inertiaTime;
858 }
859
860 public void setInertiaTime(float inertiaTime) {
861 this.inertiaTime = inertiaTime;
862 }
863
864
865}
866
867
868
869
870
871
872
static SettingsAPI getSettings()
Definition Global.java:51
static SectorAPI getSector()
Definition Global.java:59
void setPostingLocation(SectorEntityToken postingLocation)
void sendUpdateIfPlayerHasIntel(Object listInfoParam, TextPanelAPI textPanel)
static void addMarketToList(TooltipMakerAPI info, MarketAPI market, float pad)
void createSmallDescription(TooltipMakerAPI info, float width, float height)
void addInterestInfo(TooltipMakerAPI info, float width, float height)
void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle)
void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param)
static List< LuddicPathCellsIntel > getCellsForBase(LuddicPathBaseIntel base, boolean includeSleeper)
String getSpriteName(String category, String id)
float getFloatFromArray(String key, int index)