Starsector API
Loading...
Searching...
No Matches
DelayedFleetEncounter.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.missions;
2
3import java.util.ArrayList;
4import java.util.Arrays;
5import java.util.List;
6import java.util.Map;
7import java.util.Random;
8
9import org.lwjgl.util.vector.Vector2f;
10
11import com.fs.starfarer.api.Global;
12import com.fs.starfarer.api.campaign.CampaignFleetAPI;
13import com.fs.starfarer.api.campaign.FactionAPI;
14import com.fs.starfarer.api.campaign.FactionAPI.ShipPickMode;
15import com.fs.starfarer.api.campaign.InteractionDialogAPI;
16import com.fs.starfarer.api.campaign.JumpPointAPI;
17import com.fs.starfarer.api.campaign.JumpPointAPI.JumpDestination;
18import com.fs.starfarer.api.campaign.LocationAPI;
19import com.fs.starfarer.api.campaign.PlanetAPI;
20import com.fs.starfarer.api.campaign.SectorEntityToken;
21import com.fs.starfarer.api.campaign.StarSystemAPI;
22import com.fs.starfarer.api.campaign.ai.FleetAIFlags;
23import com.fs.starfarer.api.campaign.econ.MarketAPI;
24import com.fs.starfarer.api.campaign.listeners.GateTransitListener;
25import com.fs.starfarer.api.campaign.rules.MemoryAPI;
26import com.fs.starfarer.api.characters.PersonAPI;
27import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.CustomRepImpact;
28import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActionEnvelope;
29import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActions;
30import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepRewards;
31import com.fs.starfarer.api.impl.campaign.ids.Factions;
32import com.fs.starfarer.api.impl.campaign.ids.Tags;
33import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithSearch;
34import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithSearch.RequiredSystemTags;
35import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers;
36import com.fs.starfarer.api.impl.campaign.missions.hub.MissionTrigger.TriggerAction;
37import com.fs.starfarer.api.impl.campaign.missions.hub.MissionTrigger.TriggerActionContext;
38import com.fs.starfarer.api.impl.campaign.missions.hub.ReqMode;
39import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator;
40import com.fs.starfarer.api.util.Misc;
41import com.fs.starfarer.api.util.Misc.Token;
42import com.fs.starfarer.api.util.WeightedRandomPicker;
43
44public class DelayedFleetEncounter extends HubMissionWithTriggers implements GateTransitListener {
45
46 public static String TRIGGER_REP_LOSS_MINOR = "DFEFWTRepLossMinor";
47 public static String TRIGGER_REP_LOSS_MEDIUM = "DFEFWTRepLossMedium";
48 public static String TRIGGER_REP_LOSS_HIGH = "DFEFWTRepLossHigh";
49
50 public static enum EncounterType {
51 OUTSIDE_SYSTEM,
52 IN_HYPER_EN_ROUTE,
53 JUMP_IN_NEAR_PLAYER,
54 FROM_SOMEWHERE_IN_SYSTEM,
55 }
56
57 public static enum EncounterLocation {
58 ANYWHERE,
59 POPULATED_SYSTEM,
60 NEAR_CORE,
61 MIDRANGE,
62 FRINGE,
63 }
64
65 public static float RADIUS_FROM_CORE = 30000f; // may send fleet when within this radius from core
68 public static float BASE_TIMEOUT = 10f;
69
70 public static float BASE_DELAY_VERY_SHORT = 365f * 0.25f;
71 public static float BASE_DELAY_SHORT = 365f * 0.67f;
72 public static float BASE_DELAY_MEDIUM = 365f * 2f;
73 public static float BASE_DELAY_LONG = 365f * 5f;
74
75 public static float BASE_ONLY_CHECK_IN_SYSTEM_DAYS = 15f;
76
77 public enum Stage {
81 }
82
83 public static float getRandomValue(float base) {
84 return StarSystemGenerator.getNormalRandom(Misc.random, base * 0.75f, base * 1.25f);
85 }
86
87 public static String TIMEOUT_KEY = "$core_dfe_timeout";
88 public static boolean isInTimeout() {
89 return Global.getSector().getMemoryWithoutUpdate().getBoolean(TIMEOUT_KEY);
90 }
91 public static void setTimeout() {
92 Global.getSector().getMemoryWithoutUpdate().set(TIMEOUT_KEY, true, getRandomValue(BASE_TIMEOUT));
93 }
94
95 public class CanSpawnFleetConditionChecker implements ConditionChecker {
96 protected StarSystemAPI lastSystemPlayerWasIn = null;
97 protected float daysInSystem = 0f;
98 protected boolean conditionsMet = false;
99 protected EncounterType typePicked = null;
100 protected Vector2f location;
101 protected SectorEntityToken foundEntity;
102
105
106
107 public boolean conditionsMet() {
108 doCheck();
109 return conditionsMet;
110 }
111
112 public void advance(float amount) {
113 if (conditionsMet) return;
114
115 float days = Global.getSector().getClock().convertToDays(amount);
116 CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
117
118
119 StarSystemAPI curr = playerFleet.getStarSystem();
120 if (curr != null) {
121 if (curr != lastSystemPlayerWasIn) {
122 daysInSystem = 0f;
123 }
125 daysInSystem += days;
126 }
127 }
128
129 public void doCheck() {
130 if (isInTimeout()) return;
131 if (conditionsMet) return;
132
133 CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
134 if (playerFleet.getFleetPoints() > estimatedFleetPoints * playerFleetSizeAbortMult) {
135 return;
136 }
137
138 if (madeGateTransit && initialTransitFrom != null &&
139 Misc.getDistanceLY(initialTransitFrom.getLocation(),
140 playerFleet.getLocationInHyperspace()) > 2f) {
141 return;
142 }
143
144 boolean onlyCheckInSystem = true;
145 StageData stage = getData(currentStage);
146 if (stage != null && stage.elapsed > onlyCheckForSpawnInSystemDays) {
147 onlyCheckInSystem = false;
148 }
149
150
152 if (allowedTypes.contains(EncounterType.IN_HYPER_EN_ROUTE) && !onlyCheckInSystem) {
153 if (playerFleet.isInHyperspace()) {
154 float maxSpeed = Misc.getSpeedForBurnLevel(playerFleet.getFleetData().getBurnLevel());
155 //float threshold = Misc.getSpeedForBurnLevel(15);
156 float currSpeed = playerFleet.getVelocity().length();
157 if (currSpeed >= maxSpeed * 0.9f) {
158 //Misc.findNearestJumpPointThatCouldBeExitedFrom(playerFleet);
159 float dist = getRandomValue(2500f);
160 float dir = Misc.getAngleInDegrees(playerFleet.getVelocity());
161 dir += 75f - 150f * genRandom.nextFloat();
162 location = Misc.getUnitVectorAtDegreeAngle(dir);
163 location.scale(dist);
164 Vector2f.add(location, playerFleet.getLocation(), location);
165 conditionsMet = true;
166 typePicked = EncounterType.IN_HYPER_EN_ROUTE;
167 //getPreviousCreateFleetAction().params.locInHyper = playerFleet.getLocationInHyperspace();
168 return;
169 }
170 }
171 }
172 if (allowedTypes.contains(EncounterType.OUTSIDE_SYSTEM)) {
173 if (playerFleet.isInHyperspace() && daysInSystem > daysBeforeInHyper && lastSystemPlayerWasIn != null) {
174 float dist = Misc.getDistance(lastSystemPlayerWasIn.getLocation(), playerFleet.getLocationInHyperspace());
175 if (dist < 3000f) {
176 conditionsMet = true;
177 typePicked = EncounterType.OUTSIDE_SYSTEM;
178 return;
179 }
180 }
181 }
182 if (allowedTypes.contains(EncounterType.FROM_SOMEWHERE_IN_SYSTEM)) {
183 if (playerFleet.getStarSystem() == lastSystemPlayerWasIn && daysInSystem > daysBeforeInSystem &&
184 lastSystemPlayerWasIn != null) {
185 conditionsMet = true;
186 typePicked = EncounterType.FROM_SOMEWHERE_IN_SYSTEM;
187 return;
188 }
189 }
190 if (allowedTypes.contains(EncounterType.JUMP_IN_NEAR_PLAYER)) {
191 if (playerFleet.getStarSystem() == lastSystemPlayerWasIn && daysInSystem > daysBeforeInSystem &&
192 lastSystemPlayerWasIn != null) {
193 // spawn from:
194 // a nearby jump-point
195 // a gas giant gravity well
196 // a planet gravity well (transverse jump)
197 // a star gravity well
198 SectorEntityToken entity = Misc.findNearestJumpPointTo(playerFleet);
199 if (entity != null) {
200 float dist = Misc.getDistance(playerFleet, entity);
201 if (dist < 3000f) {
202 conditionsMet = true;
203 }
204 }
205 if (!conditionsMet) {
206 entity = Misc.findNearestPlanetTo(playerFleet, true, false);
207 if (entity != null) {
208 float dist = Misc.getDistance(playerFleet, entity);
209 if (dist < 3000f) {
210 conditionsMet = true;
211 }
212 }
213 }
214 // only jump in near gas giants; don't fall back to other planets/stars
215 // it feels too weird/forced if the fleet can just jump in anywhere
216// if (!conditionsMet) {
217// entity = Misc.findNearestPlanetTo(playerFleet, false, false);
218// if (entity != null) {
219// float dist = Misc.getDistance(playerFleet, entity);
220// if (dist < 3000f) {
221// conditionsMet = true;
222// }
223// }
224// }
225// if (!conditionsMet) {
226// entity = Misc.findNearestPlanetTo(playerFleet, false, true);
227// if (entity != null) {
228// float dist = Misc.getDistance(playerFleet, entity);
229// if (dist < 3000f) {
230// conditionsMet = true;
231// }
232// }
233// }
234
235 if (conditionsMet) {
236 foundEntity = entity;
237 typePicked = EncounterType.JUMP_IN_NEAR_PLAYER;
238 return;
239 }
240 }
241 }
242 }
243 }
244
245 protected boolean isPlayerInRightRangeBand(LocationAPI system) {
246 //if (allowedLocations.contains(EncounterLocation.ANYWHERE)) return true;
247 CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
248
249 if (system instanceof StarSystemAPI && system == playerFleet.getContainingLocation()) {
250 if (requiredTags != null) {
251 for (RequiredSystemTags req : requiredTags) {
252 if (!req.systemMatchesRequirement((StarSystemAPI) system)) {
253 return false;
254 }
255 }
256 }
257
258 List<MarketAPI> markets = Misc.getMarketsInLocation(system);
260 MarketAPI largest = null;
261 MarketAPI largestHostile = null;
262 int maxSize = 0;
263 int maxHostileSize = 0;
264 for (MarketAPI market : markets) {
265 if (market.getSize() > maxSize) {
266 largest = market;
267 maxSize = market.getSize();
268 }
269 if (market.getFaction().isHostileTo(requireLargestMarketNotHostileToFaction)) {
270 if (market.getSize() > maxHostileSize) {
271 largestHostile = market;
272 maxHostileSize = market.getSize();
273 }
274 }
275 }
276 if (largestHostile != null && maxHostileSize > maxSize) {
277 return false;
278 }
279 }
280 if (requiredFactionPresence != null) {
281 boolean found = false;
282 for (MarketAPI market : markets) {
283 if (requiredFactionPresence.contains(market.getFactionId())) {
284 found = true;
285 break;
286 }
287 }
288 if (!found) {
289 return false;
290 }
291 }
292 }
293
294 Vector2f coreCenter = new Vector2f();
295
296 float fringeRange = 46000;
297
298 float nearMarketRange = 5000f;
299 boolean nearCoreMarket = false;
300 boolean nearAnyMarket = false;
301 MarketAPI nearest = null;
302 float minDist = Float.MAX_VALUE;
303
304 float count = 0f;
305 for (MarketAPI market : Global.getSector().getEconomy().getMarketsCopy()) {
306 if (market.isHidden()) continue;
307 if (market.getContainingLocation().hasTag(Tags.THEME_CORE_POPULATED)) {
308 Vector2f.add(coreCenter, market.getLocationInHyperspace(), coreCenter);
309 count++;
310
311 if (!nearCoreMarket) {
312 float dist = Misc.getDistance(market.getLocation(), playerFleet.getLocationInHyperspace());
313 nearCoreMarket = dist < nearMarketRange;
314 if (dist < minDist) {
315 nearest = market;
316 minDist = dist;
317 }
318 }
319 } else if (!nearAnyMarket) {
320 float dist = Misc.getDistance(market.getLocation(), playerFleet.getLocationInHyperspace());
321 nearAnyMarket = dist < nearMarketRange;
322 if (dist < minDist) {
323 nearest = market;
324 minDist = dist;
325 }
326 }
327 }
328
329 if ((nearCoreMarket || nearAnyMarket) && !allowInsidePopulatedSystems && nearest != null) {
330 if (!Global.getSector().getPlayerFleet().isInHyperspace() &&
331 system == nearest.getStarSystem()) {
332 return false;
333 }
334 }
335
336
337 if (count > 0) {
338 coreCenter.scale(1f / count);
339 }
340
341 if (nearCoreMarket && allowedLocations.contains(EncounterLocation.NEAR_CORE)) {
342 return true;
343 }
344 if (nearAnyMarket && allowedLocations.contains(EncounterLocation.POPULATED_SYSTEM)) {
345 return true;
346 }
347
348 for (EncounterLocation location : allowedLocations) {
349 if (location == EncounterLocation.NEAR_CORE) continue;
350 if (location == EncounterLocation.POPULATED_SYSTEM) continue;
351
352 //location = EncounterLocation.FRINGE;
353
354 float distFromCore = Misc.getDistance(coreCenter, playerFleet.getLocationInHyperspace());
355
356 if (location == EncounterLocation.MIDRANGE) {
357 if (distFromCore > fringeRange || nearCoreMarket) {
358 continue;
359 }
360 }
361
362 if (location == EncounterLocation.FRINGE) {
363 if (distFromCore < fringeRange || nearCoreMarket) {
364 continue;
365 }
366 }
367
368 return true;
369 }
370 return false;
371 }
372 }
373
374 public class DFEPlaceFleetAction implements TriggerAction {
376 }
377
378 public void doAction(TriggerActionContext context) {
379 setTimeout();
380
381// protected EncounterType typePicked = null;
382// protected Vector2f location;
383// protected SectorEntityToken foundEntity;
384 CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
385 playerFleet.getContainingLocation().addEntity(context.fleet);
386
387 if (checker.typePicked == EncounterType.OUTSIDE_SYSTEM) {
388 Vector2f loc = Misc.getPointAtRadius(playerFleet.getLocationInHyperspace(), 1000f);
389 context.fleet.setLocation(loc.x, loc.y);
390 } else if (checker.typePicked == EncounterType.FROM_SOMEWHERE_IN_SYSTEM) {
391 WeightedRandomPicker<MarketAPI> from = new WeightedRandomPicker<MarketAPI>(genRandom);
392 for (MarketAPI curr : Global.getSector().getEconomy().getMarkets(playerFleet.getContainingLocation())) {
393 float w = 0f;
394 if (curr.getFaction() == context.fleet.getFaction()) {
395 w = curr.getSize() * 10000f;
396 } else if (!curr.getFaction().isHostileTo(context.fleet.getFaction())) {
397 w = curr.getSize();
398 }
399 if (w > 0f) {
400 from.add(curr, w);
401 }
402 }
403 MarketAPI market = from.pick();
404 if (market != null) {
405 float dir = Misc.getAngleInDegrees(playerFleet.getLocation(), market.getPrimaryEntity().getLocation());
406 Vector2f loc = HubMissionWithTriggers.pickLocationWithinArc(genRandom, playerFleet,
407 dir, 30f, 3000f, 3000f, 3000f);
408 context.fleet.setLocation(loc.x, loc.y);
409 } else {
410 Vector2f loc = Misc.getPointAtRadius(playerFleet.getLocation(), 3000f);
411 context.fleet.setLocation(loc.x, loc.y);
412 }
413 } else if (checker.typePicked == EncounterType.JUMP_IN_NEAR_PLAYER) {
414 JumpDestination dest = new JumpDestination(checker.foundEntity, null);
415 if (checker.foundEntity instanceof JumpPointAPI) {
416 JumpPointAPI jp = (JumpPointAPI) checker.foundEntity;
417 jp.open();
418 context.fleet.setLocation(jp.getLocation().x, jp.getLocation().y);
419 } else if (checker.foundEntity instanceof PlanetAPI) {
420 dest.setMinDistFromToken(checker.foundEntity.getRadius() + 50f);
421 dest.setMaxDistFromToken(checker.foundEntity.getRadius() + 400f);
422 }
423 context.fleet.updateFleetView(); // so that ship views exist and can do the jump-in warping animation
424 context.fleet.getContainingLocation().removeEntity(context.fleet);
425 Global.getSector().getHyperspace().addEntity(context.fleet);
426 context.fleet.setLocation(1000000000, 0);
427 Global.getSector().doHyperspaceTransition(context.fleet, null, dest);
428 } else if (checker.typePicked == EncounterType.IN_HYPER_EN_ROUTE) {
429 context.fleet.setLocation(checker.location.x, checker.location.y);
430 }
431
432
433 // this is only relevant if an intercept isn't ordered; the triggerIntercept method sets this
434 // as well.
435 float radius = 2000f * (0.5f + 0.5f * genRandom.nextFloat());
436 Vector2f approximatePlayerLoc = Misc.getPointAtRadius(playerFleet.getLocation(), radius);
437 context.fleet.getMemoryWithoutUpdate().set(FleetAIFlags.PLACE_TO_LOOK_FOR_TARGET, approximatePlayerLoc, 2f);
438 }
439 }
440
441
442 protected float minDelay;
443 protected float maxDelay;
445 protected String globalEndFlag;
446
447 protected List<EncounterType> allowedTypes = new ArrayList<EncounterType>();
448 protected List<EncounterLocation> allowedLocations = new ArrayList<EncounterLocation>();
449 protected boolean allowInsidePopulatedSystems = true;
451 protected List<String> requiredFactionPresence = null;
452 protected List<RequiredSystemTags> requiredTags = null;
453
454 protected boolean canBeAvoidedByGateTransit = true;
455 protected boolean madeGateTransit = false;
456 protected LocationAPI initialTransitFrom = null;
457
459
460 public DelayedFleetEncounter(Random random, String missionId) {
461 if (random == null) random = new Random(Misc.genRandomSeed());
462 setGenRandom(random);
463 setNoRepChanges();
464 globalEndFlag = "$" + "dfe"+ "_" + missionId + "_" + Misc.genUID();
465 setMissionId(missionId);
466
467 setTypes(EncounterType.OUTSIDE_SYSTEM, EncounterType.JUMP_IN_NEAR_PLAYER, EncounterType.IN_HYPER_EN_ROUTE);
468 // don't, since in-system attacks are a jump-in near the player, so it's probably fine anyway
469 // and possibly interesting if not fine
470 //requireDFESystemTags(ReqMode.NOT_ANY, Tags.THEME_UNSAFE);
471
472 onlyCheckForSpawnInSystemDays = BASE_ONLY_CHECK_IN_SYSTEM_DAYS * (0.5f + genRandom.nextFloat());
473 Global.getSector().getListenerManager().addListener(this);
474 }
475
479
480 public void reportFleetTransitingGate(CampaignFleetAPI fleet, SectorEntityToken gateFrom, SectorEntityToken gateTo) {
481 if (!fleet.isPlayerFleet() || gateFrom == null) return;
482
483 if (getCurrentStage() == Stage.WAITING &&
484 getElapsedInCurrentStage() < waitDays * 0.9f) {
485 return;
486 }
487
488 float dist = Misc.getDistanceLY(gateFrom, gateTo);
489 if (dist > 2f) {
490 madeGateTransit = true;
491 }
492 if (initialTransitFrom == null) {
493 initialTransitFrom = gateFrom.getContainingLocation();
494 }
495 }
496
497 @Override
498 protected void notifyEnding() {
499 super.notifyEnding();
500 Global.getSector().getListenerManager().removeListener(this);
501 }
502
504 this.allowInsidePopulatedSystems = allowInsidePopulatedSystems;
505 }
507 this.requireLargestMarketNotHostileToFaction = requireLargestMarketNotHostileToFaction;
508 }
509 public void setRequireFactionPresence(String ... factions) {
510 if (factions == null || factions.length <= 0) {
512 } else {
513 requiredFactionPresence = new ArrayList<String>();
514 requiredFactionPresence.addAll(Arrays.asList(factions));
515 }
516 }
517
519 requiredTags = null;
520 }
521 public void requireDFESystemTags(ReqMode mode, String ... tags) {
522 if (requiredTags == null) {
523 requiredTags = new ArrayList<HubMissionWithSearch.RequiredSystemTags>();
524 }
525 RequiredSystemTags req = new RequiredSystemTags(mode, tags);
526 requiredTags.add(req);
527 }
528
529 public void setEncounterInHyper() {
530 setTypes(EncounterType.OUTSIDE_SYSTEM, EncounterType.IN_HYPER_EN_ROUTE);
531 }
533 setTypes(EncounterType.OUTSIDE_SYSTEM);
534 }
536 setTypes(EncounterType.JUMP_IN_NEAR_PLAYER);
537 }
539 setTypes(EncounterType.FROM_SOMEWHERE_IN_SYSTEM);
540 }
542 setTypes(EncounterType.IN_HYPER_EN_ROUTE);
543 }
544
545 public void setTypes(EncounterType ... types) {
546 allowedTypes.clear();
547 allowedTypes.addAll(Arrays.asList(types));
548 }
556
557 public void setDelay(float minDays, float maxDays) {
558 this.minDelay = minDays;
559 this.maxDelay = maxDays;
560 }
561
562 public void setDelay(float base) {
563 this.minDelay = base * 0.5f;
564 this.maxDelay = base * 1.5f;
565 }
566
571
576
581
586
591
596
597
598 public void setDelayNone() {
599 setDelay(0f);
600 }
601
605
606 public void setDelayShort() {
608 }
609
610 public void setDelayMedium() {
612 }
613
614 public void setDelayLong() {
616 }
617
619 triggerMakeHostileAndAggressive();
620 triggerFleetAllowLongPursuit();
621 triggerSetFleetAlwaysPursue();
622 triggerOrderFleetInterceptPlayer();
623 triggerOrderFleetMaybeEBurn();
624 }
625
626
627 @Override
628 protected void advanceImpl(float amount) {
629 super.advanceImpl(amount);
630
631 //System.out.println("Wait: " + waitDays);
632
633 if (getCurrentStage() == Stage.SPAWN_FLEET && checker != null) {
634 checker.advance(amount);
635 }
636
637 }
638
639 protected float waitDays;
640 public void beginCreate() {
642
643 if (minDelay <= 0 && maxDelay <= 0) {
644 // this check does NOT apply to in hyper in route
645 // so, if "immediate" spawn, assuming all encounter types are allowed:
646 // - wait a bit before spawning when player exits system
647 // - wait a bit longer before it jumps into the system
648 // - and wait a little bit (i.e. only check in-system spawn) before spawning in-hyper-en-route
649 checker.daysBeforeInHyper = (0.5f + (0.5f + genRandom.nextFloat())) * 2f;
650 checker.daysBeforeInSystem = (0.5f + (0.5f + genRandom.nextFloat())) * 3f;
651 onlyCheckForSpawnInSystemDays = 0.5f + (0.5f + genRandom.nextFloat());
652 }
653
654 waitDays = minDelay + (maxDelay - minDelay) * genRandom.nextFloat();
655 connectWithDaysElapsed(Stage.WAITING, Stage.SPAWN_FLEET, waitDays);
656 setStartingStage(Stage.WAITING);
657 setSuccessStage(Stage.ENDED);
658 setStageOnGlobalFlag(Stage.ENDED, globalEndFlag);
659
660 setStageOnCustomCondition(Stage.ENDED, new ConditionChecker() {
661 public boolean conditionsMet() {
662 CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
663 // abort if player is too strong
664 if (playerFleet.getFleetPoints() > estimatedFleetPoints * playerFleetSizeAbortMult) {
665 if ((getCurrentStage() == Stage.WAITING &&
666 getElapsedInCurrentStage() > waitDays * 0.9f) ||
667 getCurrentStage() == Stage.SPAWN_FLEET) {
668 return true;
669 }
670 return false;
671 }
672
673 // abort if player made a gate transit shortly before the encounter would trigger
674 // the "shortly before" part is handled in reportFleetTransitingGate()
675 // and also check that they didn't transit back to their original location
676 if (madeGateTransit && initialTransitFrom != null &&
677 Misc.getDistanceLY(initialTransitFrom.getLocation(),
678 playerFleet.getLocationInHyperspace()) > 2f) {
679 return true;
680 }
681 return false;
682 }
683 });
684
685 beginCustomTrigger(checker, Stage.SPAWN_FLEET);
686 triggerMakeAllFleetFlagsPermanent();
687 }
688
689 public void endCreate() {
690 triggerSetGlobalMemoryValue(globalEndFlag, true);
691 triggerCustomAction(new DFEPlaceFleetAction());
692 endTrigger();
693 accept(null, null);
694 }
695
696
697 public void triggerSetAdjustStrengthBasedOnQuality(boolean randomize, float quality) {
698 if (randomize) {
699 triggerRandomizeFleetProperties();
700 }
701 setQuality(quality);
702 setUseQualityInsteadOfQualityFraction(true);
703 triggerAutoAdjustFleetStrengthMajor();
704 setUseQualityInsteadOfQualityFraction(false);
705 }
706
707 protected PersonAPI personForRepLoss = null;
708 public void setFleetWantsThing(String originalFactionId,
709 String thing,
710 String thingItOrThey,
711 String thingDesc,
712 int paymentOffered,
713 boolean aggressiveIfDeclined,
714 ComplicationRepImpact repImpact,
715 String failTrigger,
716 PersonAPI personForRepLoss) {
717
718 this.personForRepLoss = personForRepLoss;
719
720 triggerSetFleetMissionRef("$" + getMissionId() + "_ref");
721 triggerSetFleetMissionRef("$fwt_ref");
722
723 if (aggressiveIfDeclined) {
724 triggerSetPirateFleet();
725 triggerMakeHostileAndAggressive();
726 }
727
728 if (repImpact == ComplicationRepImpact.LOW) {
729 triggerMakeLowRepImpact();
730 } else if (repImpact == ComplicationRepImpact.NONE) {
731 triggerMakeNoRepImpact();
732 }
733
734 triggerFleetAllowLongPursuit();
735 triggerSetFleetAlwaysPursue();
736
737 FactionAPI faction = Global.getSector().getFaction(originalFactionId);
738 if (faction.getCustomBoolean(Factions.CUSTOM_SPAWNS_AS_INDEPENDENT)) {
739 triggerSetFleetFaction(Factions.INDEPENDENT);
740 triggerSetFleetMemoryValue("$fwt_originalFaction", originalFactionId);
741 }
742
743 triggerSetFleetMemoryValue("$fwt_wantsThing", true);
744 triggerSetFleetMemoryValue("$fwt_aggressive", aggressiveIfDeclined);
745 triggerSetFleetMemoryValue("$fwt_thing", getWithoutArticle(thing));
746 triggerSetFleetMemoryValue("$fwt_Thing", Misc.ucFirst(getWithoutArticle(thing)));
747 triggerSetFleetMemoryValue("$fwt_theThing", thing);
748 triggerSetFleetMemoryValue("$fwt_TheThing", Misc.ucFirst(thing));
749 triggerSetFleetMemoryValue("$fwt_payment", Misc.getWithDGS(paymentOffered));
750 triggerSetFleetMemoryValue("$fwt_itOrThey", thingItOrThey);
751 triggerSetFleetMemoryValue("$fwt_ItOrThey", Misc.ucFirst(thingItOrThey));
752
753 String thingItOrThem = "them";
754 if ("it".equals(thingItOrThey)) thingItOrThem = "it";
755 triggerSetFleetMemoryValue("$fwt_itOrThem", thingItOrThem);
756 triggerSetFleetMemoryValue("$fwt_ItOrThem", Misc.ucFirst(thingItOrThem));
757
758 triggerSetFleetMemoryValue("$fwt_thingDesc", thingDesc);
759 triggerSetFleetMemoryValue("$fwt_ThingDesc", Misc.ucFirst(thingDesc));
760
761 if (failTrigger == null) {
762 failTrigger = "FWTDefaultFailTrigger";
763 }
764 triggerSetFleetMemoryValue("$fwt_missionFailTrigger", failTrigger);
765 }
766
767
768// public void setAbortWhenPlayerFleetTooStrong() {
769// playerFleetSizeAbortMult = 2f;
770// }
771
772 public void setAlwaysAbort() {
774 }
778
780 this.playerFleetSizeAbortMult = playerFleetSizeAbortMult;
781 }
782
783 protected FleetSize fleetSize = FleetSize.MEDIUM;
784 protected float estimatedFleetPoints = 0f;
785 protected float playerFleetSizeAbortMult = 2f;
786 protected void computeThresholdPoints(String factionId) {
787 FactionAPI faction = Global.getSector().getFaction(factionId);
788 float maxPoints = faction.getApproximateMaxFPPerFleet(ShipPickMode.PRIORITY_THEN_ALL);
789 estimatedFleetPoints = fleetSize.maxFPFraction * maxPoints;
790 }
791
792 public void triggerFleetSetFaction(String factionId) {
793 computeThresholdPoints(factionId);
794 super.triggerSetFleetFaction(factionId);
795 }
796
797 @Override
798 public void triggerCreateFleet(FleetSize size, FleetQuality quality, String factionId, String type, SectorEntityToken roughlyWhere) {
799 fleetSize = size;
800 computeThresholdPoints(factionId);
801 super.triggerCreateFleet(size, quality, factionId, type, roughlyWhere);
802 }
803 @Override
804 public void triggerCreateFleet(FleetSize size, FleetQuality quality, String factionId, String type, StarSystemAPI roughlyWhere) {
805 fleetSize = size;
806 computeThresholdPoints(factionId);
807 super.triggerCreateFleet(size, quality, factionId, type, roughlyWhere);
808 }
809 @Override
810 public void triggerCreateFleet(FleetSize size, FleetQuality quality, String factionId, String type, Vector2f locInHyper) {
811 fleetSize = size;
812 computeThresholdPoints(factionId);
813 super.triggerCreateFleet(size, quality, factionId, type, locInHyper);
814 }
815
816 @Override
817 protected boolean create(MarketAPI createdAt, boolean barEvent) {
818 return false;
819 }
820 @Override
821 public String getBaseName() {
822 return null;
823 }
824
825 @Override
826 public boolean isHidden() {
827 return true;
828 }
829
830
831 @Override
832 protected boolean callAction(String action, String ruleId, InteractionDialogAPI dialog, List<Token> params, Map<String, MemoryAPI> memoryMap) {
833 float repLossPerson = 0f;
834 float repLossFaction = 0f;
835 if ("repLossMinor".equals(action)) {
836 repLossPerson = -RepRewards.SMALL;
837 repLossFaction = -RepRewards.TINY;
838 } else if ("repLossMedium".equals(action)) {
839 repLossPerson = -RepRewards.HIGH;
840 repLossFaction = -RepRewards.SMALL;
841 } else if ("repLossHigh".equals(action)) {
842 repLossPerson = -RepRewards.EXTREME;
843 repLossFaction = -RepRewards.HIGH;
844 }
845
846 if (repLossPerson != 0 && personForRepLoss != null) {
847 CustomRepImpact impact = new CustomRepImpact();
848 impact.delta = repLossPerson;
849 Global.getSector().adjustPlayerReputation(
850 new RepActionEnvelope(RepActions.CUSTOM, impact,
851 null, dialog.getTextPanel(), true), personForRepLoss);
852
853 impact.delta = repLossFaction;
854 Global.getSector().adjustPlayerReputation(
855 new RepActionEnvelope(RepActions.CUSTOM, impact,
856 null, dialog.getTextPanel(), true), personForRepLoss.getFaction().getId());
857
858 return true;
859 }
860 return super.callAction(action, ruleId, dialog, params, memoryMap);
861 }
862
863
864}
865
866
867
868
static SectorAPI getSector()
Definition Global.java:59
void setFleetWantsThing(String originalFactionId, String thing, String thingItOrThey, String thingDesc, int paymentOffered, boolean aggressiveIfDeclined, ComplicationRepImpact repImpact, String failTrigger, PersonAPI personForRepLoss)
void setLocationAnywhere(boolean allowInsidePopulatedSystems, String requireLargestMarketNotHostileToFaction)
void setRequireLargestMarketNotHostileToFaction(String requireLargestMarketNotHostileToFaction)
void setLocationAnyPopulated(boolean allowInsidePopulatedSystems, String requireLargestMarketNotHostileToFaction)
void setLocations(boolean allowInsidePopulatedSystems, String requireLargestMarketNotHostileToFaction, EncounterLocation ... locations)
void triggerCreateFleet(FleetSize size, FleetQuality quality, String factionId, String type, SectorEntityToken roughlyWhere)
boolean callAction(String action, String ruleId, InteractionDialogAPI dialog, List< Token > params, Map< String, MemoryAPI > memoryMap)
void reportFleetTransitingGate(CampaignFleetAPI fleet, SectorEntityToken gateFrom, SectorEntityToken gateTo)
void triggerCreateFleet(FleetSize size, FleetQuality quality, String factionId, String type, Vector2f locInHyper)
void setLocationOuterSector(boolean allowInsidePopulatedSystems, String requireLargestMarketNotHostileToFaction)
void setLocationFringeOnly(boolean allowInsidePopulatedSystems, String requireLargestMarketNotHostileToFaction)
void triggerCreateFleet(FleetSize size, FleetQuality quality, String factionId, String type, StarSystemAPI roughlyWhere)
void setLocationCoreOnly(boolean allowInsidePopulatedSystems, String requireLargestMarketNotHostileToFaction)
void setLocationInnerSector(boolean allowInsidePopulatedSystems, String requireLargestMarketNotHostileToFaction)