Starsector API
Loading...
Searching...
No Matches
HostileActivityEventIntel.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.intel.events;
2
3import java.util.ArrayList;
4import java.util.Collections;
5import java.util.Comparator;
6import java.util.Iterator;
7import java.util.LinkedHashMap;
8import java.util.List;
9import java.util.Map;
10import java.util.Set;
11
12import java.awt.Color;
13
14import com.fs.starfarer.api.Global;
15import com.fs.starfarer.api.campaign.BattleAPI;
16import com.fs.starfarer.api.campaign.CampaignEventListener.FleetDespawnReason;
17import com.fs.starfarer.api.campaign.CampaignFleetAPI;
18import com.fs.starfarer.api.campaign.StarSystemAPI;
19import com.fs.starfarer.api.campaign.StoryPointActionDelegate;
20import com.fs.starfarer.api.campaign.econ.EconomyAPI.EconomyUpdateListener;
21import com.fs.starfarer.api.campaign.econ.MarketAPI;
22import com.fs.starfarer.api.campaign.listeners.FleetEventListener;
23import com.fs.starfarer.api.campaign.listeners.ListenerUtil;
24import com.fs.starfarer.api.combat.MutableStatWithTempMods;
25import com.fs.starfarer.api.fleet.FleetMemberAPI;
26import com.fs.starfarer.api.impl.campaign.command.WarSimScript.LocationDanger;
27import com.fs.starfarer.api.impl.campaign.ids.Conditions;
28import com.fs.starfarer.api.impl.campaign.ids.Factions;
29import com.fs.starfarer.api.impl.campaign.ids.Sounds;
30import com.fs.starfarer.api.impl.campaign.ids.Tags;
31import com.fs.starfarer.api.impl.campaign.intel.bases.LuddicPathBaseIntel;
32import com.fs.starfarer.api.impl.campaign.intel.bases.PirateBaseIntel;
33import com.fs.starfarer.api.impl.campaign.rulecmd.HA_CMD;
34import com.fs.starfarer.api.impl.campaign.rulecmd.SetStoryOption.BaseOptionStoryPointActionDelegate;
35import com.fs.starfarer.api.impl.campaign.rulecmd.SetStoryOption.StoryOptionParams;
36import com.fs.starfarer.api.ui.Alignment;
37import com.fs.starfarer.api.ui.ButtonAPI;
38import com.fs.starfarer.api.ui.IntelUIAPI;
39import com.fs.starfarer.api.ui.LabelAPI;
40import com.fs.starfarer.api.ui.SectorMapAPI;
41import com.fs.starfarer.api.ui.TooltipMakerAPI;
42import com.fs.starfarer.api.ui.TooltipMakerAPI.TooltipCreator;
43import com.fs.starfarer.api.ui.TooltipMakerAPI.TooltipLocation;
44import com.fs.starfarer.api.util.Misc;
45import com.fs.starfarer.api.util.WeightedRandomPicker;
46
47public class HostileActivityEventIntel extends BaseEventIntel implements EconomyUpdateListener, FleetEventListener {
48
49 public static enum Stage {
50 START,
51 MINOR_EVENT,
52 HA_EVENT,
53
54 // unused, left in for save compatibility between 0.96a and 0.96.1a, can remove for 0.97a
55 @Deprecated HA_1,
56 @Deprecated HA_2,
57 @Deprecated INCREASED_DEFENSES,
58 @Deprecated HA_3,
59 @Deprecated HA_4,
60 }
61 public static String KEY = "$hae_ref";
62
63 public static String BUTTON_ESCALATE = "button_escalate";
64
65 public static float FP_PER_POINT = Global.getSettings().getFloat("HA_fleetPointsPerPoint");
66
67 public static int MAX_PROGRESS = 600;
68 public static int ESCALATE_PROGRESS = 550;
69
70 public static int RESET_MIN = 0;
71 public static int RESET_MAX = 400;
72
73
74 public static class HAERandomEventData {
75 public HostileActivityFactor factor;
76 public EventStageData stage;
77 public boolean isReset = false;
78 public Object custom;
79 public HAERandomEventData(HostileActivityFactor factor, EventStageData stage) {
80 this.factor = factor;
81 this.stage = stage;
82 }
83
84 }
85
86 public static class HAEFactorDangerData {
87 public HostileActivityFactor factor;
88 public float mag;
89 }
90 public static class HAEStarSystemDangerData {
91 public StarSystemAPI system;
92 public float maxMag;
93 public float totalMag;
94 public float sortMag;
95 public List<HAEFactorDangerData> factorData = new ArrayList<HAEFactorDangerData>();
96 }
97
98
102
103 protected int blowback;
104 protected Map<String, MutableStatWithTempMods> systemSpawnMults = new LinkedHashMap<String, MutableStatWithTempMods>();
105
107 super();
108
109 //Global.getSector().getEconomy().addUpdateListener(this);
110
112
113 setup();
114
115 // now that the event is fully constructed, add it and send notification
117 }
118
119 protected void setup() {
120
121 boolean minorCompleted = false;
122 EventStageData minor = getDataFor(Stage.MINOR_EVENT);
123 if (minor != null) minorCompleted = minor.wasEverReached;
124
125 factors.clear();
126 stages.clear();
127
129 addStage(Stage.START, 0);
130 addStage(Stage.MINOR_EVENT, 300, StageIconSize.MEDIUM);
131 addStage(Stage.HA_EVENT, 600, true, StageIconSize.LARGE);
132
133 setRandomized(Stage.MINOR_EVENT, RandomizedStageType.BAD, 200, 250, false, false);
134 setRandomized(Stage.HA_EVENT, RandomizedStageType.BAD, 425, 500, false);
135
136 minor = getDataFor(Stage.MINOR_EVENT);
137 if (minor != null) {
138 minor.wasEverReached = minorCompleted;
139 }
140
149
150
153
155
158 addActivity(pirate, new StandardPirateActivityCause2(this));
161
165
172
174 }
175
176
177 protected Object readResolve() {
178 if (systemSpawnMults == null) {
179 systemSpawnMults = new LinkedHashMap<String, MutableStatWithTempMods>();
180 }
181 return this;
182 }
183
184 public void redoSetupIfNeeded() {
185 if (getDataFor(Stage.INCREASED_DEFENSES) != null || getMaxProgress() == 500) {// || Global.getSettings().isDevMode()) {
186 setup();
187 }
188 }
189
190
191 @Override
192 protected void notifyEnding() {
193 super.notifyEnding();
196 }
197
198 @Override
199 protected void notifyEnded() {
200 super.notifyEnded();
202 }
203
204
205 protected void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode, boolean isUpdate,
206 Color tc, float initPad) {
207
208 if (addEventFactorBulletPoints(info, mode, isUpdate, tc, initPad)) {
209 return;
210 }
211
212 if (isUpdate && getListInfoParam() instanceof HAERandomEventData) {
213 HAERandomEventData data = (HAERandomEventData) getListInfoParam();
214 if (data.isReset) {
215 data.factor.addBulletPointForEventReset(this, data.stage, info, mode, isUpdate, tc, initPad);
216 } else {
217 data.factor.addBulletPointForEvent(this, data.stage, info, mode, isUpdate, tc, initPad);
218 }
219 return;
220 }
221
222 for (EventStageData stage : stages) {
223 if (stage.rollData instanceof HAERandomEventData) {
224 HAERandomEventData data = (HAERandomEventData) stage.rollData;
225 data.factor.addBulletPointForEvent(this, stage, info, mode, isUpdate, tc, initPad);
226 return;
227 }
228 }
229
230// EventStageData esd = getLastActiveStage(false);
231// if (esd != null && EnumSet.of(Stage.START, Stage.HA_1, Stage.HA_2, Stage.HA_3, Stage.HA_4).contains(esd.id)) {
232// Pair<String, Color> p = getImpactDisplayData((Stage) esd.id);
233// String impact = p.one;
234// Color impactColor = p.two;
238// info.addPara("Colony impact: %s", initPad, tc, impactColor, impact);
239// return;
240// }
241
242 //super.addBulletPoints(info, mode, isUpdate, tc, initPad);
243 }
244
245 public HAERandomEventData getRollDataForEvent() {
246 EventStageData stage = getDataFor(Stage.HA_EVENT);
247 if (stage == null) return null;;
248
249 if (stage.rollData instanceof HAERandomEventData) {
250 HAERandomEventData data = (HAERandomEventData) stage.rollData;
251 return data;
252 }
253 return null;
254 }
255
256 @Override
257 public void addStageDescriptionText(TooltipMakerAPI info, float width, Object stageId) {
258 float opad = 10f;
259 float small = 0f;
260 Color h = Misc.getHighlightColor();
261
262 //setProgress(0);
263 //setProgress(210);
264 //setProgress(600);
265 //setProgress(899);
266// setProgress(424);
267// setProgress(480);
268// setProgress(230);
269// random = new Random();
270// setProgress(260);
271// random = new Random();
272// setProgress(499);
273
274 List<HAEStarSystemDangerData> systemData = computePlayerSystemDangerData();
275
276 EventStageData stage = getDataFor(stageId);
277 if (stage == null) return;
278
279 if (stage.rollData instanceof HAERandomEventData) {
280 HAERandomEventData data = (HAERandomEventData) stage.rollData;
281 data.factor.addStageDescriptionForEvent(this, stage, info);
282 return;
283 }
284
285 if (isStageActiveAndLast(stageId)) {
286 if (stageId == Stage.START) {
287 float delta = getMonthlyProgress();
288
289 if (delta <= 0) {
290 info.addPara("Low-level pirate activity continues, but aside from that, there are "
291 + "no major crises on the horizon.", small);
292 } else {
293 info.addPara("A crisis is virtually inevitable at some point, "
294 + "and hostile fleets continually probe your defenses, but where there is "
295 + "danger, there is often opportunity.", small);
296 }
297// info.addPara("A crisis is virtually inevitable at some point, "
298// + "and hostile fleets continually probe your defenses, but where there is "
299// + "danger, there is often opportunity. A crisis may be averted or delayed by defeating "
300// + "hostile fleets and taking other actions to address the various contributing factors, "
301// + "but another crisis will always be just beyond the horizon.", small);
302 }
303
304 float systemW = 230f;
305 float threatW = 300f;
307 "Star system", systemW,
308 "Danger", 100f,
309 "Primary threats", threatW
310 );
312
313 int maxSystemsToList = 4;
314 int numListed = 0;
315 info.addTableHeaderTooltip(0, "Star system with hostile activity, and the name (or number) of your colonies found there.\n\nUp to four of the hardest-hit systems are listed here.");
316 info.addTableHeaderTooltip(1, "Danger level of the stronger fleets likely to be found in the system. "
317 + "Approximate, there may be exceptions. Does not include hostile fleets that may be present there for other reasons.");
318 info.addTableHeaderTooltip(2, "The most dangerous types of threats likely to be found in the system. "
319 + "Not comprehensive, and does not include hostile fleets that may be present there for other reasons.");
320
321 //List<HAEStarSystemDangerData> systemData = computePlayerSystemDangerData();
322
323 for (final HAEStarSystemDangerData sys : systemData) {
324 if (sys.sortMag <= 0) continue;
325
326 float mag = sys.sortMag;
327 String danger = getDangerString(mag);
328
329 int maxThreats = 3;
330 int count = 0;
331 List<String> threats = new ArrayList<String>();
332 List<Color> colors = new ArrayList<Color>();
333 for (HAEFactorDangerData data : sys.factorData) {
334 if (data.mag <= 0) continue;
335 threats.add(data.factor.getNameForThreatList(count == 0));
336 colors.add(data.factor.getNameColorForThreatList());
337 count++;
338 if (count >= maxThreats) {
339 break;
340 }
341 }
342 String threatStr = Misc.getJoined("", threats);
343
344 LabelAPI label = info.createLabel(threatStr, Misc.getTextColor(), threatW);
345 label.setHighlightColors(colors.toArray(new Color[0]));
346 label.setHighlight(threats.toArray(new String[0]));
347
348 String systemName = sys.system.getNameWithNoType();
349 //String systemName = sys.system.getNameWithLowercaseTypeShort();
350 List<MarketAPI> colonies = Misc.getMarketsInLocation(sys.system, Factions.PLAYER);
351 String colStr = "";
352 if (colonies.size() == 1) {
353 colStr = colonies.get(0).getName();
354 } else {
355 colStr = "" + colonies.size() + " colonies";
356 }
357 systemName += " - " + colStr + "";
358
360 Alignment.MID, getDangerColor(mag), danger,
361 Alignment.MID, null, label);
363 @Override
364 public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, Object tooltipParam) {
365 float w = tooltip.getWidthSoFar();
366 float h = Math.round(w / 1.6f);
367 tooltip.addSectorMap(w, h, sys.system, 0f);
368 tooltip.addPara("Click to open map", Misc.getGrayColor(), 5f);
369 }
370
371 }, TooltipLocation.LEFT, false);
372
373 info.setIdForAddedRow(sys);
374
375 numListed++;
376 if (numListed >= maxSystemsToList) {
377 break;
378 }
379 }
380 info.addTable("None", -1, opad);
381 info.addSpacer(3f);
382 }
383 }
384
385
386
387 @Override
389 int progress = getProgress();
391 float width = getBarWidth();
392 Color color = Misc.getStoryOptionColor();
393 Color dark = Misc.getStoryDarkColor();
394 float bw = 300f;
395 ButtonAPI button = addGenericButton(main, bw, color, dark, "Escalate crisis", BUTTON_ESCALATE);
396 float inset = width - bw;
397 //inset = 0f;
398 button.getPosition().setXAlignOffset(inset);
399 main.addSpacer(0f).getPosition().setXAlignOffset(-inset);
401 button.setEnabled(false);
402 main.addTooltipTo(new TooltipCreator() {
403 @Override
404 public boolean isTooltipExpandable(Object tooltipParam) {
405 return false;
406 }
407 @Override
408 public float getTooltipWidth(Object tooltipParam) {
409 return 450;
410 }
411 @Override
412 public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, Object tooltipParam) {
413 tooltip.addPara("Only available when event progress is below %s points.", 0f,
415 }
416 }, button, TooltipLocation.BELOW);
417 }
418 }
419 }
420
421 public void tableRowClicked(IntelUIAPI ui, TableRowClickData data) {
422 if (data.rowId instanceof HAEStarSystemDangerData) {
423 HAEStarSystemDangerData d = (HAEStarSystemDangerData) data.rowId;
424 List<MarketAPI> m = Misc.getMarketsInLocation(d.system, Factions.PLAYER);
425 if (m.size() == 1) {
426 ui.showOnMap(m.get(0).getPrimaryEntity());
427 } else {
428 ui.showOnMap(d.system.getHyperspaceAnchor());
429 }
430 }
431 }
432
433
434 public TooltipCreator getStageTooltipImpl(Object stageId) {
435 final EventStageData esd = getDataFor(stageId);
436
437 if (esd != null && esd.rollData instanceof HAERandomEventData) {
438 HAERandomEventData data = (HAERandomEventData) esd.rollData;
439 return data.factor.getStageTooltipImpl(this, esd);
440 }
441
442 return null;
443 }
444
445
446
447 @Override
448 public String getIcon() {
449 return Global.getSettings().getSpriteName("events", "hostile_activity");
450 }
451
452
453
454 @Override
455 protected String getStageIcon(Object stageId) {
456 EventStageData esd = getDataFor(stageId);
457 if (esd != null && esd.id == Stage.HA_EVENT && esd.rollData != null && RANDOM_EVENT_NONE.equals(esd.rollData)) {
458 return Global.getSettings().getSpriteName("events", "stage_unknown_neutral");
459 }
460 return super.getStageIcon(stageId);
461 }
462
463 @Override
464 public TooltipCreator getStageTooltip(Object stageId) {
465 final EventStageData esd = getDataFor(stageId);
466 if (esd != null && esd.id == Stage.HA_EVENT && esd.rollData != null && RANDOM_EVENT_NONE.equals(esd.rollData)) {
467 return new TooltipCreator() {
468 public boolean isTooltipExpandable(Object tooltipParam) {
469 return false;
470 }
471 public float getTooltipWidth(Object tooltipParam) {
473 }
474
475 public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, Object tooltipParam) {
476 Color h = Misc.getHighlightColor();
477 tooltip.addPara("There's no crisis on the horizon right now. When this stage is reached, "
478 + "event progress will be reset to a lower value.",
479 0f);
480 }
481 };
482 }
483 return super.getStageTooltip(stageId);
484 }
485
486
487 protected String getStageIconImpl(Object stageId) {
488 EventStageData esd = getDataFor(stageId);
489 if (esd == null) return null;
490
491// if (esd.id == Stage.MINOR_EVENT) {
492// System.out.println("ewfwfew");
493// }
494
495 //setProgress(48);
496 //setProgress(74);
497
498 if (esd.rollData instanceof HAERandomEventData) {
499 HAERandomEventData data = (HAERandomEventData) esd.rollData;
500 return data.factor.getEventStageIcon(this, esd);
501 }
502// if (esd.id == Stage.HA_EVENT) {
503// System.out.println("wefwefwe");
504// }
505 //if (stageId == Stage.START) return null;
506
507 if (esd.id == Stage.START) {
508 return Global.getSettings().getSpriteName("events", "hostile_activity_" + ((Stage)esd.id).name());
509 }
510 // should not happen - the above cases should handle all possibilities - but just in case
511 return Global.getSettings().getSpriteName("events", "hostile_activity");
512 }
513
514
515 @Override
516 public Color getBarColor() {
517 Color color = Misc.getNegativeHighlightColor();
518 //color = Misc.getBasePlayerColor();
519 color = Misc.interpolateColor(color, Color.black, 0.25f);
520 return color;
521 }
522
523 @Override
525 return super.getBarProgressIndicatorColor();
526 }
527
528
529 @Override
530 protected int getStageImportance(Object stageId) {
531// if (stageId == Stage.HA_EVENT) {
532// return 1;
533// }
534// if (stageId == Stage.MINOR_EVENT) {
535// return 1;
536// }
537 return super.getStageImportance(stageId);
538 }
539
540
541
542 @Override
543 protected String getName() {
544 //return "Hostile Activity";
545 return "Colony Crises";
546 }
547
548
550 return true;
551 }
552
553
555 BaseHostileActivityFactor curr = getActivityOfClass(factor.getClass());
556 if (curr == null) {
557 addFactor(factor);
558 curr = factor;
559 }
560 curr.addCause(cause);
561 }
562
563
564 public void removeActivityCause(Class activityClass, Class causeClass) {
565 BaseHostileActivityFactor curr = getActivityOfClass(activityClass);
566 if (curr == null) return;
567
568 HostileActivityCause2 cause = curr.getCauseOfClass(causeClass);
569 if (cause == null) return;
570
571 curr.getCauses().remove(cause);
572
573 if (curr.getCauses().isEmpty()) {
574 removeActivity(curr);
575 }
576 }
577
578 public HostileActivityCause2 getActivityCause(Class activityClass, Class causeClass) {
579 BaseHostileActivityFactor curr = getActivityOfClass(activityClass);
580 if (curr == null) return null;
581
582 HostileActivityCause2 cause = curr.getCauseOfClass(causeClass);
583 if (cause == null) return null;
584
585 return cause;
586 }
587
588
590 factors.remove(plugin);
591 }
592 public void removeActivityOfClass(Class c) {
593 Iterator<EventFactor> iter = factors.iterator();
594 while (iter.hasNext()) {
595 EventFactor curr = iter.next();
596 if (curr.getClass() == c) {
597 iter.remove();
598 }
599 }
600 }
601
603 Iterator<EventFactor> iter = factors.iterator();
604 while (iter.hasNext()) {
605 EventFactor curr = iter.next();
606 if (curr.getClass() == c) {
607 return (BaseHostileActivityFactor) curr;
608 }
609 }
610 return null;
611 }
612
613 public List<HAEStarSystemDangerData> computePlayerSystemDangerData() {
614 List<HAEStarSystemDangerData> systemData = new ArrayList<HAEStarSystemDangerData>();
615 for (StarSystemAPI system : Misc.getPlayerSystems(false)) {
616 HAEStarSystemDangerData data = computeDangerData(system);
617 systemData.add(data);
618 }
619 Collections.sort(systemData, new Comparator<HAEStarSystemDangerData>() {
620 public int compare(HAEStarSystemDangerData o1, HAEStarSystemDangerData o2) {
621 int result = (int) Math.signum(o2.sortMag - o1.sortMag);
622 if (result == 0) {
623 result = (int) Math.signum(o2.totalMag - o1.totalMag);
624 }
625 if (result == 0) {
626 result = (int) Math.signum(o2.system.getId().hashCode() - o1.system.getId().hashCode());
627 }
628 return result;
629 }
630 });
631 return systemData;
632 }
633
634 public HAEStarSystemDangerData computeDangerData(StarSystemAPI system) {
635 HAEStarSystemDangerData data = new HAEStarSystemDangerData();
636 data.system = system;
637
638 float maxMag = 0f;
639 float total = 0f;
640 for (EventFactor factor : factors) {
641 if (factor instanceof BaseHostileActivityFactor) {
642 HAEFactorDangerData curr = new HAEFactorDangerData();
643 curr.factor = (HostileActivityFactor) factor;
644 curr.mag = ((BaseHostileActivityFactor) factor).getEffectMagnitude(system);
645 data.factorData.add(curr);
646 maxMag = Math.max(maxMag, curr.mag);
647 total += curr.mag;
648 }
649 }
650 data.maxMag = maxMag;
651 data.totalMag = total;
652 data.sortMag = data.maxMag * 0.75f + data.totalMag * 0.25f;
653
654 Collections.sort(data.factorData, new Comparator<HAEFactorDangerData>() {
655 public int compare(HAEFactorDangerData o1, HAEFactorDangerData o2) {
656 return (int) Math.signum(o2.mag - o1.mag);
657 }
658 });
659
660 return data;
661 }
662
663 public LocationDanger getDanger(float mag) {
664 if (mag <= 0f) return LocationDanger.NONE;
665 if (mag < 0.25f) return LocationDanger.MINIMAL;
666 if (mag < 0.5f) return LocationDanger.LOW;
667 if (mag < 0.75f) return LocationDanger.MEDIUM;
668 if (mag < 1f) return LocationDanger.HIGH;
669 return LocationDanger.EXTREME;
670 }
671
672 public String getDangerString(float mag) {
673 return getDangerString(getDanger(mag));
674 }
675 public String getDangerString(LocationDanger d) {
676 switch (d) {
677 case EXTREME: return "Extreme";
678 case HIGH: return "High";
679 case MEDIUM: return "Medium";
680 case LOW: return "Low";
681 case MINIMAL: return "Minimal";
682 case NONE: return "None";
683 }
684 return "Unknown";
685 }
686
687 public Color getDangerColor(float mag) {
688 LocationDanger d = getDanger(mag);
689 if (d == LocationDanger.NONE || d == LocationDanger.MINIMAL) {
691 }
692 if (d == LocationDanger.EXTREME || d == LocationDanger.HIGH) {
694 }
695 return Misc.getHighlightColor();
696 }
697
699 float mag = getTotalActivityMagnitude(system, true);
700 //mag *= getProgressFraction();
701 mag *= 0.2f + getMarketPresenceFactor(system) * 0.8f;
702 return mag * 1000f;
703 }
704
705
712 float maxSize = 0;
713 float count = 0;
714 for (MarketAPI market : Misc.getMarketsInLocation(system, Factions.PLAYER)) {
715 maxSize = Math.max(market.getSize(), maxSize);
716 count++;
717 }
718
719 float f = (maxSize - 3f + count - 1f) / 3f;
720
721 float cap = 0.35f;
722 if (maxSize <= 4f) cap = 0.55f;
723 else if (maxSize <= 5f) cap = 0.75f;
724 else cap = 1f;
725
726 if (f < 0f) f = 0f;
727 if (f > cap) f = cap;
728
729 return f;
730 }
731
733 return getTotalActivityMagnitude(system, true);
734 }
735 public float getTotalActivityMagnitude(StarSystemAPI system, boolean capped) {
736 //if (true) return 0.1f;
737 float total = 0f;
738 for (EventFactor factor : factors) {
739 if (factor instanceof BaseHostileActivityFactor) {
740 total += ((BaseHostileActivityFactor) factor).getEffectMagnitude(system);
741 }
742 }
743
744 if (capped && total > 1f) total = 1f;
745
746 total = Math.round(total * 100f) / 100f;
747
748 return total;
749 }
750
751 @Override
752 protected void advanceImpl(float amount) {
753 super.advanceImpl(amount);
754 //blowback = 55;
755 if (systemSpawnMults != null) {
756 float days = Misc.getDays(amount);
757 for (MutableStatWithTempMods stat : systemSpawnMults.values()) {
758 stat.advance(days);
759 }
760 }
761 }
762
764 if (system == null) {
765 return new MutableStatWithTempMods(1f);
766 }
767 if (systemSpawnMults == null) {
768 systemSpawnMults = new LinkedHashMap<String, MutableStatWithTempMods>();
769 }
770
771 String id = system.getId();
772 MutableStatWithTempMods stat = systemSpawnMults.get(id);
773 if (stat == null) {
774 stat = new MutableStatWithTempMods(1f);
775 systemSpawnMults.put(id, stat);
776 }
777 return stat;
778 }
779
781 return getNumFleetsStat(system).getModifiedValue();
782 }
783
784 public void economyUpdated() {
785 cleanUpHostileActivityConditions();
786 }
787
788
790 for (MarketAPI curr : Misc.getPlayerMarkets(false)) {
791 if (curr.hasCondition(Conditions.HOSTILE_ACTIVITY)) {
792 curr.removeCondition(Conditions.HOSTILE_ACTIVITY);
793 }
794 }
795 }
796
797 public boolean isEconomyListenerExpired() {
798 return isEnding() || isEnded();
799 }
800
801 public void commodityUpdated(String commodityId) {
802 }
803
804
805 public void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param) {
806 }
807
808 public void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle) {
809 if (isEnded() || isEnding()) return;
810
811 if (!battle.isPlayerInvolved()) return;
812
814 battle.getPlayerSide().contains(primaryWinner)) {
816 for (CampaignFleetAPI otherFleet : battle.getNonPlayerSideSnapshot()) {
817 if (otherFleet.isStationMode() && otherFleet.getFleetData().getMembersListCopy().isEmpty()) {
818 {
820 if (intel != null && Misc.getStationFleet(intel.getMarket()) == otherFleet &&
821 HA_CMD.baseInvolved(system, intel)) {
822 int tier = intel.getTier().ordinal();
823 if (tier < 0) tier = 0;
824 if (tier > 4) tier = 4;
825 int points = -1 * Global.getSettings().getIntFromArray("HA_pirateBase", tier);
827 addFactor(factor);
828 return;
829 }
830 }
831 {
833 if (intel != null && Misc.getStationFleet(intel.getMarket()) == otherFleet) {
834 float totalInterest = 0f;
835 float activeCells = 0f;
836 for (StarSystemAPI curr : Misc.getPlayerSystems(false)) {
837 totalInterest += StandardLuddicPathActivityCause2.getPatherInterest(curr, 0f, 0f, 1f);
838 activeCells += StandardLuddicPathActivityCause2.getPatherInterest(curr, 0f, 0f, 1f, true);
839 }
840
841 if (totalInterest > 0) {
842 int flat = Global.getSettings().getInt("HA_patherBaseFlat");
843 int perCell = Global.getSettings().getInt("HA_patherBasePerActiveCell");
844 int max = Global.getSettings().getInt("HA_patherBaseMax");
845
846 int points = -1 * Math.min(max, (flat + perCell * (int) Math.round(activeCells)));
848 addFactor(factor);
849 }
850 return;
851 }
852 }
853 }
854 }
855
856 }
857
858 boolean nearAny = false;
859 for (StarSystemAPI system : Misc.getPlayerSystems(false)) {
860 nearAny |= Misc.isNear(primaryWinner, system.getLocation());
861 if (nearAny) break;
862 }
863 if (!nearAny) return;
864
865 float fpDestroyed = 0;
866 CampaignFleetAPI first = null;
867 for (CampaignFleetAPI otherFleet : battle.getNonPlayerSideSnapshot()) {
868 //if (!Global.getSector().getPlayerFaction().isHostileTo(otherFleet.getFaction())) continue;
869 for (FleetMemberAPI loss : Misc.getSnapshotMembersLost(otherFleet)) {
870 fpDestroyed += loss.getFleetPointCost();
871 if (first == null) {
872 first = otherFleet;
873 }
874 }
875 }
876
877 int points = computeProgressPoints(fpDestroyed);
878 if (points > 0) {
879 //points = 700;
880 HAShipsDestroyedFactor factor = new HAShipsDestroyedFactor(-1 * points);
881 //sendUpdateIfPlayerHasIntel(factor, false); // addFactor now sends update
882 addFactor(factor);
883 }
884 }
885
886 public static int computeProgressPoints(float fleetPointsDestroyed) {
887 if (fleetPointsDestroyed <= 0) return 0;
888
889 int points = Math.round(fleetPointsDestroyed / FP_PER_POINT);
890 if (points < 1) points = 1;
891 return points;
892 }
893
894
895 @Override
896 protected void notifyStageReached(EventStageData stage) {
897 if (stage.rollData instanceof HAERandomEventData) {
898 HAERandomEventData data = (HAERandomEventData) stage.rollData;
899 boolean fired = data.factor.fireEvent(this, stage);
900 stage.rollData = null;
901
902 if (stage.id == Stage.HA_EVENT) {
903 int resetProgress = getResetProgress(fired);
904 setProgress(resetProgress);
905 }
906 } else if (stage.id == Stage.HA_EVENT &&
907 (stage.rollData == null || RANDOM_EVENT_NONE.equals(stage.rollData))) {
908 stage.rollData = null;
909 int resetProgress = getResetProgress(false);
910 setProgress(resetProgress);
911 }
912 }
913
914 protected int getResetProgress(boolean fired) {
916 blowback = 0;
917 }
918 int min = RESET_MIN;
919 if (!fired) min = RESET_MAX - 200;
920
921 int resetAdd = random.nextInt(RESET_MAX - min + 1);
922 resetAdd = Math.min(resetAdd, random.nextInt(RESET_MAX - min + 1));
923 int resetProgress = min + resetAdd;
924
925 int add = Math.min(blowback, (int)((RESET_MAX - resetProgress) * 0.5f));
926 if (add > 0) {
927 resetProgress += add;
928 blowback -= add;
929 }
930 return resetProgress;
931 }
932
933 public void resetHA_EVENT() {
934 EventStageData stage = getDataFor(Stage.HA_EVENT);
935 //int resetProgress = stage.progressToRollAt - getRandom().nextInt(100);
936 int resetProgress = getResetProgress(false);
937 resetRandomizedStage(stage);
938 setProgress(resetProgress);
939 }
940
942 EventStageData stage = getDataFor(Stage.HA_EVENT);
943 if (stage != null && stage.rollData instanceof HAERandomEventData &&
944 ((HAERandomEventData)stage.rollData).factor == factor) {
945 resetHA_EVENT();
946 }
947 }
948
949 @Override
950 public void resetRandomizedStage(EventStageData stage) {
951 if (stage.rollData instanceof HAERandomEventData) {
952 HAERandomEventData data = (HAERandomEventData) stage.rollData;
953 data.isReset = true;
954 data.factor.resetEvent(this, stage);
955 }
956 super.resetRandomizedStage(stage);
957 }
958
959 protected HostileActivityFactor prevMajorEventPick = null;
960
961 @Override
962 public void rollRandomizedStage(EventStageData stage) {
963 if (stage.id == Stage.HA_EVENT || stage.id == Stage.MINOR_EVENT) {
964 float total = 0f;
965 for (EventFactor factor : factors) {
966 if (factor instanceof BaseHostileActivityFactor) {
967 total += factor.getProgress(this);
968 }
969 }
970 if (total < 1f) total = 1f;
971 //System.out.println("Random: " + random.nextLong());
973 for (EventFactor factor : factors) {
974 if (factor instanceof BaseHostileActivityFactor) {
976 curr.setRandomizedStageSeed(random.nextLong()); // seed will be reused by .rollEvent()
977 float f = curr.getEventFrequency(this, stage);
978 float w = factor.getProgress(this) / total;
979 if (w > 0) {
980 w = 0.1f + 0.9f * w;
981 }
982 picker.add(curr, f * w);
983 }
984 }
985
986 HostileActivityFactor pick = picker.pickAndRemove();
987 if (stage.id == Stage.HA_EVENT) {
988 if (prevMajorEventPick == pick && !picker.isEmpty()) {
989 pick = picker.pickAndRemove();
990 }
991 prevMajorEventPick = pick;
992 }
993
994 if (pick == null) return;
995
996 stage.rollData = null;
997 pick.rollEvent(this, stage);
998 }
999 }
1000
1001 @Override
1002 public Set<String> getIntelTags(SectorMapAPI map) {
1003 Set<String> tags = super.getIntelTags(map);
1004 tags.add(Tags.INTEL_COLONIES);
1005 return tags;
1006 }
1007
1008
1009
1010 @Override
1011 public void addFactor(EventFactor factor) {
1012 if (factor.isOneTime()) {
1013 int points = factor.getProgress(this);
1014 if (points < 0) {
1015 int p = Math.round(-1f * points * HABlowbackFactor.FRACTION);
1016 p = Math.min(p, getProgress());
1017 if (p > 0) {
1018 addBlowback(p);
1019 }
1020 }
1021 }
1022 super.addFactor(factor);
1023 }
1024
1025 @Override
1027 super.reportEconomyMonthEnd();
1028
1029 if (blowback > 0) {
1030 int amt = Math.round(blowback * HABlowbackFactor.PER_MONTH);
1031
1032 float mult = 1f;
1033 for (EventFactor factor : factors) {
1034 if (factor.isOneTime()) continue;
1035 mult *= factor.getAllProgressMult(this);
1036 }
1037
1038 amt = Math.round(amt * mult);
1039
1040 if (amt < 1) amt = 1;
1041 blowback -= amt;
1042 if (blowback < 0) blowback = 0;
1043 }
1044 }
1045
1046 public void addBlowback(int points) {
1047 if (!HABlowbackFactor.ENABLED) return;
1048 blowback += points;
1049 }
1050 public int getBlowback() {
1052 blowback = 0;
1053 }
1054 return blowback;
1055 }
1056
1057 public void setBlowback(int blowback) {
1058 if (!HABlowbackFactor.ENABLED) return;
1059 this.blowback = blowback;
1060 }
1061
1062 protected String getSoundForOtherUpdate(Object param) {
1063 if (param instanceof HAERandomEventData) {
1064 HAERandomEventData data = (HAERandomEventData) param;
1065 if (data.isReset) return null;
1066 if (data.factor == null) return null;
1067 return data.factor.getEventStageSound(data);
1068 }
1069 return null;
1070 }
1071
1072
1073 @Override
1075 if (Misc.isEasy()) {
1076 return Global.getSettings().getInt("ha_maxMonthlyProgressEasy");
1077 }
1078 return Global.getSettings().getInt("ha_maxMonthlyProgress");
1079 }
1080
1081 public void storyActionConfirmed(Object buttonId, IntelUIAPI ui) {
1082 if (buttonId == BUTTON_ESCALATE) {
1083 ui.recreateIntelUI();
1084 }
1085 }
1086
1088 if (buttonId == BUTTON_ESCALATE) {
1089 StoryOptionParams params = new StoryOptionParams(null, 1, "escalateCrisis",
1091 "Escalated colony crisis");
1092 return new BaseOptionStoryPointActionDelegate(null, params) {
1093 @Override
1094 public void confirm() {
1095 setProgress(ESCALATE_PROGRESS);
1096 }
1097
1098 @Override
1099 public String getTitle() {
1100 return null;
1101 }
1102
1103 @Override
1104 public void createDescription(TooltipMakerAPI info) {
1105 info.setParaInsigniaLarge();
1106 info.addPara("Take certain actions to precipitate a crisis more quickly. Sets event progress "
1107 + "to %s points.", -10f, Misc.getHighlightColor(), "" + (int) ESCALATE_PROGRESS);
1108 info.addSpacer(20f);
1109 super.createDescription(info);
1110 }
1111 };
1112 }
1113 return null;
1114 }
1115
1116}
1117
1118
1119
1120
1121
1122
1123
1124
static SettingsAPI getSettings()
Definition Global.java:57
static SectorAPI getSector()
Definition Global.java:65
static void finishedAddingCrisisFactors(HostileActivityEventIntel intel)
ButtonAPI addGenericButton(TooltipMakerAPI info, float width, String text, Object data)
static LuddicPathBaseIntel getIntelFor(StarSystemAPI system)
static PirateBaseIntel getIntelFor(StarSystemAPI system)
void setRandomized(Object stageId, RandomizedStageType type, int resetAt, int rollAt, boolean sendUpdateWhenReached)
boolean addEventFactorBulletPoints(TooltipMakerAPI info, ListInfoMode mode, boolean isUpdate, Color tc, float initPad)
float getEventFrequency(HostileActivityEventIntel intel, EventStageData stage)
HostileActivityCause2 getActivityCause(Class activityClass, Class causeClass)
void addActivity(BaseHostileActivityFactor factor, HostileActivityCause2 cause)
void addStageDescriptionText(TooltipMakerAPI info, float width, Object stageId)
void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode, boolean isUpdate, Color tc, float initPad)
void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle)
void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param)
static float getPatherInterest(StarSystemAPI system, float multIfNoCells, float multIfSleeper, float multIfActive)
static boolean baseInvolved(StarSystemAPI system, PirateBaseIntel base)
Definition HA_CMD.java:916
static Color getStoryOptionColor()
Definition Misc.java:782
static Color getTextColor()
Definition Misc.java:839
static Color getStoryDarkColor()
Definition Misc.java:773
static List< FleetMemberAPI > getSnapshotMembersLost(CampaignFleetAPI fleet)
Definition Misc.java:748
static List< MarketAPI > getMarketsInLocation(LocationAPI location, String factionId)
Definition Misc.java:936
static Color getNegativeHighlightColor()
Definition Misc.java:802
static String getJoined(String joiner, List< String > strings)
Definition Misc.java:879
static List< StarSystemAPI > getPlayerSystems(boolean includeNonPlayerFaction)
Definition Misc.java:993
static Color getBasePlayerColor()
Definition Misc.java:833
static Color getGrayColor()
Definition Misc.java:826
static float getDays(float amount)
Definition Misc.java:4663
static boolean isNear(SectorEntityToken entity, Vector2f hyperLoc)
Definition Misc.java:4656
static Color getHighlightColor()
Definition Misc.java:792
static CampaignFleetAPI getStationFleet(MarketAPI market)
Definition Misc.java:4571
static List< MarketAPI > getPlayerMarkets(boolean includeNonPlayerFaction)
Definition Misc.java:980
static Color interpolateColor(Color from, Color to, float progress)
Definition Misc.java:1261
static Color getPositiveHighlightColor()
Definition Misc.java:822
static boolean isEasy()
Definition Misc.java:2284
int getIntFromArray(String key, int index)
String getSpriteName(String category, String id)
List< CampaignFleetAPI > getNonPlayerSideSnapshot()
List< CampaignFleetAPI > getPlayerSide()
ListenerManagerAPI getListenerManager()
void removeUpdateListener(EconomyUpdateListener listener)
void set(String key, Object value)
String getEventStageIcon(HostileActivityEventIntel intel, EventStageData stage)
boolean fireEvent(HostileActivityEventIntel intel, EventStageData stage)
void addStageDescriptionForEvent(HostileActivityEventIntel intel, EventStageData stage, TooltipMakerAPI info)
void addBulletPointForEvent(HostileActivityEventIntel intel, EventStageData stage, TooltipMakerAPI info, ListInfoMode mode, boolean isUpdate, Color tc, float initPad)
void addBulletPointForEventReset(HostileActivityEventIntel intel, EventStageData stage, TooltipMakerAPI info, ListInfoMode mode, boolean isUpdate, Color tc, float initPad)
TooltipCreator getStageTooltipImpl(HostileActivityEventIntel intel, EventStageData stage)
void rollEvent(HostileActivityEventIntel intel, EventStageData stage)
void resetEvent(HostileActivityEventIntel intel, EventStageData stage)
void setEnabled(boolean enabled)
void showOnMap(SectorEntityToken token)
void setHighlight(int start, int end)
void setHighlightColors(Color ... colors)
PositionAPI setXAlignOffset(float xAlignOffset)
void addTable(String emptyText, int andMore, float pad)
void addTableHeaderTooltip(int colIndex, TooltipCreator tc)
void addTooltipTo(TooltipCreator tc, UIComponentAPI to, TooltipLocation loc)
UIPanelAPI addSectorMap(float w, float h, StarSystemAPI system, float pad)
LabelAPI createLabel(String str, Color color)
UIPanelAPI beginTable(FactionAPI faction, float itemHeight, Object ... columns)
LabelAPI addPara(String format, float pad, Color hl, String... highlights)
UIComponentAPI addSpacer(float height)
Object addRowWithGlow(Object ... data)
void addTooltipToAddedRow(TooltipCreator tc, TooltipLocation loc)