Starsector API
Loading...
Searching...
No Matches
LuddicPathHostileActivityFactor.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.intel.events;
2
3import java.util.List;
4import java.util.Random;
5
6import java.awt.Color;
7
8import org.lwjgl.util.vector.Vector2f;
9
10import com.fs.starfarer.api.Global;
11import com.fs.starfarer.api.campaign.CampaignFleetAPI;
12import com.fs.starfarer.api.campaign.StarSystemAPI;
13import com.fs.starfarer.api.campaign.comm.CommMessageAPI.MessageClickAction;
14import com.fs.starfarer.api.campaign.comm.IntelInfoPlugin;
15import com.fs.starfarer.api.campaign.comm.IntelInfoPlugin.ListInfoMode;
16import com.fs.starfarer.api.campaign.econ.MarketAPI;
17import com.fs.starfarer.api.campaign.listeners.ListenerUtil;
18import com.fs.starfarer.api.campaign.listeners.PatherCellListener;
19import com.fs.starfarer.api.impl.campaign.ids.Factions;
20import com.fs.starfarer.api.impl.campaign.ids.Sounds;
21import com.fs.starfarer.api.impl.campaign.intel.MessageIntel;
22import com.fs.starfarer.api.impl.campaign.intel.bases.LuddicPathBaseIntel;
23import com.fs.starfarer.api.impl.campaign.intel.bases.LuddicPathBaseManager;
24import com.fs.starfarer.api.impl.campaign.intel.bases.LuddicPathCellsIntel;
25import com.fs.starfarer.api.impl.campaign.intel.events.BaseEventIntel.EventStageData;
26import com.fs.starfarer.api.impl.campaign.intel.events.HostileActivityEventIntel.HAERandomEventData;
27import com.fs.starfarer.api.impl.campaign.intel.events.HostileActivityEventIntel.Stage;
28import com.fs.starfarer.api.impl.campaign.intel.group.FleetGroupIntel;
29import com.fs.starfarer.api.impl.campaign.intel.group.FleetGroupIntel.FGIEventListener;
30import com.fs.starfarer.api.impl.campaign.intel.group.GenericRaidFGI;
31import com.fs.starfarer.api.impl.campaign.intel.group.GenericRaidFGI.GenericRaidParams;
32import com.fs.starfarer.api.impl.campaign.missions.FleetCreatorMission;
33import com.fs.starfarer.api.impl.campaign.missions.FleetCreatorMission.FleetStyle;
34import com.fs.starfarer.api.impl.campaign.rulecmd.HA_CMD;
35import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.MarketCMD.BombardType;
36import com.fs.starfarer.api.ui.LabelAPI;
37import com.fs.starfarer.api.ui.TooltipMakerAPI;
38import com.fs.starfarer.api.ui.TooltipMakerAPI.TooltipCreator;
39import com.fs.starfarer.api.util.Misc;
40import com.fs.starfarer.api.util.WeightedRandomPicker;
41
42public class LuddicPathHostileActivityFactor extends BaseHostileActivityFactor implements PatherCellListener, FGIEventListener {
43
44 public static String DEFEATED_PATHER_EXPEDITION = "$defeatedPatherExpedition";
45
46 public static String ATTACK_KEY = "$PatherAttack_ref";
47
54
55
56 public static class HAPatherCellsEventData {
57 public LuddicPathCellsIntel cells;
58 public MarketAPI market;
59 public float interest;
60 public HAPatherCellsEventData(LuddicPathCellsIntel cells, MarketAPI market) {
61 this.cells = cells;
62 this.market = market;
64 }
65 }
66
72
74 return "";
75 }
76
77 public String getDesc(BaseEventIntel intel) {
78 return "Luddic Path";
79 }
80
81 public String getNameForThreatList(boolean first) {
82 if (first) return "Luddic Path";
83 return "Luddic Path";
84 }
85
86
88 if (getProgress(intel) <= 0) {
89 return Misc.getGrayColor();
90 }
92 }
93
94 @Override
98
100 return new BaseFactorTooltip() {
101 public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, Object tooltipParam) {
102 float opad = 10f;
103
104 tooltip.addPara("Advanced technology and artificial intelligence are anathema to the Luddic Path.", 0f);
105 tooltip.addPara("Most of the Pather fleets are small, engaging in reconnaissance and demanding tithes "
106 + "from unwary travellers, but occasionaly a larger raiding force will make an appearance.", opad);
107
108 addAgreementStatus(tooltip, opad);
109 }
110 };
111 }
112
113 public static void addAgreementStatus(TooltipMakerAPI tooltip, float initPad) {
114 float opad = 10f;
116 Color h = Misc.getHighlightColor();
120 if (days < 1 && days > 0) days = 1;
121 days = Math.round(days);
122 String dStr = "days";
123 if ((int)days == 1) dStr = "day";
124 tooltip.addPara("You've %s a signficant amount to the Pathers, and their fleets and "
125 + "ground-based cells should leave your colonies alone for another %s " + dStr + ".",
126 initPad, new Color[] {p, h}, "tithed", "" + (int)days);
127 } else {
128 tooltip.addPara("You've reached an understanding with the Pathers, and their fleets and "
129 + "ground-based cells should leave your colonies alone in the future, "
130 + "barring unexpected events.",
131 initPad, p, "understanding");
132 }
133 } else {
134 tooltip.addPara("It's possible that you might reach some kind of understanding with the Pathers, "
135 + "provided you find the right people to talk to.", initPad,
136 h, "find the right people");
137
138// LuddicPathBaseIntel base = LuddicPathCellsIntel.getClosestBase(market);
139// tooltip.addPara("If your colony has active Pather cells, destroying the base that's supplying them "
140// + "will also reduce the level of Pather fleet actvity.", opad, h,
141// "destroying the base");
142
143 }
144 }
145
147 //return getProgress(intel) > 0 || HA_CMD.playerHasPatherAgreement();
149 }
150
151
152
153 @Override
154 public int getMaxNumFleets(StarSystemAPI system) {
155 return Global.getSettings().getInt("luddicPathMaxFleets");
156 }
157
158 public CampaignFleetAPI createFleet(StarSystemAPI system, Random random) {
159
160 float f = 0f;
161 f += getEffectMagnitude(system);
162
163 if (f > 1f) f = 1f;
164
165 float p = Global.getSettings().getFloat("luddicPathSmallFleetProb");
166 boolean small = random.nextFloat() < p;
167
168 int difficulty = 0;
169
170 if (small) {
171 difficulty = 1 + random.nextInt(2);
172 } else {
173 difficulty = 3;
174 difficulty += (int) Math.round(f * 5f);
175 difficulty += random.nextInt(6);
176 }
177
178
180 m.beginFleet();
181
182 Vector2f loc = system.getLocation();
183 String factionId = Factions.LUDDIC_PATH;
184
185 if (small) {
186 m.createStandardFleet(difficulty, factionId, loc);
187 } else {
188 m.createStandardFleet(difficulty, factionId, loc);
189 }
190
193
194 if (!small) {
195 //m.triggerFleetPatherNoDefaultTithe();
197 }
198
199 CampaignFleetAPI fleet = m.createFleet();
200
201 return fleet;
202 }
203
204
205 @Override
209
210 public void notifyEventEnding() {
212 }
213
214 public static HAPatherCellsEventData getPatherCellData(EventStageData stage) {
215 if (stage == null) return null;
216 if (stage.rollData instanceof HAERandomEventData) {
217 HAERandomEventData data = (HAERandomEventData) stage.rollData;
218 if (data.custom instanceof HAPatherCellsEventData) {
219 HAPatherCellsEventData attackData = (HAPatherCellsEventData) data.custom;
220 return attackData;
221 }
222 }
223 return null;
224 }
225
226
228 ListInfoMode mode, boolean isUpdate, Color tc, float initPad) {
229
230 HAPatherCellsEventData data = getPatherCellData(stage);
232
233 if (data == null) return;
234
235 LabelAPI label = info.addPara("Signs of a Luddic Path attack targeting %s",
236 initPad, tc, tc, data.market.getName());
237 label.setHighlight("Luddic Path", data.market.getName());
239 }
240
242 ListInfoMode mode, boolean isUpdate, Color tc, float initPad) {
243 info.addPara("Luddic Path attack averted", tc, initPad);
244 }
245
247 HAPatherCellsEventData data = getPatherCellData(stage);
248 if (data == null) return;
249
251
252 float small = 0f;
253 float opad = 10f;
254
255 small = 8f;
256
257 LabelAPI label = info.addPara("There are signs of an impending Luddic Path attack targeting %s."
258 + " If the attack is successful, the colony will suffer a catastrophic saturation bombardment.",
259 small, c, data.market.getName());
260 label.setHighlight(data.market.getName(), "catastrophic saturation bombardment");
262
263
264 info.addPara("This attack represents a significant resource investment by the Pathers. "
265 + "If it is defeated, Luddic Path cells Sector-wide will be disrupted and Pathers will take "
266 + "less interest in your operations in the future.",
267 opad, Misc.getPositiveHighlightColor(), "disrupted", "less interest");
268
269
270 stage.beginResetReqList(info, true, "crisis", opad);
271 label = info.addPara("The Luddic Path cells on %s are disrupted",
272 0f, Misc.getBasePlayerColor(), data.market.getName());
273 label.setHighlight("Luddic Path", data.market.getName());
275
276 info.addPara("An agreement is reached with the Luddic Path",
278 stage.endResetReqList(info, false, "crisis", -1, -1);
279
281 }
282
283
284 public String getEventStageIcon(HostileActivityEventIntel intel, EventStageData stage) {
286 }
287
288 public TooltipCreator getStageTooltipImpl(final HostileActivityEventIntel intel, final EventStageData stage) {
289 if (stage.id == Stage.HA_EVENT) {
290 return getDefaultEventTooltip("Luddic Path attack", intel, stage);
291// return new BaseFactorTooltip() {
292// @Override
293// public void createTooltip(TooltipMakerAPI info, boolean expanded, Object tooltipParam) {
294// float opad = 10f;
295// info.addTitle("Luddic Path attack");
296// HAPatherCellsEventData data = getPatherCellData(stage);
297// if (data == null) return;
298//
299// info.addPara("A Luddic Path task force will target %s and attempt an obital bombardment.",
300// opad, Misc.getBasePlayerColor(), data.market.getName());
301//
302// stage.beginResetReqList(info, true, "crisis", opad);
303// Color c = Global.getSector().getFaction(Factions.LUDDIC_PATH).getBaseUIColor();
304// LabelAPI label = info.addPara("The Luddic Path cells on %s are disrupted",
305// 0f, Misc.getBasePlayerColor(), data.market.getName());
306// label.setHighlight("Luddic Path", data.market.getName());
307// label.setHighlightColors(c, Misc.getBasePlayerColor());
308// stage.endResetReqList(info, true, "crisis",
309// HostileActivityEventIntel.RESET_MIN, HostileActivityEventIntel.RESET_MAX);
310// }
311// };
312 }
313 return null;
314 }
315
316
317 public float getEventFrequency(HostileActivityEventIntel intel, EventStageData stage) {
318 if (HA_CMD.playerHasPatherAgreement()) return 0f;
319
320 if (stage.id == Stage.HA_EVENT) {
321 if (pickTargetMarket() != null) {
322 return 10f;
323 }
324 }
325 return 0;
326 }
327
330 for (MarketAPI market : Misc.getPlayerMarkets(false)) {
331 // to put a damper on shenanigans with establishing and abandoning a colony
332 // with an Alpha Core admin to bait an attack
333 if (market.getDaysInExistence() < 180f && !Global.getSettings().isDevMode()) continue;
334
336 if (cells == null || cells.isSleeper()) continue;
337
339 picker.add(market, w * w);
340 }
341 return picker.pick();
342 }
343
344
345// public void resetEvent(HostileActivityEventIntel intel, EventStageData stage) {
346// super.resetEvent(intel, stage);
350// }
351
352 public void rollEvent(HostileActivityEventIntel intel, EventStageData stage) {
353// if (true) return;
354
355 MarketAPI market = pickTargetMarket();
357 if (market == null || cells == null) return;
358
359 HAERandomEventData data = new HAERandomEventData(this, stage);
360 data.custom = new HAPatherCellsEventData(cells, market);
361 stage.rollData = data;
363 }
364
365 public boolean fireEvent(HostileActivityEventIntel intel, EventStageData stage) {
366 //if (true) return false;
367
368 HAPatherCellsEventData data = getPatherCellData(stage);
369 if (data == null || data.market == null || data.cells == null || data.cells.isSleeper()) {
370 return false;
371 }
372
373 if (!data.market.isInEconomy()) return false;
374
376 if (base == null) return false;
377
378 StarSystemAPI system = data.market.getStarSystem();
379 if (system == null) return false;
380
381 return startRaid(base.getMarket(), data.market, data.interest, system, stage, getRandomizedStageRandom(3));
382 }
383
385// HostileActivityEventIntel intel = HostileActivityEventIntel.get();
386// if (intel == null) return;
387 EventStageData stage = intel.getDataFor(Stage.HA_EVENT);
388 HAPatherCellsEventData data = getPatherCellData(stage);
389 if (data != null && data.cells == cell && stage.rollData != null) {
391 }
392 }
393
394 public static void avertOrAbortAttack() {
395 if (GenericRaidFGI.get(ATTACK_KEY) != null) {
397 }
398
400 if (intel == null) return;
401
402 EventStageData stage = intel.getDataFor(Stage.HA_EVENT);
403 HAPatherCellsEventData data = getPatherCellData(stage);
404 if (data != null && stage.rollData != null) {
406 }
407 }
408
409 public boolean startRaid(MarketAPI source, MarketAPI target, float interest, StarSystemAPI system, EventStageData stage, Random random) {
410
411 GenericRaidParams params = new GenericRaidParams(new Random(random.nextLong()), true);
412 params.factionId = source.getFactionId();
413 params.source = source;
414
415 params.prepDays = 14f + random.nextFloat() * 14f;
416 params.payloadDays = 27f + 7f * random.nextFloat();
417
418 params.raidParams.where = system;
419 params.raidParams.allowedTargets.add(target);
420 params.raidParams.allowNonHostileTargets = true;
421 params.raidParams.setBombardment(BombardType.SATURATION);
422
423 params.style = FleetStyle.STANDARD;
424
425
426 float w = interest;
427 w += Math.max(0f, (target.getSize() - 2)) * 10f;
428 if (w < 0f) w = 0f;
429 if (w > 50f) w = 50f;
430
431 float f = w / 50f;
432 float totalDifficulty = (0.25f + f * 0.75f) * 40f;
433
434 Random r = getRandomizedStageRandom(7);
435 if (r.nextFloat() < 0.33f) {
436 params.style = FleetStyle.QUANTITY;
437 }
438
439 while (totalDifficulty > 0) {
440// float max = Math.min(10f, totalDifficulty * 0.5f);
441// float min = Math.max(2, max - 2);
442// if (max < min) max = min;
443//
444// int diff = Math.round(StarSystemGenerator.getNormalRandom(r, min, max));
445 int diff = (int) Math.min(10f, totalDifficulty);
446 if (diff < 2) diff = 2;
447
448 params.fleetSizes.add(diff);
449 totalDifficulty -= diff;
450 }
451
452
454 if (base != null) {
455 if (Misc.isHiddenBase(source) && !base.isPlayerVisible()) {
456 base.makeKnown();
458 }
459 }
460
461 //PatherAttack raid = new PatherAttack(params);
462 params.memoryKey = ATTACK_KEY;
463 GenericRaidFGI raid = new GenericRaidFGI(params);
464 raid.setListener(this);
466
467 return true;
468 }
469
472
473 MessageIntel msg = new MessageIntel();
474 msg.addLine("Luddic Path cells disrupted", Misc.getBasePlayerColor());
475 msg.setIcon(Global.getSettings().getSpriteName("intel", "sleeper_cells"));
477 Global.getSector().getCampaignUI().addMessage(msg, MessageClickAction.COLONY_INFO);
478
479 List<IntelInfoPlugin> cells = Global.getSector().getIntelManager().getIntel(LuddicPathCellsIntel.class);
480 for (IntelInfoPlugin curr : cells) {
482 //if (cell.getMarket().isPlayerOwned()) {
483 cell.makeSleeper(Global.getSettings().getFloat("patherCellDisruptionDuration"));
484 //cell.sendUpdateIfPlayerHasIntel(LuddicPathCellsIntel.UPDATE_DISRUPTED, false);
486 //}
487 }
488
489 }
490
491}
492
493
494
495
static SettingsAPI getSettings()
Definition Global.java:57
static SectorAPI getSector()
Definition Global.java:65
static void reportCellDisrupted(LuddicPathCellsIntel cell)
void sendUpdateIfPlayerHasIntel(Object listInfoParam, TextPanelAPI textPanel)
static LuddicPathBaseIntel getIntelFor(StarSystemAPI system)
TooltipCreator getDefaultEventTooltip(final String title, final HostileActivityEventIntel intel, final EventStageData stage)
void addStageDescriptionForEvent(HostileActivityEventIntel intel, EventStageData stage, TooltipMakerAPI info)
void addBulletPointForEventReset(HostileActivityEventIntel intel, EventStageData stage, TooltipMakerAPI info, ListInfoMode mode, boolean isUpdate, Color tc, float initPad)
boolean startRaid(MarketAPI source, MarketAPI target, float interest, StarSystemAPI system, EventStageData stage, Random random)
void addBulletPointForEvent(HostileActivityEventIntel intel, EventStageData stage, TooltipMakerAPI info, ListInfoMode mode, boolean isUpdate, Color tc, float initPad)
TooltipCreator getStageTooltipImpl(final HostileActivityEventIntel intel, final EventStageData stage)
void createStandardFleet(int difficulty, String factionId, Vector2f locInHyper)
static boolean isHiddenBase(MarketAPI market)
Definition Misc.java:6713
static Color getNegativeHighlightColor()
Definition Misc.java:802
static Color getBasePlayerColor()
Definition Misc.java:833
static Color getGrayColor()
Definition Misc.java:826
static Color getHighlightColor()
Definition Misc.java:792
static List< MarketAPI > getPlayerMarkets(boolean includeNonPlayerFaction)
Definition Misc.java:980
static Color getPositiveHighlightColor()
Definition Misc.java:822
String getSpriteName(String category, String id)
FactionAPI getFaction(String factionId)
ListenerManagerAPI getListenerManager()
void set(String key, Object value)
void setHighlight(int start, int end)
void setHighlightColors(Color ... colors)
LabelAPI addPara(String format, float pad, Color hl, String... highlights)