Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,37 +1,29 @@
package net.swofty.type.skyblockgeneric.event.actions.player;

import net.kyori.adventure.key.Key;
import net.swofty.commons.StringUtility;
import org.tinylog.Logger;
import net.kyori.adventure.sound.Sound;
import org.tinylog.Logger;
import net.minestom.server.coordinate.Pos;
import org.tinylog.Logger;
import net.minestom.server.coordinate.Vec;
import org.tinylog.Logger;
import net.minestom.server.entity.EntityType;
import org.tinylog.Logger;
import net.minestom.server.entity.LivingEntity;
import org.tinylog.Logger;
import net.minestom.server.event.player.PlayerMoveEvent;
import org.tinylog.Logger;
import net.minestom.server.network.packet.server.play.ParticlePacket;
import org.tinylog.Logger;
import net.minestom.server.particle.Particle;
import org.tinylog.Logger;
import net.swofty.commons.ServerType;
import net.swofty.proxyapi.ProxyInformation;
import net.swofty.type.generic.event.EventNodes;
import org.tinylog.Logger;
import net.swofty.type.generic.event.HypixelEvent;
import org.tinylog.Logger;
import net.swofty.type.generic.event.HypixelEventClass;
import org.tinylog.Logger;
import net.swofty.type.generic.utility.MathUtility;
import org.tinylog.Logger;
import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer;
import org.tinylog.Logger;
import net.swofty.type.skyblockgeneric.utility.LaunchPads;
import org.tinylog.Logger;

import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
Expand All @@ -41,6 +33,7 @@
public class ActionPlayerLaunchPads implements HypixelEventClass {
private static final int SEGMENTS = 30;
private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private static final Set<UUID> notifiedPlayers = ConcurrentHashMap.newKeySet();


@HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = true, isAsync = true)
Expand All @@ -53,7 +46,12 @@ public void run(PlayerMoveEvent event) {
} catch (ExceptionInInitializerError err) {
return;
}
if (pad == null) return;

if (pad == null) {
notifiedPlayers.remove(player.getUuid());
return;
}

if (player.isInLaunchpad()) return;
player.setInLaunchpad(true);

Expand Down Expand Up @@ -84,37 +82,78 @@ public void run(PlayerMoveEvent event) {
player.setInLaunchpad(false);
return;
}
player.playSound(Sound.sound(Key.key("entity.firework_rocket.launch"), Sound.Source.PLAYER, 1, 1));

LivingEntity armorStand = new LivingEntity(EntityType.ARMOR_STAND);
armorStand.getEntityMeta().setInvisible(true);
armorStand.getEntityMeta().setHasNoGravity(true);
armorStand.setInstance(player.getInstance(), player.getPosition());
armorStand.addPassenger(player);

List<Pos> curve = MathUtility.bezierCurve(player.getPosition(), pad.getDestination(), SEGMENTS);
long timeToSleep = 3000 / SEGMENTS;

