diff --git a/common/src/main/java/dev/ftb/mods/ftbessentials/FTBEEventHandler.java b/common/src/main/java/dev/ftb/mods/ftbessentials/FTBEEventHandler.java index 18a8291..0f18d64 100644 --- a/common/src/main/java/dev/ftb/mods/ftbessentials/FTBEEventHandler.java +++ b/common/src/main/java/dev/ftb/mods/ftbessentials/FTBEEventHandler.java @@ -2,8 +2,11 @@ import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import dev.architectury.event.CompoundEventResult; import dev.architectury.event.EventResult; import dev.architectury.event.events.common.*; +import dev.ftb.mods.ftbessentials.api.TeleportDestination; +import dev.ftb.mods.ftbessentials.api.event.TeleportImmediateEvent; import dev.ftb.mods.ftbessentials.api.records.TPARequest; import dev.ftb.mods.ftbessentials.commands.FTBCommands; import dev.ftb.mods.ftbessentials.commands.impl.teleporting.TPACommand; diff --git a/common/src/main/java/dev/ftb/mods/ftbessentials/api/TeleportDestination.java b/common/src/main/java/dev/ftb/mods/ftbessentials/api/TeleportDestination.java new file mode 100644 index 0000000..5ee0672 --- /dev/null +++ b/common/src/main/java/dev/ftb/mods/ftbessentials/api/TeleportDestination.java @@ -0,0 +1,63 @@ +package dev.ftb.mods.ftbessentials.api; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; +import java.util.UUID; + +/** + * Represents a teleport destination used by the various teleportation commands in the mod. + * + * @param dimension the dimension + * @param pos the block position + * @param yRot the player's Y rotation (yaw) on arrival (if empty, use player's current yaw) + * @param xRot the player's X rotation (pitch) on arrival (if empty, use player's current pitch) + * @param playerId the player's UUID, only if this destination was created from a player, null otherwise + */ +public record TeleportDestination( + ResourceKey dimension, + BlockPos pos, + Optional yRot, + Optional xRot, + @Nullable UUID playerId +) { + public TeleportDestination withPos(BlockPos newPos) { + return new TeleportDestination(dimension, newPos, yRot, xRot, playerId); + } + + /** + * Return a successful outcome for this destination. See also {@link dev.ftb.mods.ftbessentials.api.event.SavedTeleportEvent.PreTeleport#onTeleport(String, ServerPlayer, TeleportDestination, UUID)}. + * + * @return a successful outcome + */ + public Outcome success() { + return new Outcome(this, Component.empty()); + } + + /** + * Return a successful outcome with a new destination. + * + * @return a successful outcome + */ + public Outcome success(TeleportDestination newDest) { + return new Outcome(newDest, Component.empty()); + } + + /** + * Return a successful outcome for this destination. See also {@link dev.ftb.mods.ftbessentials.api.event.SavedTeleportEvent.PreTeleport#onTeleport(String, ServerPlayer, TeleportDestination, UUID)}. + * + * @param reason the failure reason to report to the player + * @return a failed outcome + */ + public Outcome failed(Component reason) { + return new Outcome(this, reason); + } + + public record Outcome(TeleportDestination dest, Component reason) { + } +} diff --git a/common/src/main/java/dev/ftb/mods/ftbessentials/api/TeleportResult.java b/common/src/main/java/dev/ftb/mods/ftbessentials/api/TeleportResult.java new file mode 100644 index 0000000..948214c --- /dev/null +++ b/common/src/main/java/dev/ftb/mods/ftbessentials/api/TeleportResult.java @@ -0,0 +1,56 @@ +package dev.ftb.mods.ftbessentials.api; + +import dev.ftb.mods.ftblibrary.util.TimeUtils; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; + +import java.util.function.LongSupplier; + +@FunctionalInterface +public interface TeleportResult { + int runCommand(ServerPlayer player); + + default boolean isSuccess() { + return false; + } + + static TeleportResult failed(Component msg) { + return player -> { + player.displayClientMessage(msg, false); + return 0; + }; + } + + TeleportResult DIMENSION_NOT_FOUND = failed(Component.translatable("ftbessentials.dimension_not_found")); + TeleportResult UNKNOWN_DESTINATION = failed(Component.translatable("ftbessentials.unknown_dest")); + TeleportResult PREVENTED = failed(Component.translatable("ftbessentials.teleport_prevented")); + TeleportResult DIMENSION_NOT_ALLOWED_FROM = failed(Component.translatable("ftbessentials.teleport.not_from_here")); + TeleportResult DIMENSION_NOT_ALLOWED_TO = failed(Component.translatable("ftbessentials.teleport.not_to_here")); + TeleportResult SUCCESS = new TeleportResult() { + @Override + public int runCommand(ServerPlayer player) { + return 1; + } + + @Override + public boolean isSuccess() { + return true; + } + }; + + @FunctionalInterface + interface OnCooldown extends TeleportResult { + long getCooldown(); + + @Override + default int runCommand(ServerPlayer player) { + String secStr = TimeUtils.prettyTimeString(getCooldown() / 1000L); + player.displayClientMessage(Component.translatable("ftbessentials.teleport.on_cooldown", secStr), false); + return 0; + } + + static OnCooldown create(LongSupplier longSupplier) { + return longSupplier::getAsLong; + } + } +} diff --git a/common/src/main/java/dev/ftb/mods/ftbessentials/api/event/SavedTeleportEvent.java b/common/src/main/java/dev/ftb/mods/ftbessentials/api/event/SavedTeleportEvent.java new file mode 100644 index 0000000..751a345 --- /dev/null +++ b/common/src/main/java/dev/ftb/mods/ftbessentials/api/event/SavedTeleportEvent.java @@ -0,0 +1,68 @@ +package dev.ftb.mods.ftbessentials.api.event; + +import dev.architectury.event.CompoundEventResult; +import dev.architectury.event.Event; +import dev.architectury.event.EventFactory; +import dev.ftb.mods.ftbessentials.api.TeleportDestination; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; +import org.jetbrains.annotations.Nullable; + +import java.util.UUID; + +public interface SavedTeleportEvent { + /** + * See {@link #onAdded(String, TeleportDestination, ServerPlayer, UUID)} + */ + Event ADDED = EventFactory.createLoop(); + /** + * See {@link #onDeleted(String, TeleportDestination, UUID)} + */ + Event DELETED = EventFactory.createLoop(); + /** + * See {@link PreTeleport#onTeleport(String, ServerPlayer, TeleportDestination, UUID)} + */ + Event PRE_TELEPORT = EventFactory.createCompoundEventResult(); + + /** + * Fired after a saved destination (home or warp) has been added. + * + * @param name the name of the destination + * @param dest the destination that was added + * @param player the player who added the destination + * @param owningPlayer the player's UUID for a home destination, or null for a global warp destination + */ + void onAdded(String name, TeleportDestination dest, ServerPlayer player, @Nullable UUID owningPlayer); + + /** + * Fired after a saved destination (home or warp) has been deleted. + * + * @param name the name of the destination + * @param destination the destination that was removed + * @param owningPlayer the player's UUID for a home destination, or null for a global warp destination + */ + void onDeleted(String name, TeleportDestination destination, @Nullable UUID owningPlayer); + + @FunctionalInterface + interface PreTeleport { + /** + * Fired when a player is about to teleport to a saved destination (home or warp). This event allows + * the destination to be modified, or the teleportation to be prevented entirely. + *
    + *
  • To modify the destination, return {@link CompoundEventResult#interruptTrue(Object)} with a new + * {@link TeleportDestination.Outcome} - see {@link TeleportDestination#success()}
  • + *
  • To prevent teleportation, return {@link CompoundEventResult#interruptFalse(Object)} - see {@link TeleportDestination#failed(Component)}
  • + *
  • To proceed with the default behavior, return {@link CompoundEventResult#pass()}
  • + *
+ * See also {@link TeleportEvent}, which is fired after this event, and provides a second opportunity to + * prevent teleportation. + * + * @param name the name of the saved destination + * @param player the player about to teleport + * @param dest the planned teleport destination + * @param owningPlayer UUID of the player who owns the destination; non-null for a player home, null for a global warp + * @return the event result (see above) + */ + CompoundEventResult onTeleport(String name, ServerPlayer player, TeleportDestination dest, @Nullable UUID owningPlayer); + } +} diff --git a/common/src/main/java/dev/ftb/mods/ftbessentials/api/event/TeleportEvent.java b/common/src/main/java/dev/ftb/mods/ftbessentials/api/event/TeleportEvent.java index 0545aba..e61873c 100644 --- a/common/src/main/java/dev/ftb/mods/ftbessentials/api/event/TeleportEvent.java +++ b/common/src/main/java/dev/ftb/mods/ftbessentials/api/event/TeleportEvent.java @@ -9,7 +9,16 @@ public class TeleportEvent { public static Event TELEPORT = EventFactory.createCompoundEventResult(); + @FunctionalInterface public interface Teleport { + /** + * Fired when the player is ready to teleport, but before any warmup is started. This can be canceled to prevent + * teleportation by returning {@link CompoundEventResult#interruptFalse(Object)} with a message to supply to the + * player about why teleportation was prevented. + * + * @param player the player about to teleport + * @return the event result + */ CompoundEventResult teleport(ServerPlayer player); } } diff --git a/common/src/main/java/dev/ftb/mods/ftbessentials/api/event/TeleportImmediateEvent.java b/common/src/main/java/dev/ftb/mods/ftbessentials/api/event/TeleportImmediateEvent.java new file mode 100644 index 0000000..df8ac70 --- /dev/null +++ b/common/src/main/java/dev/ftb/mods/ftbessentials/api/event/TeleportImmediateEvent.java @@ -0,0 +1,26 @@ +package dev.ftb.mods.ftbessentials.api.event; + +import dev.architectury.event.CompoundEventResult; +import dev.architectury.event.Event; +import dev.architectury.event.EventFactory; +import dev.ftb.mods.ftbessentials.api.TeleportDestination; +import net.minecraft.server.level.ServerPlayer; + +public class TeleportImmediateEvent { + public static Event TELEPORT = EventFactory.createCompoundEventResult(TeleportImmediate.class); + + @FunctionalInterface + public interface TeleportImmediate { + /** + * Fired when the player is just about to teleport, when any possible teleportation warmup is complete. + *

+ * Teleportation can be prevented by returning a failed outcome e.g. {@code destination.failed(reason)}, + * or a modified destination e.g. {@code detination.success(newdest)}. + * + * @param player the player about to teleport + * @param destination the teleport destination + * @return the event outcome + */ + CompoundEventResult teleport(ServerPlayer player, TeleportDestination destination); + } +} diff --git a/common/src/main/java/dev/ftb/mods/ftbessentials/commands/impl/teleporting/TPACommand.java b/common/src/main/java/dev/ftb/mods/ftbessentials/commands/impl/teleporting/TPACommand.java index 1f321e9..ec65fa4 100644 --- a/common/src/main/java/dev/ftb/mods/ftbessentials/commands/impl/teleporting/TPACommand.java +++ b/common/src/main/java/dev/ftb/mods/ftbessentials/commands/impl/teleporting/TPACommand.java @@ -2,6 +2,7 @@ import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import dev.ftb.mods.ftbessentials.api.TeleportResult; import dev.ftb.mods.ftbessentials.api.records.TPARequest; import dev.ftb.mods.ftbessentials.commands.FTBCommand; import dev.ftb.mods.ftbessentials.config.FTBEConfig; @@ -62,7 +63,7 @@ public int tpa(ServerPlayer player, ServerPlayer target, boolean here) { return 0; } - TeleportPos.TeleportResult result = here ? + TeleportResult result = here ? dataTarget.tpaTeleporter.checkCooldown(target) : dataSource.tpaTeleporter.checkCooldown(player); @@ -127,7 +128,7 @@ public int tpaccept(ServerPlayer player, String id) { return 0; } - TeleportPos.TeleportResult result = request.here() ? + TeleportResult result = request.here() ? request.target().tpaTeleporter.teleport(player, p -> new TeleportPos(sourcePlayer)) : request.source().tpaTeleporter.teleport(sourcePlayer, p -> new TeleportPos(player)); diff --git a/common/src/main/java/dev/ftb/mods/ftbessentials/util/FTBEPlayerData.java b/common/src/main/java/dev/ftb/mods/ftbessentials/util/FTBEPlayerData.java index ce7d7ad..66b4b4f 100644 --- a/common/src/main/java/dev/ftb/mods/ftbessentials/util/FTBEPlayerData.java +++ b/common/src/main/java/dev/ftb/mods/ftbessentials/util/FTBEPlayerData.java @@ -247,14 +247,14 @@ public void read(CompoundTag tag) { god = tag.getBoolean("god"); nick = tag.getString("nick"); recording = RecordingStatus.NAME_MAP.map.getOrDefault(tag.getString("recording"), RecordingStatus.NONE); - lastSeenPos = tag.contains("last_seen") ? new TeleportPos(tag.getCompound("last_seen")) : null; + lastSeenPos = tag.contains("last_seen") ? new TeleportPos(tag.getCompound("last_seen"), uuid) : null; teleportHistory.clear(); ListTag th = tag.getList("teleport_history", Tag.TAG_COMPOUND); for (int i = 0; i < th.size(); i++) { - teleportHistory.add(new TeleportPos(th.getCompound(i))); + teleportHistory.add(new TeleportPos(th.getCompound(i), uuid)); } kitUseTimes.clear(); diff --git a/common/src/main/java/dev/ftb/mods/ftbessentials/util/SavedTeleportManager.java b/common/src/main/java/dev/ftb/mods/ftbessentials/util/SavedTeleportManager.java index 506cf0c..0c80bd9 100644 --- a/common/src/main/java/dev/ftb/mods/ftbessentials/util/SavedTeleportManager.java +++ b/common/src/main/java/dev/ftb/mods/ftbessentials/util/SavedTeleportManager.java @@ -1,13 +1,17 @@ package dev.ftb.mods.ftbessentials.util; +import dev.ftb.mods.ftbessentials.api.TeleportResult; +import dev.ftb.mods.ftbessentials.api.event.SavedTeleportEvent; import dev.ftb.mods.ftbessentials.config.FTBEConfig; import dev.ftb.mods.ftblibrary.snbt.SNBTCompoundTag; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerPlayer; +import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.UUID; import java.util.stream.Stream; public abstract class SavedTeleportManager { @@ -19,20 +23,34 @@ public void addDestination(String name, TeleportPos dest, ServerPlayer player) { throw new TooManyDestinationsException(); } destinations.put(nameLower, dest); + SavedTeleportEvent.ADDED.invoker().onAdded(name, dest.asDestination(), player, owningPlayer()); onChanged(); } public boolean deleteDestination(String name) { - if (destinations.remove(name.toLowerCase()) != null) { + TeleportPos removed = destinations.remove(name.toLowerCase()); + if (removed != null) { + SavedTeleportEvent.DELETED.invoker().onDeleted(name, removed.asDestination(), owningPlayer()); onChanged(); return true; } return false; } - public TeleportPos.TeleportResult teleportTo(String name, ServerPlayer player, WarmupCooldownTeleporter teleporter) { + public TeleportResult teleportTo(String name, ServerPlayer player, WarmupCooldownTeleporter teleporter) { TeleportPos pos = destinations.get(name.toLowerCase()); - return pos != null ? teleporter.teleport(player, p -> pos) : TeleportPos.TeleportResult.UNKNOWN_DESTINATION; + if (pos == null) { + return TeleportResult.UNKNOWN_DESTINATION; + } + + var result = SavedTeleportEvent.PRE_TELEPORT.invoker().onTeleport(name, player, pos.asDestination(), owningPlayer()); + if (result.isFalse()) { + return TeleportResult.failed(result.object().reason()); + } + + TeleportPos newPos = result.isEmpty() ? pos : TeleportPos.fromDestination(result.object().dest()); + + return newPos != null ? teleporter.teleport(player, p -> newPos) : TeleportResult.UNKNOWN_DESTINATION; } public Stream destinations() { @@ -48,7 +66,7 @@ public CompoundTag writeNBT() { public void readNBT(CompoundTag tag) { destinations.clear(); for (String key : tag.getAllKeys()) { - destinations.put(key, new TeleportPos(tag.getCompound(key))); + destinations.put(key, new TeleportPos(tag.getCompound(key), owningPlayer())); } } @@ -62,6 +80,9 @@ protected int getMaxSize(ServerPlayer player) { protected abstract void onChanged(); + @Nullable + protected abstract UUID owningPlayer(); + public static class HomeManager extends SavedTeleportManager { private final FTBEPlayerData playerData; @@ -78,6 +99,11 @@ protected int getMaxSize(ServerPlayer player) { protected void onChanged() { playerData.markDirty(); } + + @Override + protected UUID owningPlayer() { + return playerData.getUuid(); + } } public static class WarpManager extends SavedTeleportManager { @@ -91,6 +117,11 @@ public WarpManager(FTBEWorldData worldData) { protected void onChanged() { worldData.markDirty(); } + + @Override + protected UUID owningPlayer() { + return null; + } } public record DestinationEntry(String name, TeleportPos destination) { diff --git a/common/src/main/java/dev/ftb/mods/ftbessentials/util/TeleportPos.java b/common/src/main/java/dev/ftb/mods/ftbessentials/util/TeleportPos.java index 2bfce4e..00a4bb2 100644 --- a/common/src/main/java/dev/ftb/mods/ftbessentials/util/TeleportPos.java +++ b/common/src/main/java/dev/ftb/mods/ftbessentials/util/TeleportPos.java @@ -1,12 +1,13 @@ package dev.ftb.mods.ftbessentials.util; +import dev.ftb.mods.ftbessentials.api.TeleportDestination; +import dev.ftb.mods.ftbessentials.api.TeleportResult; +import dev.ftb.mods.ftbessentials.api.event.TeleportImmediateEvent; import dev.ftb.mods.ftblibrary.snbt.SNBTCompoundTag; -import dev.ftb.mods.ftblibrary.util.TimeUtils; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; @@ -17,42 +18,66 @@ import org.jetbrains.annotations.Nullable; import java.util.Optional; +import java.util.UUID; public class TeleportPos { private final ResourceKey dimension; private final BlockPos pos; + @Nullable public final Float yRot, xRot; - private final long time; + @Nullable + private final UUID playerId; public TeleportPos(ResourceKey d, BlockPos p) { this(d, p, null, null); } - public TeleportPos(ResourceKey d, BlockPos p, Float yRot, Float xRot) { - dimension = d; - pos = p; - this.yRot = yRot; - this.xRot = xRot; - time = System.currentTimeMillis(); - } - - public TeleportPos(Level world, BlockPos p, Float yRot, Float xRot) { + public TeleportPos(Level world, BlockPos p, @Nullable Float yRot, @Nullable Float xRot) { this(world.dimension(), p, yRot, xRot); } public TeleportPos(Entity entity) { - this(entity.level(), entity.blockPosition(), entity.getYRot(), entity.getXRot()); + this(entity.level().dimension(), entity.blockPosition(), entity.getYRot(), entity.getXRot(), + entity instanceof Player p ? p.getUUID() : null); } - public TeleportPos(CompoundTag tag) { + public TeleportPos(CompoundTag tag, @Nullable UUID playerId) { dimension = ResourceKey.create(Registries.DIMENSION, ResourceLocation.tryParse(tag.getString("dim"))); pos = new BlockPos(tag.getInt("x"), tag.getInt("y"), tag.getInt("z")); this.yRot = (tag.getTagType("yRot") == CompoundTag.TAG_FLOAT) ? tag.getFloat("yRot") : null; this.xRot = (tag.getTagType("xRot") == CompoundTag.TAG_FLOAT) ? tag.getFloat("xRot") : null; - time = tag.getLong("time"); + this.playerId = playerId; + } + + private TeleportPos(ResourceKey d, BlockPos p, @Nullable Float yRot, @Nullable Float xRot) { + this(d, p, yRot, xRot, null); + } + + // canonical ctor + private TeleportPos(ResourceKey dimension, BlockPos pos, @Nullable Float yRot, @Nullable Float xRot, @Nullable UUID playerId) { + this.dimension = dimension; + this.pos = pos; + this.yRot = yRot; + this.xRot = xRot; + this.playerId = playerId; + } + + @Nullable + public static TeleportPos fromDestination(@Nullable TeleportDestination dest) { + return dest == null ? + null : + new TeleportPos(dest.dimension(), dest.pos(), + dest.yRot().orElse(null), dest.xRot().orElse(null), + dest.playerId() + ); + } + + TeleportDestination asDestination() { + return new TeleportDestination(dimension, pos, Optional.ofNullable(yRot), Optional.ofNullable(xRot), playerId); } public TeleportPos safeForPlayer(ServerPlayer player) { + assert player.getServer() != null; ServerLevel level = player.getServer().getLevel(dimension); if (level == null) return this; // shouldn't happen @@ -94,6 +119,18 @@ public TeleportResult checkDimensionBlacklist(Player player) { } public TeleportResult teleport(ServerPlayer player) { + TeleportDestination oldDest = asDestination(); + var outcome = TeleportImmediateEvent.TELEPORT.invoker().teleport(player, oldDest); + if (outcome.isFalse()) { + return TeleportResult.failed(outcome.object().reason()); + } + + var newDest = outcome.isEmpty() ? oldDest : outcome.object().dest(); + TeleportPos newPos = newDest.equals(oldDest) ? this : TeleportPos.fromDestination(newDest); + return newPos.actuallyTeleport(player); + } + + private TeleportResult actuallyTeleport(ServerPlayer player) { ServerLevel level = player.server.getLevel(dimension); if (level == null) { return TeleportResult.DIMENSION_NOT_FOUND; @@ -114,7 +151,6 @@ public CompoundTag write() { tag.putInt("x", pos.getX()); tag.putInt("y", pos.getY()); tag.putInt("z", pos.getZ()); - tag.putLong("time", time); if (this.xRot != null) tag.putFloat("xRot", this.xRot); if (this.yRot != null) tag.putFloat("yRot", this.yRot); return tag; @@ -147,54 +183,6 @@ public BlockPos getPos() { public String posAsString() { // Normal shortString would be 1, 2, 3 so we remove the commas - return pos.toShortString().replaceAll(",", ""); - } - - @FunctionalInterface - public interface TeleportResult { - TeleportResult SUCCESS = new TeleportResult() { - @Override - public int runCommand(ServerPlayer player) { - return 1; - } - - @Override - public boolean isSuccess() { - return true; - } - }; - - static TeleportResult failed(Component msg) { - return player -> { - player.displayClientMessage(msg, false); - return 0; - }; - } - - TeleportResult DIMENSION_NOT_FOUND = failed(Component.translatable("ftbessentials.dimension_not_found")); - - TeleportResult UNKNOWN_DESTINATION = failed(Component.translatable("ftbessentials.unknown_dest")); - - TeleportResult DIMENSION_NOT_ALLOWED_FROM = failed(Component.translatable("ftbessentials.teleport.not_from_here")); - - TeleportResult DIMENSION_NOT_ALLOWED_TO = failed(Component.translatable("ftbessentials.teleport.not_to_here")); - - int runCommand(ServerPlayer player); - - default boolean isSuccess() { - return false; - } - } - - @FunctionalInterface - public interface CooldownTeleportResult extends TeleportResult { - long getCooldown(); - - @Override - default int runCommand(ServerPlayer player) { - String secStr = TimeUtils.prettyTimeString(getCooldown() / 1000L); - player.displayClientMessage(Component.translatable("ftbessentials.teleport.on_cooldown", secStr), false); - return 0; - } + return pos.toShortString().replace(",", ""); } } diff --git a/common/src/main/java/dev/ftb/mods/ftbessentials/util/WarmupCooldownTeleporter.java b/common/src/main/java/dev/ftb/mods/ftbessentials/util/WarmupCooldownTeleporter.java index afd2373..9e4cd8b 100644 --- a/common/src/main/java/dev/ftb/mods/ftbessentials/util/WarmupCooldownTeleporter.java +++ b/common/src/main/java/dev/ftb/mods/ftbessentials/util/WarmupCooldownTeleporter.java @@ -4,7 +4,7 @@ import dev.architectury.injectables.annotations.ExpectPlatform; import dev.ftb.mods.ftbessentials.api.event.TeleportEvent; import dev.ftb.mods.ftbessentials.config.FTBEConfig; -import dev.ftb.mods.ftbessentials.util.TeleportPos.TeleportResult; +import dev.ftb.mods.ftbessentials.api.TeleportResult; import net.minecraft.ChatFormatting; import net.minecraft.commands.Commands; import net.minecraft.network.chat.Component; @@ -45,7 +45,7 @@ public TeleportResult checkCooldown(ServerPlayer player) { long nextRun = lastRun + Math.max(0L, cooldownConfig.applyAsInt(player) * 1000L); if (now < nextRun) { - return (TeleportPos.CooldownTeleportResult) () -> nextRun - now; + return TeleportResult.OnCooldown.create(() -> nextRun - now); } return TeleportResult.SUCCESS;