Starsector API
Loading...
Searching...
No Matches
PirateHostileActivityFactor.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.List;
7import java.util.Random;
8
9import java.awt.Color;
10
11import org.lwjgl.util.vector.Vector2f;
12
13import com.fs.starfarer.api.Global;
14import com.fs.starfarer.api.campaign.CampaignFleetAPI;
15import com.fs.starfarer.api.campaign.StarSystemAPI;
16import com.fs.starfarer.api.campaign.comm.IntelInfoPlugin;
17import com.fs.starfarer.api.campaign.comm.IntelInfoPlugin.ListInfoMode;
18import com.fs.starfarer.api.campaign.econ.MarketAPI;
19import com.fs.starfarer.api.impl.campaign.econ.PiracyRespite;
20import com.fs.starfarer.api.impl.campaign.ids.Factions;
21import com.fs.starfarer.api.impl.campaign.intel.bases.PirateBaseIntel;
22import com.fs.starfarer.api.impl.campaign.intel.events.BaseEventIntel.EventStageData;
23import com.fs.starfarer.api.impl.campaign.intel.events.HostileActivityEventIntel.HAERandomEventData;
24import com.fs.starfarer.api.impl.campaign.intel.events.HostileActivityEventIntel.Stage;
25import com.fs.starfarer.api.impl.campaign.intel.group.FleetGroupIntel;
26import com.fs.starfarer.api.impl.campaign.intel.group.FleetGroupIntel.FGIEventListener;
27import com.fs.starfarer.api.impl.campaign.intel.group.GenericRaidFGI;
28import com.fs.starfarer.api.impl.campaign.intel.group.GenericRaidFGI.GenericRaidParams;
29import com.fs.starfarer.api.impl.campaign.missions.FleetCreatorMission;
30import com.fs.starfarer.api.impl.campaign.missions.FleetCreatorMission.FleetStyle;
31import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator;
32import com.fs.starfarer.api.impl.campaign.rulecmd.KantaCMD;
33import com.fs.starfarer.api.ui.TooltipMakerAPI;
34import com.fs.starfarer.api.ui.TooltipMakerAPI.TooltipCreator;
35import com.fs.starfarer.api.util.Misc;
36import com.fs.starfarer.api.util.WeightedRandomPicker;
37
38public class PirateHostileActivityFactor extends BaseHostileActivityFactor implements FGIEventListener {
39
40// public static class HARaidEventData {
41// public SectorEntityToken source;
42// public StarSystemAPI target;
43// }
44
45 public static String RAID_KEY = "$PirateRaid_ref";
46 public static String SMALL_RAID_KEY = "$SmallPirateRaid_ref";
47
48 public static final String DEFEATED_LARGE_PIRATE_RAID = "$defeatedLargePirateRaid";
49
50 public static boolean isDefeatedLargePirateRaid() {
51 //if (true) return true;
53 }
57
58
62
64 return "";
65 }
66
67 @Override
69 if (PiracyRespiteScript.get() != null) {
70 return 0;
71 }
72 return super.getProgress(intel);
73 }
74
75 public String getDesc(BaseEventIntel intel) {
76 return "Pirate activity";
77 }
78
79 public String getNameForThreatList(boolean first) {
80 if (first) return "Pirates";
81 return "Pirates";
82 }
83
84
86 if (getProgress(intel) <= 0) {
87 return Misc.getGrayColor();
88 }
90 }
91
93 return new BaseFactorTooltip() {
94 public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, Object tooltipParam) {
95 float opad = 10f;
96 tooltip.addPara("Piracy follows interstellar civilization almost without exception.", 0f);
98 tooltip.addPara("However, you have %s, which is enough dissuade most pirates from attacking your interests.",
99 opad, Misc.getPositiveHighlightColor(), "Kanta's protection");
100 } else {
102 tooltip.addPara("You've %s, and it's not the sort of thing you can do over.",
103 opad, Misc.getNegativeHighlightColor(), "lost Kanta's protection");
104 } else {
105 tooltip.addPara("Having %s, however, should be enough dissuade most pirates from attacking your interests.",
106 opad, Misc.getHighlightColor(), "Kanta's protection");
107 }
108 }
109 }
110 };
111 }
112
115 }
116
117 @Override
121
122 public Color getNameColor(float mag) {
123 if (mag <= 0f) {
124 return Misc.getGrayColor();
125 }
127 }
128
129 @Override
130 public int getMaxNumFleets(StarSystemAPI system) {
131 if (getProgress(intel) <= 0) {
132 return 1;
133 }
134 return super.getMaxNumFleets(system);
135 }
136
137 public CampaignFleetAPI createFleet(StarSystemAPI system, Random random) {
138
139 float f = 0f;
140 f += getEffectMagnitude(system);
141
142 if (f > 1f) f = 1f;
143
144 int difficulty = 0;
145 difficulty += (int) Math.round(f * 7f);
146
147// int size = 0;
148// for (MarketAPI market : Misc.getMarketsInLocation(system, Factions.PLAYER)) {
149// size = Math.max(market.getSize(), size);
150// }
151// int minDiff = Math.max(0, size - 2);
152
153 float mult = 1f;
154 if (getProgress(intel) <= 0) {
155 mult = 0.5f;
156 }
157
158 int minDiff = Math.round(intel.getMarketPresenceFactor(system) * 6f * mult);
159
160 if (difficulty < minDiff) difficulty = minDiff;
161
162 difficulty += random.nextInt(4);
163
165 m.beginFleet();
166
167 Vector2f loc = system.getLocation();
168 String factionId = Factions.PIRATES;
169
170 m.createStandardFleet(difficulty, factionId, loc);
173 //m.triggerFleetAllowLongPursuit();
174
175 CampaignFleetAPI fleet = m.createFleet();
176
177 return fleet;
178 }
179
180
181
182
184 ListInfoMode mode, boolean isUpdate, Color tc, float initPad) {
185 info.addPara("Rumors of pirate raid", tc, initPad);
186// Color c = Global.getSector().getFaction(Factions.PIRATES).getBaseUIColor();
187// info.addPara("Rumors of pirate raid", initPad, tc, c, "pirate raid");
188 }
189
191 ListInfoMode mode, boolean isUpdate, Color tc, float initPad) {
192 info.addPara("Pirate raid averted", tc, initPad);
193 }
194
196 float small = 0f;
197 float opad = 10f;
198
199 small = 8f;
200// info.addPara("There are rumors that a pirate raid targeting your colonies "
201// + "may be organized in the near future.", opad);
202//
203// info.addPara(BaseIntelPlugin.BULLET + "If the raid is successful, the targeted colonies will suffer from reduced stability.", opad,
204// Misc.getNegativeHighlightColor(), "reduced stability");
205//
206// info.addPara(BaseIntelPlugin.BULLET + "If the raid is defeated, your colonies will gain "
207// + "increased accessibility for several cycles.",
208// 0f, Misc.getPositiveHighlightColor(), "increased accessibility");
209
210 info.addPara("There are rumors that a pirate raid targeting your colonies "
211 + "may be organized in the near future. If the raid is successful, the targeted colonies will "
212 + "suffer from reduced stability.", small,
213 Misc.getNegativeHighlightColor(), "reduced stability");
214
215 if (stage.id == Stage.HA_EVENT) {
217 info.addPara("If the raid is defeated, your colonies will suffer less shipping disruptions from "
218 + "piracy for the foreseeable future.",
219 opad, Misc.getPositiveHighlightColor(), "less shipping disruptions");
220 } else {
222 info.addPara("If the raid is defeated, your colonies will "
223 + "permanently gain increased accessibility.",
224 opad, Misc.getPositiveHighlightColor(), "increased accessibility");
225 } else {
226 info.addPara("If the raid is defeated, your colonies will gain "
227 + "increased accessibility for several cycles.",
228 opad, Misc.getPositiveHighlightColor(), "increased accessibility");
229 }
230 }
231 }
232
233 //if (stage.id == Stage.MINOR_EVENT) {
234 stage.addResetReq(info, false, "crisis", -1, -1, opad);
235// } else {
236// stage.beginResetReqList(info, true, "crisis", opad);
237 // want to keep this less prominent, actually, so: just the above
238// info.addPara("An agreement is reached with Kanta, the pirate queen",
239// 0f, Global.getSector().getFaction(Factions.LUDDIC_PATH).getBaseUIColor(), "Luddic Path");
240// stage.endResetReqList(info, false, "crisis", -1, -1);
241// }
242
243
244
246
247
248// Color c = Global.getSector().getFaction(Factions.PIRATES).getBaseUIColor();
249// UIComponentAPI rect = info.createRect(c, 2f);
250// info.addCustomDoNotSetPosition(rect).getPosition().inTL(-small, 0).setSize(
251// info.getWidthSoFar() + small * 2f, Math.max(64f, info.getHeightSoFar() + small));
252 }
253
254
255 public String getEventStageIcon(HostileActivityEventIntel intel, EventStageData stage) {
257 }
258
259 public TooltipCreator getStageTooltipImpl(final HostileActivityEventIntel intel, final EventStageData stage) {
260 if (stage.id == Stage.HA_EVENT || stage.id == Stage.MINOR_EVENT) {
261 if (stage.id == Stage.MINOR_EVENT) {
262 return new BaseFactorTooltip() {
263 @Override
264 public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, Object tooltipParam) {
265 float opad = 10f;
266 tooltip.addTitle("Pirate raid");
267 tooltip.addPara("A pirate raid will be launched against one of your "
268 + "star systems.", opad);
269 }
270 };
271 }
272 return getDefaultEventTooltip("Pirate raid", intel, stage);
273// return new BaseFactorTooltip() {
274// @Override
275// public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, Object tooltipParam) {
276// float opad = 10f;
277// tooltip.addTitle("Pirate raid");
278// tooltip.addPara("A pirate raid will be launched against one of your "
279// + "star systems.", opad);
283// stage.addResetReq(tooltip, true, "crisis", HostileActivityEventIntel.RESET_MIN, HostileActivityEventIntel.RESET_MAX, opad);
284// }
285// };
286 }
287 return null;
288 }
289
290
291 public float getEventFrequency(HostileActivityEventIntel intel, EventStageData stage) {
292 if (KantaCMD.playerHasProtection()) return 0f;
293
294 if (PiracyRespiteScript.get() != null) return 0f;
295
296 if (stage.id == Stage.HA_EVENT || stage.id == Stage.MINOR_EVENT) {
297 StarSystemAPI target = findRaidTarget(intel, stage);
298 MarketAPI source = findRaidSource(intel, stage, target);
299 if (target != null && source != null) {
300 return 10f;
301 }
302 }
303 return 0f;
304 }
305
306
307// public void resetEvent(HostileActivityEventIntel intel, EventStageData stage) {
308// super.resetEvent(intel, stage);
309// }
310
311 public void rollEvent(HostileActivityEventIntel intel, EventStageData stage) {
312// if (true) return;
313 HAERandomEventData data = new HAERandomEventData(this, stage);
314 stage.rollData = data;
316 }
317
318 public boolean fireEvent(HostileActivityEventIntel intel, EventStageData stage) {
319 StarSystemAPI target = findRaidTarget(intel, stage);
320 MarketAPI source = findRaidSource(intel, stage, target);
321 if (source == null || target == null) {
322 return false;
323 }
324
325 stage.rollData = null;
326 return startRaid(source, target, stage, getRandomizedStageRandom(5));
327 }
328
331
332 for (StarSystemAPI system : Misc.getPlayerSystems(false)) {
333 float mag = getEffectMagnitude(system);
334 if (mag < 0.1f && stage.id != Stage.MINOR_EVENT) {
335 //if (mag < 0.2f) {
336 continue;
337 }
338 picker.add(system, mag * mag);
339 }
340
341 return picker.pick();
342 }
343
344 public MarketAPI findRaidSource(HostileActivityEventIntel intel, EventStageData stage, final StarSystemAPI target) {
345 if (target == null) return null;
346
347 List<MarketAPI> list = new ArrayList<MarketAPI>();
348 float maxDist = Global.getSettings().getFloat("sectorWidth") * 0.5f;
349
351 PirateBaseIntel base = (PirateBaseIntel) curr;
352 if (base.playerHasDealWithBaseCommander()) continue;
353
354 float dist = Misc.getDistance(target.getLocation(), base.getMarket().getLocationInHyperspace());
355 if (dist > maxDist) continue;
356
357 list.add(base.getMarket());
358 }
359
360 for (MarketAPI market : Global.getSector().getEconomy().getMarketsCopy()) {
361 if (Factions.PIRATES.equals(market.getFaction().getId())) {
362 for (MarketAPI other : Misc.getMarketsInLocation(market.getContainingLocation())) {
363 if (other == market) continue;
364 if (!other.getFaction().isHostileTo(market.getFaction())) continue;
365 if (other.getSize() <= market.getSize() - 2) continue;
366
367 float dist = Misc.getDistance(market.getPrimaryEntity().getLocation(), other.getPrimaryEntity().getLocation());
368 if (dist < 8000) continue;
369
370 list.add(market);
371 }
372 }
373 }
374
375 Collections.sort(list, new Comparator<MarketAPI>() {
376 public int compare(MarketAPI m1, MarketAPI m2) {
377 float d1 = Misc.getDistance(target.getLocation(), m1.getLocationInHyperspace());
378 float d2 = Misc.getDistance(target.getLocation(), m2.getLocationInHyperspace());
379 return (int) Math.signum(d1 - d2);
380 }
381 });
382
384 for (int i = 0; i < list.size() && i < 4; i++) {
385 MarketAPI market = list.get(i);
386 float dist = Misc.getDistance(target.getLocation(), market.getLocationInHyperspace());
387 float w = 100000f / (dist * dist);
388 picker.add(market, w);
389 }
390
391 return picker.pick();
392 }
393
394 public static void avertOrAbortRaid() {
395 if (GenericRaidFGI.get(SMALL_RAID_KEY) != null) {
397 }
398
399 if (GenericRaidFGI.get(RAID_KEY) != null) {
401 }
402
404 if (intel == null) return;
405
406 HAERandomEventData data = intel.getRollDataForEvent();
407 if (data != null && data.factor instanceof PirateHostileActivityFactor) {
409 }
410 }
411
412
413 public boolean startRaid(MarketAPI source, StarSystemAPI target, EventStageData stage, Random random) {
414 GenericRaidParams params = new GenericRaidParams(new Random(random.nextLong()), true);
415 params.factionId = source.getFactionId();
416 params.source = source;
417
418 params.prepDays = 7f + random.nextFloat() * 14f;
419 params.payloadDays = 27f + 7f * random.nextFloat();
420
421 params.raidParams.where = target;
422 for (MarketAPI market : Misc.getMarketsInLocation(target)) {
423 if (market.getFaction().isHostileTo(source.getFaction()) || market.getFaction().isPlayerFaction()) {
424 params.raidParams.allowedTargets.add(market);
425 }
426 }
427 if (params.raidParams.allowedTargets.isEmpty()) return false;
428 params.raidParams.allowNonHostileTargets = true;
429
430 params.style = FleetStyle.STANDARD;
431
432 if (stage.id == Stage.MINOR_EVENT) {
433 params.fleetSizes.add(5);
434 params.fleetSizes.add(3);
435 params.memoryKey = SMALL_RAID_KEY;
436 } else {
437 params.memoryKey = RAID_KEY;
438
439 float mag1 = getEffectMagnitude(target);
440 if (mag1 > 1f) mag1 = 1f;
441 float mag2 = intel.getMarketPresenceFactor(target);
442 float totalDifficulty = (0.25f + mag1 * 0.25f + mag2 * 0.5f) * 100f;
443
444 Random r = getRandomizedStageRandom(7);
445 if (r.nextFloat() < 0.33f) {
446 params.style = FleetStyle.QUANTITY;
447 }
448
449 while (totalDifficulty > 0) {
450 float max = Math.min(10f, totalDifficulty * 0.5f);
451 float min = Math.max(2, max - 2);
452 if (max < min) max = min;
453
454 int diff = Math.round(StarSystemGenerator.getNormalRandom(r, min, max));
455
456 params.fleetSizes.add(diff);
457 totalDifficulty -= diff;
458 }
459 }
460
462 if (base != null) {
463 if (Misc.isHiddenBase(source) && !base.isPlayerVisible()) {
464 base.makeKnown();
466 }
467 }
468
469 GenericRaidFGI raid = new GenericRaidFGI(params);
470 if (stage.id == Stage.HA_EVENT) { // don't want piracy respite from the minor raid
471 raid.setListener(this);
472 }
474
475 return true;
476 }
477
482
483
484
485 public static void main(String[] args) {
486 Random r = new Random();
487 int [] counts = new int[11];
488 for (int i = 0; i < 10000; i++) {
489 int x = Math.round(getNormalRandom(r, 7, 10));
490 counts[x]++;
491 }
492 for (int i = 0; i < counts.length; i++) {
493 System.out.println(i + ": " + counts[i]);
494 }
495 }
496
497 public static float getNormalRandom(Random random, float min, float max) {
498 double r = random.nextGaussian();
499 r *= 0.2f;
500 r += 0.5f;
501 if (r < 0) r = 0;
502 if (r > 1) r = 1;
503
504 // 70% chance 0.3 < r < .7
505 // 95% chance 0.1 < r < .7
506 // 99% chance 0 < r < 1
507 return min + (float) r * (max - min);
508 }
509
510}
511
512
513
514
static SettingsAPI getSettings()
Definition Global.java:57
static SectorAPI getSector()
Definition Global.java:65
void sendUpdateIfPlayerHasIntel(Object listInfoParam, TextPanelAPI textPanel)
static PirateBaseIntel getIntelFor(StarSystemAPI system)
TooltipCreator getDefaultEventTooltip(final String title, final HostileActivityEventIntel intel, final EventStageData stage)
float getEventFrequency(HostileActivityEventIntel intel, EventStageData stage)
boolean startRaid(MarketAPI source, StarSystemAPI target, EventStageData stage, Random random)
boolean fireEvent(HostileActivityEventIntel intel, EventStageData stage)
MarketAPI findRaidSource(HostileActivityEventIntel intel, EventStageData stage, final StarSystemAPI target)
StarSystemAPI findRaidTarget(HostileActivityEventIntel intel, EventStageData stage)
String getEventStageIcon(HostileActivityEventIntel intel, EventStageData stage)
void addBulletPointForEventReset(HostileActivityEventIntel intel, EventStageData stage, TooltipMakerAPI info, ListInfoMode mode, boolean isUpdate, Color tc, float initPad)
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 addStageDescriptionForEvent(HostileActivityEventIntel intel, EventStageData stage, TooltipMakerAPI info)
void createStandardFleet(int difficulty, String factionId, Vector2f locInHyper)
static boolean isHiddenBase(MarketAPI market)
Definition Misc.java:6713
static List< MarketAPI > getMarketsInLocation(LocationAPI location, String factionId)
Definition Misc.java:936
static Color getNegativeHighlightColor()
Definition Misc.java:802
static List< StarSystemAPI > getPlayerSystems(boolean includeNonPlayerFaction)
Definition Misc.java:993
static Color getGrayColor()
Definition Misc.java:826
static float getDistance(SectorEntityToken from, SectorEntityToken to)
Definition Misc.java:599
static Color getHighlightColor()
Definition Misc.java:792
static Color getPositiveHighlightColor()
Definition Misc.java:822
FactionAPI getFaction(String factionId)
void set(String key, Object value)
LabelAPI addPara(String format, float pad, Color hl, String... highlights)