80 protected SlipstreamTerrainPlugin2 plugin;
81 protected boolean done =
false;
82 protected int index = 0;
83 protected float elapsed = 0f;
84 protected float maxElapsed = 0f;
85 public SlipsurgeFadeInScript(SlipstreamTerrainPlugin2 plugin) {
88 float fadeInLength = 300f;
89 float lengthSoFar = 0f;
91 maxElapsed = durIn * plugin.getSegments().size() * 0.34f + 3f;
92 for (SlipstreamSegment seg : plugin.getSegments()) {
93 seg.fader.setDurationIn(durIn);
96 seg.bMult = Math.min(1f, lengthSoFar / fadeInLength);
97 lengthSoFar += seg.lengthToNext;
100 public void advance(
float amount) {
106 if (!plugin.getEntity().isInCurrentLocation()) {
107 for (SlipstreamSegment curr : plugin.getSegments()) {
116 if (index >= plugin.getSegments().size() || elapsed > maxElapsed) {
120 SlipstreamSegment curr = plugin.getSegments().get(index);
121 if (curr.fader.isFadedIn()) {
126 if (curr.fader.getBrightness() > 0.33f && index < plugin.getSegments().size() - 1) {
127 plugin.getSegments().get(index + 1).fader.fadeIn();
129 if (curr.fader.getBrightness() > 0.67f && index < plugin.getSegments().size() - 2) {
130 plugin.getSegments().get(index + 2).fader.fadeIn();
134 public boolean isDone() {
137 public boolean runWhilePaused() {
143 protected float elapsed = 0f;
144 protected float extraRadius;
145 public ExpandStormRadiusScript(
float extraRadius) {
146 this.extraRadius = extraRadius;
148 public void advance(
float amount) {
151 CampaignTerrainAPI terrain = Misc.getHyperspaceTerrain();
152 if (terrain !=
null) {
153 HyperspaceTerrainPlugin htp = (HyperspaceTerrainPlugin) terrain.getPlugin();
154 htp.setExtraDistanceAroundPlayerToAdvanceStormCells(extraRadius);
155 htp.setStormCellTimeMultOutsideBaseArea(5f);
159 public boolean isDone() {
160 return elapsed >= 10f;
162 public boolean runWhilePaused() {
167 public static class SlipsurgeEffectScript
implements EveryFrameScript {
168 protected CampaignFleetAPI fleet;
169 protected boolean triggered =
false;
170 protected boolean done =
false;
171 protected boolean didTempCleanup =
false;
172 protected float elapsed = 0f;
173 protected SlipstreamTerrainPlugin2 plugin;
174 public SlipsurgeEffectScript(CampaignFleetAPI fleet, SlipstreamTerrainPlugin2 plugin) {
176 this.plugin = plugin;
179 public void abort() {
181 didTempCleanup =
true;
182 fleet.fadeInIndicator();
183 fleet.setNoEngaging(0f);
184 fleet.getStats().getSensorRangeMod().unmodifyMult(
SENSOR_MOD_ID);
185 for (FleetMemberViewAPI view : fleet.getViews()) {
188 if (fleet.isPlayerFleet()) {
189 Global.getSector().getCampaignUI().setFollowingDirectCommand(
false);
194 public void advance(
float amount) {
197 if (fleet.isInHyperspaceTransition() ||
198 plugin.getEntity().getContainingLocation() != fleet.getContainingLocation()) {
199 if (!didTempCleanup) {
209 if (elapsed >= 30f ||
210 !plugin.getEntity().isAlive()) {
216 float burn = Misc.getBurnLevelForSpeed(fleet.getVelocity().length());
217 if (burn > 50 && plugin.containsEntity(fleet)) {
223 plugin.despawn(0, 0.2f,
new Random());
228 AbilityPlugin gs = fleet.getAbility(Abilities.GENERATE_SLIPSURGE);
229 if (gs instanceof BaseAbilityPlugin) {
230 BaseAbilityPlugin base = (BaseAbilityPlugin) gs;
231 for (AbilityPlugin curr : fleet.getAbilities().values()) {
232 if (curr ==
this)
continue;
233 if (!base.isCompatible(curr)) {
234 if (curr.isActiveOrInProgress()) {
242 float decelMult = Misc.getAbyssalDepth(fleet) * 1f;
243 if (fleet.getGoSlowOneFrame()) decelMult = 1f;
245 if (decelMult > 0f && !plugin.containsEntity(fleet)) {
246 float angle = Misc.getAngleInDegrees(fleet.getVelocity());
247 Vector2f decelDir = Misc.getUnitVectorAtDegreeAngle(angle + 180f);
249 float targetDecelSeconds = 0.5f;
250 float speed = fleet.getVelocity().length();
251 float decelAmount = amount * speed / targetDecelSeconds;
252 decelDir.scale(decelAmount * decelMult);
254 Vector2f vel = fleet.getVelocity();
255 fleet.setVelocity(vel.x + decelDir.x, vel.y + decelDir.y);
259 fleet.fadeOutIndicator();
260 fleet.setNoEngaging(0.1f);
261 fleet.setInteractionTarget(
null);
262 if (fleet.isPlayerFleet()) {
263 Global.getSector().getCampaignUI().setFollowingDirectCommand(
true);
265 fleet.getMemoryWithoutUpdate().set(MemFlags.NO_HIGH_BURN_TOPOGRAPHY_READINGS,
true, 0.1f);
267 didTempCleanup =
false;
269 float angle = Misc.getAngleInDegrees(fleet.getVelocity());
270 Vector2f jitterDir = Misc.getUnitVectorAtDegreeAngle(angle + 180f);
271 Vector2f windDir = Misc.getUnitVectorAtDegreeAngle(angle);
272 float windIntensity = (burn - 50f) / 250f;
273 if (windIntensity < 0) windIntensity = 0;
276 float b = (burn - 50f) / 450f;
281 if (fleet.isPlayerFleet()) {
284 Global.getSoundPlayer().setNextLoopFadeInAndOut(0.05f, 0.5f);
287 fleet.getLocation(), fleet.getVelocity());
292 for (FleetMemberViewAPI view : fleet.getViews()) {
293 Color c = view.getMember().getHullSpec().getHyperspaceJitterColor();
299 c = Misc.setAlpha(c, 60);
300 view.setJitter(0.1f, 1f, c, 10 + Math.round(40f * b), 20f);
301 view.setUseCircularJitter(
true);
302 view.setJitterDirection(jitterDir);
303 view.setJitterLength(30f * b);
304 view.setJitterBrightness(b);
308 for (FleetMemberViewAPI view : fleet.getViews()) {
316 public boolean isDone() {
319 public boolean runWhilePaused() {
326 protected JumpPointAPI
well =
null;
336 return FleetMemberDamageLevel.MEDIUM;
345 CampaignFleetAPI fleet =
getFleet();
346 if (fleet ==
null)
return;
350 if (
well ==
null)
return;
353 float angle = Misc.getAngleInDegrees(
well.getLocation(), fleet.getLocation());
355 Vector2f from = Misc.getUnitVectorAtDegreeAngle(angle);
356 from.scale(offset + fleet.getRadius());
357 Vector2f.add(from, fleet.getLocation(), from);
361 SectorEntityToken token = fleet.getContainingLocation().createToken(
startLoc);
365 well.getContainingLocation().addScript(
new ExpandStormRadiusScript(16000f));
372 CampaignFleetAPI fleet =
getFleet();
373 if (fleet ==
null)
return;
375 if (
level > 0 && level < 1 && amount > 0) {
376 fleet.goSlowOneFrame();
391 CampaignFleetAPI fleet =
getFleet();
392 if (fleet ==
null)
return;
395 JumpPointAPI jp =
well;
396 if (jp ==
null)
return;
401 float angle = Misc.getAngleInDegrees(jp.getLocation(),
startLoc);
408 SlipstreamParams2 params =
new SlipstreamParams2();
410 params.enteringSlipstreamTextOverride =
"Entering slipsurge";
411 params.enteringSlipstreamTextDurationOverride = 0.1f;
412 params.forceNoWindVisualEffectOnFleets =
true;
415 float length = 1000f;
417 length += strength * 500f;
418 params.burnLevel = Math.round(400f + strength * strength * 500f);
419 params.accelerationMult = 20f + strength * strength * 280f;
423 params.baseWidth = width;
424 params.widthForMaxSpeed = 400f;
425 params.widthForMaxSpeedMinMult = 0.34f;
427 params.slowDownInWiderSections =
true;
432 params.minSpeed = Misc.getSpeedForBurnLevel(params.burnLevel - params.burnLevel/8);
433 params.maxSpeed = Misc.getSpeedForBurnLevel(params.burnLevel + params.burnLevel/8);
435 params.lineLengthFractionOfSpeed = 2000f / ((params.maxSpeed + params.minSpeed) * 0.5f);
437 float lineFactor = 0.1f;
438 params.minSpeed *= lineFactor;
439 params.maxSpeed *= lineFactor;
442 params.maxBurnLevelForTextureScroll = (int) (params.burnLevel * 0.1f);
444 params.particleFadeInTime = 0.01f;
445 params.areaPerParticle = 1000f;
447 Vector2f to = Misc.getUnitVectorAtDegreeAngle(angle);
448 to.scale(offset + fleet.getRadius() + length);
451 CampaignTerrainAPI slipstream = (CampaignTerrainAPI)
well.getContainingLocation().addTerrain(Terrain.SLIPSTREAM, params);
452 slipstream.addTag(Tags.SLIPSTREAM_VISIBLE_IN_ABYSS);
453 slipstream.setLocation(from.x, from.y);
455 SlipstreamTerrainPlugin2 plugin = (SlipstreamTerrainPlugin2) slipstream.getPlugin();
457 float spacing = 100f;
458 float incr = spacing / length;
460 Vector2f diff = Vector2f.sub(to, from,
new Vector2f());
461 for (
float f = 0; f <= 1f; f += incr) {
462 Vector2f curr =
new Vector2f(diff);
464 Vector2f.add(curr, from, curr);
465 plugin.addSegment(curr, width - Math.min(300f, 300f * (
float)Math.sqrt(f)));
469 plugin.recomputeIfNeeded();
471 plugin.despawn(1.5f, 0.2f,
new Random());
473 slipstream.addScript(
new SlipsurgeFadeInScript(plugin));
474 fleet.addScript(
new SlipsurgeEffectScript(fleet, plugin));
480 CampaignFleetAPI fleet =
getFleet();
481 if (fleet ==
null)
return;
491 if (!super.isUsable())
return false;
492 return super.isUsable() &&
503 CampaignFleetAPI fleet =
getFleet();
504 if (fleet ==
null)
return;
506 Color text = Misc.getTextColor();
507 Color gray = Misc.getGrayColor();
508 Color highlight = Misc.getHighlightColor();
509 Color bad = Misc.getNegativeHighlightColor();
516 extra =
"and availability ";
521 tooltip.addPara(
"Overload and modulate the fleet's drive field "
522 +
"to induce an extremely powerful, "
523 +
"short-duration slipstream flowing away from the nearest gravity well, its strength " + extra
524 +
"based on the stellar object's mass, density, and some other poorly-understood factors. "
525 +
"Largely ineffective inside abyssal hyperspace.", pad);
533 Color starColor = Misc.getBasePlayerColor();
534 tooltip.beginTable(player, 20f,
"Stellar object type",
getTooltipWidth() - 150f,
"Surge strength", 150f);
536 tooltip.addRow(Alignment.LMID, starColor,
"Black holes, neutron stars",
537 Alignment.MID, highlight,
"Extreme");
538 tooltip.addRow(Alignment.LMID, starColor,
"Supergiant stars",
539 Alignment.MID, highlight,
"High");
540 tooltip.addRow(Alignment.LMID, starColor,
"Giant stars",
541 Alignment.MID, highlight,
"Average");
542 tooltip.addRow(Alignment.LMID, starColor,
"Smaller stars / stellar objects",
543 Alignment.MID, highlight,
"---");
545 tooltip.addRow(Alignment.LMID, starColor,
"Black holes, neutron stars",
546 Alignment.MID, highlight,
"Extreme");
547 tooltip.addRow(Alignment.LMID, starColor,
"Supergiant stars",
548 Alignment.MID, highlight,
"Very high");
549 tooltip.addRow(Alignment.LMID, starColor,
"Giant stars",
550 Alignment.MID, highlight,
"High");
551 tooltip.addRow(Alignment.LMID, starColor,
"Sol-like stars",
552 Alignment.MID, highlight,
"Average");
553 tooltip.addRow(Alignment.LMID, starColor,
"Dwarf stars",
554 Alignment.MID, highlight,
"Low");
555 tooltip.addRow(Alignment.LMID, starColor,
"Gas giants",
556 Alignment.MID, highlight,
"Very low");
559 tooltip.addTable(
"", 0, pad);
560 tooltip.addSpacer(5f);
562 tooltip.addPara(
"A stronger surge can allow the fleet to rapidly travel up to %s light-years. "
563 +
"Attempting to %s "
564 +
"during the transit will decelerate the fleet quickly. Fleet sensor range is "
565 +
"reduced by %s during the transit.", pad, highlight,
573 CampaignFleetAPI fleet =
getFleet();
574 if (fleet ==
null)
return false;
576 Color bad = Misc.getNegativeHighlightColor();
580 if (!fleet.isInHyperspace()) {
581 tooltip.addPara(
"Can only be used in hyperspace.", bad, pad);
587 tooltip.addPara(
"Must be near a powerful gravity well.", bad, pad);
589 tooltip.addPara(
"Must be near a gravity well.", bad, pad);
599 CampaignFleetAPI fleet =
getFleet();
600 if (fleet ==
null)
return null;
602 JumpPointAPI closest =
null;
603 float minDist = Float.MAX_VALUE;
604 for (SectorEntityToken curr : fleet.getContainingLocation().getJumpPoints()) {
605 JumpPointAPI jp = (JumpPointAPI) curr;
606 if (!jp.isStarAnchor() && !jp.isGasGiantAnchor())
continue;
607 if (jp.getDestinationVisualEntity() ==
null)
continue;
612 if (str <= min)
continue;
615 float dist = Misc.getDistance(fleet, jp) - jp.getRadius();
616 if (dist > jp.getRadius() + 150f)
continue;
617 if (dist < minDist) {
630 if (!(
object instanceof PlanetAPI))
return 0f;
631 PlanetAPI star = (PlanetAPI)
object;
632 PlanetSpecAPI
spec = star.getSpec();
634 if (val !=
null)
return val;
636 if (
spec.isGasGiant())
return 0f;
641 String key = StarTypes.YELLOW;
643 String name =
spec.getName().toLowerCase();
644 if (name.contains(
"neutron") ||
spec.isPulsar()) {
645 key = StarTypes.NEUTRON_STAR;
646 }
else if (name.contains(
"dwarf")) {
647 key = StarTypes.WHITE_DWARF;
648 }
else if (name.contains(
"giant")) {
649 key = StarTypes.BLUE_GIANT;
650 }
else if (name.contains(
"supergiant")) {
651 key = StarTypes.BLUE_SUPERGIANT;
652 }
else if (name.contains(
" hole")) {
653 key = StarTypes.BLACK_HOLE;
654 }
else if (name.contains(
"brown")) {
655 key = StarTypes.BROWN_DWARF;
659 if (val !=
null)
return val;