// Use ScheduledExecutorService to run the launch trajectory with delays
AtomicInteger index = new AtomicInteger(0);
ScheduledFuture<?>[] taskHolder = new ScheduledFuture<?>[1];
taskHolder[0] = scheduler.scheduleAtFixedRate(() -> {
int currentIndex = index.getAndIncrement();
if (currentIndex >= curve.size()) {
// Cancel the task
if (taskHolder[0] != null) {
taskHolder[0].cancel(false);

// Check server availability before starting animation
ServerType targetServerType = pad.getTargetServerType();
ProxyInformation proxyInfo = new ProxyInformation();
proxyInfo.getServerInformation(targetServerType).thenAccept(servers -> {
if (servers == null || servers.isEmpty()) {
player.setInLaunchpad(false);
if (!notifiedPlayers.contains(player.getUuid())) {
notifiedPlayers.add(player.getUuid());
player.sendMessage("§cThere are no " + StringUtility.toNormalCase(targetServerType.name()) + " servers available at the moment. Please try again later.");
}
// Execute the after finished callback
player.sendMessage("Done");
pad.getAfterFinished().accept(player);
return;
}

Pos pos = curve.get(currentIndex);
Vec toGoTo = pos.asVec();
Vec direction = toGoTo.sub(player.getPosition().asVec()).normalize();
armorStand.setVelocity(direction.mul(50, 5, 50));
}, 0, timeToSleep, TimeUnit.MILLISECONDS);
notifiedPlayers.remove(player.getUuid());

Pos originalPosition = player.getPosition();
player.playSound(Sound.sound(Key.key("entity.firework_rocket.launch"), Sound.Source.PLAYER, 1, 1));

LivingEntity armorStand = new LivingEntity(EntityType.ARMOR_STAND);
armorStand.getEntityMeta().setInvisible(true);
armorStand.getEntityMeta().setHasNoGravity(true);
armorStand.setInstance(player.getInstance(), player.getPosition());
armorStand.addPassenger(player);

List<Pos> curve = MathUtility.bezierCurve(player.getPosition(), pad.getDestination(), SEGMENTS);
long timeToSleep = 3000 / SEGMENTS;

// Use ScheduledExecutorService to run the launch trajectory with delays
AtomicInteger index = new AtomicInteger(0);
ScheduledFuture<?>[] taskHolder = new ScheduledFuture<?>[1];
taskHolder[0] = scheduler.scheduleAtFixedRate(() -> {
int currentIndex = index.getAndIncrement();
if (currentIndex >= curve.size()) {
// Cancel the task
if (taskHolder[0] != null) {
taskHolder[0].cancel(false);
}

player.setInLaunchpad(false);
notifiedPlayers.remove(player.getUuid());

// Execute the after finished callback
player.sendMessage("Done");
pad.getAfterFinished().accept(player);

// Check after a delay if player is still on this server (transfer failed)
scheduler.schedule(() -> {
// If player is still on the same server and instance, teleport them back
if (player.getInstance() != null && player.getInstance().equals(armorStand.getInstance())) {
player.teleport(originalPosition);
player.sendMessage("§cFailed to connect to the server. You have been teleported back.");
}
try {
armorStand.remove();
} catch (Exception e) {
}
}, 2, TimeUnit.SECONDS);

return;
}

Pos pos = curve.get(currentIndex);
Vec toGoTo = pos.asVec();
Vec direction = toGoTo.sub(player.getPosition().asVec()).normalize();
armorStand.setVelocity(direction.mul(50, 5, 50));
}, 0, timeToSleep, TimeUnit.MILLISECONDS);
}).exceptionally(ex -> {
Logger.error(ex, "Error checking server availability for launch pad");
player.setInLaunchpad(false);
player.sendMessage("§cAn error occurred while checking server availability. Please try again later.");
return null;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
@Getter
public enum LaunchPads {
VILLAGE_TO_FARMING(getSlimeBlocksNear(new Pos(79, 71, -185)), ServerType.SKYBLOCK_HUB,
new Pos(116.5, 74, -210.5), (player) -> {
ServerType.SKYBLOCK_THE_FARMING_ISLANDS, new Pos(116.5, 74, -210.5), (player) -> {
player.sendTo(ServerType.SKYBLOCK_THE_FARMING_ISLANDS);
}, (player) -> player.getSkills().getCurrentLevel(SkillCategories.FARMING) >= 5,
"§cYou must be at least Farming Level V to join this island!",
Expand All @@ -46,7 +46,7 @@ public enum LaunchPads {
}
}),
FARMING_TO_VILLAGE(getSlimeBlocksNear(new Pos(111, 71, -202)), ServerType.SKYBLOCK_THE_FARMING_ISLANDS,
new Pos(74, 72, -180), (player) -> {
ServerType.SKYBLOCK_HUB, new Pos(74, 72, -180), (player) -> {
player.sendTo(ServerType.SKYBLOCK_HUB);
}, (player) -> true,
"",
Expand All @@ -63,17 +63,19 @@ public enum LaunchPads {

private final List<Pos> slimeBlocks;
private final ServerType serverType;
private final ServerType targetServerType;
private final Pos destination;
private final Consumer<SkyBlockPlayer> afterFinished;
private final Function<SkyBlockPlayer, Boolean> shouldAllow;
private final String rejectionMessage;
private final Function<SkyBlockPlayer, PlayerHolograms.ExternalPlayerHologram> hologramDisplay;

LaunchPads(List<Pos> slimeBlocks, ServerType serverType, Pos destination,
LaunchPads(List<Pos> slimeBlocks, ServerType serverType, ServerType targetServerType, Pos destination,
Consumer<@NonNull SkyBlockPlayer> afterFinished, Function<SkyBlockPlayer, Boolean> shouldAllow, String rejectionMessage,
Function<@NonNull SkyBlockPlayer, PlayerHolograms.ExternalPlayerHologram> hologramDisplay) {
this.slimeBlocks = slimeBlocks;
this.serverType = serverType;
this.targetServerType = targetServerType;
this.destination = destination;
this.afterFinished = afterFinished;
this.shouldAllow = shouldAllow;
Expand Down
Loading