diff --git a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/SignType.kt b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/SignType.kt index 5309db90..588d43bc 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/SignType.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/SignType.kt @@ -12,7 +12,7 @@ import me.testaccount666.serversystem.clickablesigns.executables.weather.ActionW import me.testaccount666.serversystem.clickablesigns.executables.weather.ConfiguratorWeatherSign enum class SignType(private val _key: String, val signName: String, val clickAction: SignClickAction, val configurator: SignConfigurator) { - GIVE("Give", "F3FD1[Give]", ActionGiveSign(), ConfiguratorGiveSign()), + GIVE("Give", "F3FD1[GIVE]", ActionGiveSign(), ConfiguratorGiveSign()), KIT("Kit", "F3FD1[KIT]", ActionKitSign(), ConfiguratorKitSign()), WARP("Warp", "F3FD1[WARP]", ActionWarpSign(), ConfiguratorWarpSign()), TIME("Time", "F3FD1[TIME]", ActionTimeSign(), ConfiguratorTimeSign()), diff --git a/src/main/kotlin/me/testaccount666/serversystem/commands/executables/spawn/CommandSpawn.kt b/src/main/kotlin/me/testaccount666/serversystem/commands/executables/spawn/CommandSpawn.kt index 8dd96e9a..a4fa2769 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/commands/executables/spawn/CommandSpawn.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/commands/executables/spawn/CommandSpawn.kt @@ -4,8 +4,11 @@ import me.testaccount666.serversystem.ServerSystem.Companion.instance import me.testaccount666.serversystem.ServerSystem.Companion.log import me.testaccount666.serversystem.commands.ServerSystemCommand import me.testaccount666.serversystem.commands.executables.AbstractServerSystemCommand +import me.testaccount666.serversystem.managers.PermissionManager.hasCommandPermission import me.testaccount666.serversystem.managers.config.ConfigurationManager import me.testaccount666.serversystem.userdata.User +import me.testaccount666.serversystem.userdata.teleport.TeleportRunnable.Companion.teleportLater +import me.testaccount666.serversystem.userdata.teleport.TeleportRunnable.Companion.teleportNow import me.testaccount666.serversystem.utils.MessageBuilder.Companion.command import me.testaccount666.serversystem.utils.MessageBuilder.Companion.general import org.bukkit.Bukkit @@ -53,7 +56,6 @@ open class CommandSpawn : AbstractServerSystemCommand { if (!spawnConfiguration.isSet("Spawn")) return val worldName = spawnConfiguration.getString("Spawn.World") ?: return - val world = Bukkit.getWorld(worldName) ?: return val x = spawnConfiguration.getDouble("Spawn.X") @@ -67,17 +69,17 @@ open class CommandSpawn : AbstractServerSystemCommand { override fun execute(commandSender: User, command: Command, label: String, vararg arguments: String) { if (command.name.equals("spawn", true)) { - handleSpawnCommand(commandSender, label, *arguments) + handleSpawnCommand(commandSender, label, true, *arguments) return } handleSetSpawnCommand(commandSender, label) } - fun handleSpawnCommand(commandSender: User, label: String, vararg arguments: String) { + fun handleSpawnCommand(commandSender: User, label: String, fromCommand: Boolean, vararg arguments: String) { if (isConsoleWithNoTarget(commandSender, getSyntaxPath(null), label, arguments = arguments)) return - if (spawnLocation == null) { + val spawnLocation = spawnLocation ?: run { command("Spawn.NoSpawnSet", commandSender).build() return } @@ -86,16 +88,28 @@ open class CommandSpawn : AbstractServerSystemCommand { general("PlayerNotFound", commandSender) { target(arguments[0]) }.build() return } - - val targetPlayer = targetUser.getPlayer()!! val isSelf = targetUser === commandSender - if (!isSelf && !checkPermission(commandSender, "Spawn.Other", targetPlayer.name)) return + if (!isSelf && !checkPermission(commandSender, "Spawn.Other", targetUser.getNameSafe())) return + + val instantTeleport = !fromCommand || !isSelf || hasCommandPermission(commandSender, "Spawn.InstantTeleport", false) + + if (instantTeleport) { + targetUser.teleportNow(spawnLocation) + sendSuccessMessage(commandSender, targetUser, isSelf) + return + } - targetPlayer.teleport(spawnLocation!!) + command("Spawn.Teleporting", commandSender) { target(targetUser.getNameSafe()) }.build() + targetUser.teleportLater(spawnLocation).apply { + onSuccess = { sendSuccessMessage(commandSender, targetUser, true) } + onFailure = { command("Spawn.Moved", commandSender).build() } + } + } + private fun sendSuccessMessage(commandSender: User, targetUser: User, isSelf: Boolean) { val messagePath = if (isSelf) "Spawn.Success" else "Spawn.SuccessOther" - command(messagePath, commandSender) { target(targetPlayer.name) }.build() + command(messagePath, commandSender) { target(targetUser.getNameSafe()) }.build() if (isSelf) return command("Spawn.Success", targetUser) { sender(commandSender.getNameSafe()) }.build() diff --git a/src/main/kotlin/me/testaccount666/serversystem/commands/executables/spawn/ListenerSpawn.kt b/src/main/kotlin/me/testaccount666/serversystem/commands/executables/spawn/ListenerSpawn.kt index d4995e90..86286668 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/commands/executables/spawn/ListenerSpawn.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/commands/executables/spawn/ListenerSpawn.kt @@ -34,7 +34,7 @@ class ListenerSpawn : Listener { if (cachedUser.isOfflineUser) return@Runnable val user = cachedUser.offlineUser as User - _commandSpawn.handleSpawnCommand(user, "spawn") + _commandSpawn.handleSpawnCommand(user, "spawn", false) }, 20L) } } diff --git a/src/main/kotlin/me/testaccount666/serversystem/commands/executables/teleportask/CommandTeleportAsk.kt b/src/main/kotlin/me/testaccount666/serversystem/commands/executables/teleportask/CommandTeleportAsk.kt index c5ccbfbd..1ef7f9b0 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/commands/executables/teleportask/CommandTeleportAsk.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/commands/executables/teleportask/CommandTeleportAsk.kt @@ -1,22 +1,20 @@ package me.testaccount666.serversystem.commands.executables.teleportask -import me.testaccount666.serversystem.ServerSystem.Companion.instance import me.testaccount666.serversystem.ServerSystem.Companion.log import me.testaccount666.serversystem.commands.ServerSystemCommand import me.testaccount666.serversystem.commands.executables.AbstractServerSystemCommand import me.testaccount666.serversystem.managers.PermissionManager.hasCommandPermission import me.testaccount666.serversystem.managers.messages.MessageManager.applyPlaceholders import me.testaccount666.serversystem.userdata.User +import me.testaccount666.serversystem.userdata.teleport.TeleportRequest +import me.testaccount666.serversystem.userdata.teleport.TeleportRunnable.Companion.teleportLater +import me.testaccount666.serversystem.userdata.teleport.TeleportRunnable.Companion.teleportNow import me.testaccount666.serversystem.utils.ComponentColor.translateToComponent import me.testaccount666.serversystem.utils.MessageBuilder.Companion.command import me.testaccount666.serversystem.utils.MessageBuilder.Companion.general import net.kyori.adventure.text.Component import net.kyori.adventure.text.event.ClickEvent import net.kyori.adventure.text.event.HoverEvent -import org.bukkit.Bukkit -import org.bukkit.Location -import org.bukkit.Particle -import org.bukkit.Sound import org.bukkit.command.Command @ServerSystemCommand("teleportask", ["teleporthereask", "teleportaccept", "teleportdeny", "teleporttoggle"]) @@ -212,6 +210,7 @@ class CommandTeleportAsk : AbstractServerSystemCommand() { private fun handleTeleportAccept(commandSender: User) { val teleportRequest = validateTeleportRequest(commandSender) ?: return + teleportRequest.isCancelled = true val requester = teleportRequest.sender commandSender.teleportRequest = null @@ -221,15 +220,7 @@ class CommandTeleportAsk : AbstractServerSystemCommand() { val teleporter = if (teleportRequest.isTeleportHere) commandSender else requester val target = if (teleportRequest.isTeleportHere) requester else commandSender - val canInstantTeleport = hasCommandPermission(teleporter, "TeleportAsk.InstantTeleport", false) - - if (canInstantTeleport) { - executeTeleport(teleporter, target) - return - } - - command("TeleportAsk.StartingTeleporting", teleporter) { target(target.getNameSafe()) }.build() - startTeleportTimer(teleporter, target, teleportRequest) + executeTeleport(teleporter, target) } private fun handleTeleportDeny(commandSender: User) { @@ -242,20 +233,6 @@ class CommandTeleportAsk : AbstractServerSystemCommand() { command("TeleportDeny.SuccessOther", requester) { target(commandSender.getNameSafe()) }.build() } - private fun startTeleportTimer(teleporter: User, target: User, teleportRequest: TeleportRequest) { - val teleporterPlayer = teleporter.getPlayer() - val targetPlayer = target.getPlayer() - - activeTeleportRequests.add(teleportRequest) - (Bukkit.getScheduler().scheduleSyncDelayedTask(instance, { - if (teleporterPlayer == null || !teleporterPlayer.isOnline) return@scheduleSyncDelayedTask - if (targetPlayer == null || !targetPlayer.isOnline) return@scheduleSyncDelayedTask - - executeTeleport(teleporter, target) - activeTeleportRequests.remove(teleportRequest) - }, 20L * 5)).also { teleportRequest.timerId = it } - } - /** * Executes the teleport with animation and notification * @@ -265,11 +242,16 @@ class CommandTeleportAsk : AbstractServerSystemCommand() { private fun executeTeleport(teleporter: User, target: User) { val targetLocation = target.getPlayer()!!.location - playAnimation(targetLocation) - teleporter.getPlayer()!!.teleport(targetLocation) - playAnimation(targetLocation) - - command("TeleportAsk.TeleportFinished", teleporter) { target(target.getNameSafe()) }.build() + if (!hasCommandPermission(teleporter, "TeleportAsk.InstantTeleport", false)) { + command("TeleportAsk.StartingTeleporting", teleporter) { target(target.getNameSafe()) }.build() + teleporter.teleportLater(targetLocation).apply { + onFailure = { command("TeleportAsk.Moved", user).build() } + onSuccess = { command("TeleportAsk.TeleportFinished", user).build() } + } + } else { + teleporter.teleportNow(targetLocation) + command("TeleportAsk.TeleportFinished", teleporter) { target(target.getNameSafe()) }.build() + } } @@ -290,16 +272,6 @@ class CommandTeleportAsk : AbstractServerSystemCommand() { .asComponent() } - /** - * Plays a teleportation animation effect at the given location - * - * @param location The location to play the animation at - */ - private fun playAnimation(location: Location) { - location.world.playSound(location, Sound.ENTITY_ENDERMAN_TELEPORT, 1.0f, 1.0f) - location.world.spawnParticle(Particle.PORTAL, location, 100, 0.5, 0.5, 0.5, 0.05) - } - private fun handleTeleportToggle(commandSender: User, command: Command, label: String, vararg arguments: String) { if (isConsoleWithNoTarget(commandSender, getSyntaxPath(command), label, arguments = arguments)) return diff --git a/src/main/kotlin/me/testaccount666/serversystem/commands/executables/teleportask/ListenerTeleportRequest.kt b/src/main/kotlin/me/testaccount666/serversystem/commands/executables/teleportask/ListenerTeleportRequest.kt deleted file mode 100644 index b26d5a4b..00000000 --- a/src/main/kotlin/me/testaccount666/serversystem/commands/executables/teleportask/ListenerTeleportRequest.kt +++ /dev/null @@ -1,60 +0,0 @@ -package me.testaccount666.serversystem.commands.executables.teleportask - -import me.testaccount666.serversystem.annotations.RequiredCommands -import me.testaccount666.serversystem.commands.interfaces.ServerSystemCommandExecutor -import me.testaccount666.serversystem.utils.MessageBuilder.Companion.command -import org.bukkit.Bukkit -import org.bukkit.Location -import org.bukkit.event.EventHandler -import org.bukkit.event.Listener -import org.bukkit.event.player.PlayerMoveEvent - -@RequiredCommands([CommandTeleportAsk::class]) -class ListenerTeleportRequest : Listener { - private lateinit var _commandTeleportAsk: CommandTeleportAsk - - fun canRegister(requiredCommands: Set): Boolean { - _commandTeleportAsk = requiredCommands.firstOrNull { it is CommandTeleportAsk } as? CommandTeleportAsk ?: return false - return true - } - - @EventHandler - fun onTeleporterMove(event: PlayerMoveEvent) { - getDistance(event).let { if (it < .1) return } - - _commandTeleportAsk.activeTeleportRequests.toList() - .forEach { teleportRequest -> - val teleporter = if (teleportRequest.isTeleportHere) teleportRequest.receiver else teleportRequest.sender - if (teleporter.getPlayer() == null) return@forEach - val teleporterPlayer = teleporter.getPlayer()!! - - if (event.getPlayer().uniqueId != teleporterPlayer.uniqueId) return@forEach - - Bukkit.getScheduler().cancelTask(teleportRequest.timerId) - teleportRequest.isCancelled = true - _commandTeleportAsk.activeTeleportRequests.remove(teleportRequest) - command("TeleportAsk.Moved", teleporter).build() - } - } - - companion object { - private fun getDistance(event: PlayerMoveEvent): Double { - val fromX = event.from.x - val toX = event.to.x - - val fromY = event.from.y - val toY = event.to.y - - val fromZ = event.from.z - val toZ = event.to.z - - val fromWorld = event.from.world - val toWorld = event.to.world - - val from = Location(fromWorld, fromX, fromY, fromZ) - val to = Location(toWorld, toX, toY, toZ) - - return if (from.world.name.equals(to.world.name, true)) from.distance(to) else Double.MAX_VALUE - } - } -} diff --git a/src/main/kotlin/me/testaccount666/serversystem/commands/executables/waypoints/AbstractCommandWaypoint.kt b/src/main/kotlin/me/testaccount666/serversystem/commands/executables/waypoints/AbstractCommandWaypoint.kt index 5f97844c..eda0fede 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/commands/executables/waypoints/AbstractCommandWaypoint.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/commands/executables/waypoints/AbstractCommandWaypoint.kt @@ -2,12 +2,12 @@ package me.testaccount666.serversystem.commands.executables.waypoints import me.testaccount666.serversystem.commands.executables.AbstractServerSystemCommand import me.testaccount666.serversystem.userdata.User +import me.testaccount666.serversystem.userdata.teleport.TeleportRunnable.Companion.teleportLater +import me.testaccount666.serversystem.userdata.teleport.TeleportRunnable.Companion.teleportNow import me.testaccount666.serversystem.utils.MessageBuilder.Companion.command import me.testaccount666.serversystem.utils.MessageBuilder.Companion.general import me.testaccount666.serversystem.utils.tuples.Tuple import org.bukkit.Location -import org.bukkit.Particle -import org.bukkit.Sound import org.bukkit.command.Command abstract class AbstractCommandWaypoint, P : Waypoint> : AbstractServerSystemCommand() { @@ -75,16 +75,25 @@ abstract class AbstractCommandWaypoint, P : Waypoint> : A } val pointLocation = point.location - val player = commandSender.getPlayer()!! - playAnimation(player.location) - player.teleport(pointLocation) - playAnimation(pointLocation) - - command("${getPrefix(command)}.Success", commandSender) { - target(target.getNameSafe()) - postModifier { it.replace(getPlaceholder(), point.displayName) } - }.build() + if (!canInstantTeleport(command, commandSender)) { + commandSender.teleportLater(pointLocation).apply { + onFailure = { command("${getPrefix(command)}.Moved", commandSender) { target(target.getNameSafe()) }.build() } + onSuccess = { + command("${getPrefix(command)}.Success", user) { + target(target.getNameSafe()) + postModifier { it.replace(getPlaceholder(), point.displayName) } + }.build() + } + } + command("${getPrefix(command)}.Teleporting", commandSender) { target(target.getNameSafe()) }.build() + } else { + commandSender.teleportNow(pointLocation) + command("${getPrefix(command)}.Success", commandSender) { + target(target.getNameSafe()) + postModifier { it.replace(getPlaceholder(), point.displayName) } + }.build() + } } private fun resolveTargetAndPoint(commandSender: User, command: Command, vararg arguments: String): Tuple? { @@ -114,11 +123,6 @@ abstract class AbstractCommandWaypoint, P : Waypoint> : A }.build() } - private fun playAnimation(location: Location) { - location.world.playSound(location, Sound.ENTITY_ENDERMAN_TELEPORT, 1.0f, 1.0f) - location.world.spawnParticle(Particle.PORTAL, location, 100, 0.5, 0.5, 0.5, 0.05) - } - abstract fun argsBeforePoint(command: Command): Int abstract fun getWaypointManager(command: Command, targetUser: User): T abstract fun getCommandType(command: Command): CommandType @@ -127,6 +131,7 @@ abstract class AbstractCommandWaypoint, P : Waypoint> : A abstract fun getPrefix(command: Command): String abstract fun getPlaceholder(): String + abstract fun canInstantTeleport(command: Command, user: User): Boolean } enum class CommandType { CREATE, DELETE, TELEPORT } \ No newline at end of file diff --git a/src/main/kotlin/me/testaccount666/serversystem/commands/executables/waypoints/home/admin/CommandAdminHome.kt b/src/main/kotlin/me/testaccount666/serversystem/commands/executables/waypoints/home/admin/CommandAdminHome.kt index 458b664c..59bfbd63 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/commands/executables/waypoints/home/admin/CommandAdminHome.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/commands/executables/waypoints/home/admin/CommandAdminHome.kt @@ -2,6 +2,7 @@ package me.testaccount666.serversystem.commands.executables.waypoints.home.admin import me.testaccount666.serversystem.commands.executables.waypoints.CommandType import me.testaccount666.serversystem.commands.executables.waypoints.home.AbstractCommandHome +import me.testaccount666.serversystem.userdata.User import me.testaccount666.serversystem.userdata.home.HomeManager import org.bukkit.command.Command @@ -41,6 +42,6 @@ class CommandAdminHome : AbstractCommandHome() { } override fun getSyntaxPath(command: Command?) = "AdminHome" - override fun canAddPoints(pointManager: HomeManager, command: Command) = true + override fun canInstantTeleport(command: Command, user: User) = true } diff --git a/src/main/kotlin/me/testaccount666/serversystem/commands/executables/waypoints/home/user/CommandHome.kt b/src/main/kotlin/me/testaccount666/serversystem/commands/executables/waypoints/home/user/CommandHome.kt index 54869bef..21ba59bf 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/commands/executables/waypoints/home/user/CommandHome.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/commands/executables/waypoints/home/user/CommandHome.kt @@ -4,6 +4,8 @@ import me.testaccount666.serversystem.commands.ServerSystemCommand import me.testaccount666.serversystem.commands.executables.waypoints.CommandType import me.testaccount666.serversystem.commands.executables.waypoints.home.AbstractCommandHome import me.testaccount666.serversystem.commands.executables.waypoints.home.admin.CommandAdminHome +import me.testaccount666.serversystem.managers.PermissionManager.hasCommandPermission +import me.testaccount666.serversystem.userdata.User import me.testaccount666.serversystem.userdata.home.HomeManager import org.bukkit.command.Command @@ -63,5 +65,10 @@ class CommandHome : AbstractCommandHome() { } } + override fun canInstantTeleport(command: Command, user: User): Boolean { + if (isAdminCommand(command)) return _commandAdminHome.canInstantTeleport(command, user) + return hasCommandPermission(user, "Home.InstantTeleport", false) + } + private fun isAdminCommand(command: Command?) = command?.name?.startsWith("admin", true) ?: false } diff --git a/src/main/kotlin/me/testaccount666/serversystem/commands/executables/waypoints/warp/CommandWarp.kt b/src/main/kotlin/me/testaccount666/serversystem/commands/executables/waypoints/warp/CommandWarp.kt index 4ffd3769..72b0830f 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/commands/executables/waypoints/warp/CommandWarp.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/commands/executables/waypoints/warp/CommandWarp.kt @@ -5,6 +5,7 @@ import me.testaccount666.serversystem.commands.executables.waypoints.AbstractCom import me.testaccount666.serversystem.commands.executables.waypoints.CommandType import me.testaccount666.serversystem.commands.executables.waypoints.warp.manager.Warp import me.testaccount666.serversystem.commands.executables.waypoints.warp.manager.WarpManager +import me.testaccount666.serversystem.managers.PermissionManager.hasCommandPermission import me.testaccount666.serversystem.userdata.User import org.bukkit.Location import org.bukkit.command.Command @@ -43,4 +44,8 @@ class CommandWarp : AbstractCommandWaypoint() { CommandType.TELEPORT -> "Warp.Teleport" } } + + override fun canInstantTeleport(command: Command, user: User): Boolean { + return hasCommandPermission(user, "Warp.InstantTeleport", false) + } } diff --git a/src/main/kotlin/me/testaccount666/serversystem/userdata/User.kt b/src/main/kotlin/me/testaccount666/serversystem/userdata/User.kt index 857fdbec..6005d82e 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/userdata/User.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/userdata/User.kt @@ -1,6 +1,7 @@ package me.testaccount666.serversystem.userdata -import me.testaccount666.serversystem.commands.executables.teleportask.TeleportRequest +import me.testaccount666.serversystem.userdata.teleport.TeleportRequest +import me.testaccount666.serversystem.userdata.teleport.TeleportRunnable import net.kyori.adventure.text.Component import org.bukkit.command.CommandSender import org.bukkit.entity.Player @@ -16,7 +17,7 @@ open class User(userFile: File) : OfflineUser(userFile) { protected open var onlinePlayer: Player? = null var teleportRequest: TeleportRequest? = null - + var teleportRunnable: TeleportRunnable? = null var replyUser: User? = null var isAfk = false diff --git a/src/main/kotlin/me/testaccount666/serversystem/commands/executables/teleportask/TeleportRequest.kt b/src/main/kotlin/me/testaccount666/serversystem/userdata/teleport/TeleportRequest.kt similarity index 60% rename from src/main/kotlin/me/testaccount666/serversystem/commands/executables/teleportask/TeleportRequest.kt rename to src/main/kotlin/me/testaccount666/serversystem/userdata/teleport/TeleportRequest.kt index 839f6838..3c3ccb9c 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/commands/executables/teleportask/TeleportRequest.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/userdata/teleport/TeleportRequest.kt @@ -1,11 +1,10 @@ -package me.testaccount666.serversystem.commands.executables.teleportask +package me.testaccount666.serversystem.userdata.teleport import me.testaccount666.serversystem.userdata.User data class TeleportRequest(val sender: User, val receiver: User, private val _timeout: Long, val isTeleportHere: Boolean) { var isCancelled = false - var timerId = 0 val isExpired - get() = System.currentTimeMillis() >= _timeout -} + get() = isCancelled || System.currentTimeMillis() >= _timeout +} \ No newline at end of file diff --git a/src/main/kotlin/me/testaccount666/serversystem/userdata/teleport/TeleportRunnable.kt b/src/main/kotlin/me/testaccount666/serversystem/userdata/teleport/TeleportRunnable.kt new file mode 100644 index 00000000..c3b9e9b4 --- /dev/null +++ b/src/main/kotlin/me/testaccount666/serversystem/userdata/teleport/TeleportRunnable.kt @@ -0,0 +1,102 @@ +package me.testaccount666.serversystem.userdata.teleport + +import me.testaccount666.serversystem.ServerSystem +import me.testaccount666.serversystem.userdata.User +import org.bukkit.Bukkit +import org.bukkit.Location +import org.bukkit.Particle +import org.bukkit.Sound +import org.bukkit.event.player.PlayerTeleportEvent +import org.bukkit.scheduler.BukkitRunnable + +class TeleportRunnable(val user: User, val location: Location, val originLocation: Location, delay: Long) { + private val endTime = System.currentTimeMillis() + delay + private var _running = true + + fun cancel() = let { _running = false } + var onFailure: ((user: User) -> Unit)? = null + var onSuccess: ((user: User) -> Unit)? = null + + init { + user.teleportRunnable?.cancel() + user.teleportRunnable = this + + createTask().runTaskTimer(ServerSystem.instance, 5L, 5L) + } + + private fun createTask(): BukkitRunnable { + return object : BukkitRunnable() { + override fun run() { + runCatching { + if (!_running) { + stopTask() + return + } + + if (calculateDistance() > 0.1) { + stopTask() + return + } + + if (endTime > System.currentTimeMillis()) return + + user.getPlayer()?.let { + playAnimation(originLocation) + it.teleport(location, PlayerTeleportEvent.TeleportCause.PLUGIN) + playAnimation(location) + + onSuccess?.invoke(user) + } + + _running = false + stopTask() + }.onFailure { + it.printStackTrace() + stopTask() + } + } + + fun stopTask() { + if (_running) onFailure?.invoke(user) + + _running = false + user.teleportRunnable = null + Bukkit.getScheduler().cancelTask(taskId) + } + } + } + + private fun calculateDistance(): Double { + val location = user.getPlayer()?.location ?: return Double.MAX_VALUE + if (location.world != originLocation.world) return Double.MAX_VALUE + + return location.distance(originLocation) + } + + companion object { + /** + * Plays a teleportation animation effect at the given location + * + * @param location The location to play the animation at + */ + fun playAnimation(location: Location) { + location.world.playSound(location, Sound.ENTITY_ENDERMAN_TELEPORT, 1.0f, 1.0f) + location.world.spawnParticle(Particle.PORTAL, location, 100, 0.5, 0.5, 0.5, 0.05) + } + + fun User.teleportNow(location: Location) { + val player = getPlayer() ?: error("Player is null!") + + playAnimation(player.location) + player.teleport(location) + playAnimation(location) + } + + fun User.teleportLater(location: Location, delay: Long = 3000): TeleportRunnable { + val originalLocation = getPlayer()?.location ?: error("Player is null!") + + return TeleportRunnable(this, location, originalLocation, delay) + } + } +} + diff --git a/src/main/resources/messages/english/messages.yml b/src/main/resources/messages/english/messages.yml index 88d7567b..6b8025cb 100644 --- a/src/main/resources/messages/english/messages.yml +++ b/src/main/resources/messages/english/messages.yml @@ -67,14 +67,18 @@ Messages: ClearChat: Success: "The chat has been cleared by ." Spawn: + NoSpawnSet: "No spawn was set." + Teleporting: "Starting teleport, please stand still..." Success: "You have been teleported to spawn." SuccessOther: "You have teleported to spawn." - NoSpawnSet: "No spawn was set." + Moved: "Your teleport was cancelled, since you moved." SetSpawn: Success: "You have set spawn to your current location." Home: - Success: "You teleported to the home ." + Success: "You have been teleported to ." DoesNotExist: "The specified home does not exist." + Teleporting: "Starting teleport, please stand still..." + Moved: "Your teleport was cancelled, since you moved." DeleteHome: Success: "You deleted the home ." DoesNotExist: "The specified home does not exist." @@ -287,7 +291,9 @@ Messages: DoesNotExist: "Specified warp doesn't exist." Teleport: DoesNotExist: "Specified warp doesn't exist." - Success: "You teleported to ." + Teleporting: "Starting teleport, please stand still..." + Success: "You have been teleported to ." + Moved: "Your teleport was cancelled, since you moved." Kit: Create: KitAlreadyExists: "The kit already exists." diff --git a/src/main/resources/messages/german/messages.yml b/src/main/resources/messages/german/messages.yml index dfa56858..693206e0 100644 --- a/src/main/resources/messages/german/messages.yml +++ b/src/main/resources/messages/german/messages.yml @@ -67,14 +67,18 @@ Messages: ClearChat: Success: "Der Chat wurde von geleert." Spawn: + NoSpawnSet: "Kein Spawn wurde gesetzt." + Moved: "Deine Teleportation wurde abgebrochen, da du dich bewegt hast." Success: "Du wurdest zum Spawn teleportiert." SuccessOther: "Du hast zum Spawn teleportiert." - NoSpawnSet: "Kein Spawn wurde gesetzt." + StartingTeleporting: "Teleportation wird gestartet, bitte stehen bleiben..." SetSpawn: Success: "Du hast den Spawn auf deine aktuelle Position gesetzt." Home: - Success: "Du wurdest zum Zuhause teleportiert." DoesNotExist: "Das angegebene Zuhause existiert nicht." + Moved: "Deine Teleportation wurde abgebrochen, da du dich bewegt hast." + Success: "Du wurdest zu teleportiert." + StartingTeleporting: "Teleportation wird gestartet, bitte stehen bleiben..." DeleteHome: Success: "Du hast das Zuhause gelöscht." DoesNotExist: "Das angegebene Zuhause existiert nicht." @@ -287,7 +291,9 @@ Messages: DoesNotExist: "Der angegebene Warp existiert nicht." Teleport: DoesNotExist: "Der angegebene Warp existiert nicht." + Moved: "Deine Teleportation wurde abgebrochen, da du dich bewegt hast." Success: "Du wurdest zu teleportiert." + StartingTeleporting: "Teleportation wird gestartet, bitte stehen bleiben..." Kit: Create: KitAlreadyExists: "Das Kit existiert bereits." diff --git a/src/main/resources/messages/slovene/messages.yml b/src/main/resources/messages/slovene/messages.yml index 9577c48c..939f2d84 100644 --- a/src/main/resources/messages/slovene/messages.yml +++ b/src/main/resources/messages/slovene/messages.yml @@ -67,14 +67,18 @@ Messages: ClearChat: Success: "Klepet je počistil ." Spawn: + NoSpawnSet: "Spawn ni nastavljen." + Teleporting: "Teleportacija se zacenja. Stoj pri miru..." Success: "Bil si teleportiran na spawn." SuccessOther: "Teleportiral si na spawn." - NoSpawnSet: "Spawn ni nastavljen." + Moved: "Zaradi premika je bila teleportacija prekinjena." SetSpawn: Success: "Spawn si nastavil na svojo trenutno lokacijo." Home: - Success: "Teleportiral si se v dom ." DoesNotExist: "Navedeni dom ne obstaja." + Teleporting: "Teleportacija se zacenja. Stoj pri miru..." + Success: "Teleportacija k uspešna." + Moved: "Zaradi premika je bila teleportacija prekinjena." DeleteHome: Success: "Izbrisal si dom ." DoesNotExist: "Navedeni dom ne obstaja." @@ -287,7 +291,9 @@ Messages: WarpNotFound: "Navedeni warp ne obstaja." Teleport: WarpNotFound: "Navedeni warp ne obstaja." - Success: "Teleportiral si se na ." + Teleporting: "Teleportacija se zacenja. Stoj pri miru..." + Success: "Teleportacija k uspešna." + Moved: "Zaradi premika je bila teleportacija prekinjena." Kit: Create: KitAlreadyExists: "Komplet že obstaja." diff --git a/src/main/resources/permissions.yml b/src/main/resources/permissions.yml index 7126f14f..37351c9d 100644 --- a/src/main/resources/permissions.yml +++ b/src/main/resources/permissions.yml @@ -176,7 +176,10 @@ Permissions: Spawn: Use: Required: false - Value: "serversystem.command.spawn.use" + Value: "serversystem.command.spawn.teleport" + InstantTeleport: + Required: true + Value: "serversystem.command.warp.teleport.instant" Other: Required: true Value: "serversystem.command.spawn.other" @@ -186,7 +189,10 @@ Permissions: Home: Use: Required: false - Value: "serversystem.command.home.use" + Value: "serversystem.command.home.teleport" + InstantTeleport: + Required: true + Value: "serversystem.command.home.teleport.instant" Set: Required: false Value: "serversystem.command.home.set" @@ -374,6 +380,9 @@ Permissions: Teleport: Required: false Value: "serversystem.command.warp.teleport" + InstantTeleport: + Required: true + Value: "serversystem.command.warp.teleport.instant" Set: Required: true Value: "serversystem.admin.command.warp.set"