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