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