From 14238290024aa9b7db80eafc8a2853a552c3cf7c Mon Sep 17 00:00:00 2001 From: Boy Date: Fri, 18 Oct 2024 15:43:18 +0200 Subject: [PATCH] feat(unfinished): support syncing entities between sections without players --- .../deeperworld/listeners/MovementListener.kt | 18 +++--- .../BedrockBlockingInvalidTeleportHandler.kt | 15 ++--- .../movement/InvalidTeleportHandler.kt | 4 +- .../deeperworld/movement/MovementHandler.kt | 58 ++++++++++--------- .../deeperworld/movement/TeleportHandler.kt | 3 + .../movement/TransitionTeleportHandler.kt | 35 +++++------ .../UndoMovementInvalidTeleportHandler.kt | 7 ++- .../transition/ConfigSectionChecker.kt | 7 ++- .../movement/transition/SectionChecker.kt | 5 +- 9 files changed, 80 insertions(+), 72 deletions(-) diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/listeners/MovementListener.kt b/src/main/kotlin/com/mineinabyss/deeperworld/listeners/MovementListener.kt index c61f492..be4e1bc 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/listeners/MovementListener.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/listeners/MovementListener.kt @@ -24,19 +24,19 @@ object MovementListener : Listener { @EventHandler(ignoreCancelled = true, priority = EventPriority.LOW) fun VehicleMoveEvent.move() { - val players = vehicle.getPassengersRecursive().filterIsInstance() + vehicle.getPassengersRecursive().filterIsInstance() + .filterNot { it.hasPermission(Permissions.ADMIN_PERMISSION) && it.canMoveSections } + .forEach { it.leaveVehicle() } - players.firstOrNull { it.hasPermission(Permissions.ADMIN_PERMISSION) && it.canMoveSections }?.let { - MovementHandler.handleMovement(it, from, to) - } + MovementHandler.handleMovement(vehicle, from, to) } @EventHandler fun EntityMoveEvent.entityMove() { - if (!hasExplicitlyChangedPosition()) return - if (entity.getPassengersRecursive().isEmpty()) return - entity.getPassengersRecursive().filterIsInstance() - .filter { rider -> rider.hasPermission(Permissions.ADMIN_PERMISSION) && rider.canMoveSections } - .forEach { MovementHandler.handleMovement(it, from, to) } + //if (!hasExplicitlyChangedPosition()) return + //if (entity.getPassengersRecursive().isEmpty()) return + //entity.getPassengersRecursive().filterIsInstance() + // .filter { rider -> rider.hasPermission(Permissions.ADMIN_PERMISSION) && rider.canMoveSections } + // .forEach { MovementHandler.handleMovement(it, from, to) } } } diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/movement/BedrockBlockingInvalidTeleportHandler.kt b/src/main/kotlin/com/mineinabyss/deeperworld/movement/BedrockBlockingInvalidTeleportHandler.kt index d41227b..58a19ba 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/movement/BedrockBlockingInvalidTeleportHandler.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/movement/BedrockBlockingInvalidTeleportHandler.kt @@ -8,10 +8,11 @@ import com.mineinabyss.idofront.time.ticks import kotlinx.coroutines.delay import org.bukkit.Location import org.bukkit.Material +import org.bukkit.entity.Entity import org.bukkit.entity.Player -class BedrockBlockingInvalidTeleportHandler(player: Player, from: Location, to: Location) : - InvalidTeleportHandler(player, from, to) { +class BedrockBlockingInvalidTeleportHandler(override val entity: Entity, from: Location, to: Location) : + InvalidTeleportHandler(from, to) { override fun handleInvalidTeleport() { from.block.type = Material.BEDROCK @@ -29,12 +30,12 @@ class BedrockBlockingInvalidTeleportHandler(player: Player, from: Location, to: MovementListener.temporaryBedrock.remove(spawnedBedrock) } - val oldFallDistance = player.fallDistance - val oldVelocity = player.velocity + val oldFallDistance = entity.fallDistance + val oldVelocity = entity.velocity - player.teleport(from.up(1)) + entity.teleport(from.up(1)) - player.fallDistance = oldFallDistance - player.velocity = oldVelocity + entity.fallDistance = oldFallDistance + entity.velocity = oldVelocity } } diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/movement/InvalidTeleportHandler.kt b/src/main/kotlin/com/mineinabyss/deeperworld/movement/InvalidTeleportHandler.kt index 43f6540..bd320a3 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/movement/InvalidTeleportHandler.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/movement/InvalidTeleportHandler.kt @@ -4,11 +4,11 @@ import com.mineinabyss.idofront.messaging.error import org.bukkit.Location import org.bukkit.entity.Player -abstract class InvalidTeleportHandler(val player: Player, val from: Location, val to: Location) : +abstract class InvalidTeleportHandler(val from: Location, val to: Location) : TeleportHandler { final override fun handleTeleport() { handleInvalidTeleport() - player.error("There is no where for you to teleport") + entity.error("There is no where for you to teleport") } override fun isValidTeleport(): Boolean { diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/movement/MovementHandler.kt b/src/main/kotlin/com/mineinabyss/deeperworld/movement/MovementHandler.kt index fbb854a..fee612c 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/movement/MovementHandler.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/movement/MovementHandler.kt @@ -5,6 +5,7 @@ import com.mineinabyss.deeperworld.movement.transition.ConfigSectionChecker import com.mineinabyss.deeperworld.movement.transition.SectionTransition import com.mineinabyss.deeperworld.movement.transition.TransitionKind import com.mineinabyss.deeperworld.movement.transition.toEvent +import com.mineinabyss.deeperworld.world.section.section import com.mineinabyss.idofront.events.call import com.mineinabyss.idofront.textcomponents.miniMsg import net.kyori.adventure.text.format.NamedTextColor @@ -12,6 +13,8 @@ import net.kyori.adventure.title.Title import org.bukkit.GameMode import org.bukkit.Location import org.bukkit.attribute.Attribute +import org.bukkit.entity.Entity +import org.bukkit.entity.LivingEntity import org.bukkit.entity.Player import java.util.* import kotlin.time.Duration.Companion.seconds @@ -21,15 +24,25 @@ object MovementHandler { private val sectionCheckers = listOf(ConfigSectionChecker) val teleportCooldown = mutableSetOf() - fun handleMovement(player: Player, from: Location, to: Location) { - if (sectionCheckers.any { it.inSection(player) }) { - sectionCheckers.firstNotNullOfOrNull { it.checkForTransition(player, from, to) }?.let { - with(getTeleportHandler(player, it)) { - if (this.isValidTeleport()) it.toEvent(player).call { this@with.handleTeleport() } - else this.handleTeleport() + fun handleMovement(entity: Entity, from: Location, to: Location) { + if (sectionCheckers.any { it.inSection(entity) }) { + sectionCheckers.firstNotNullOfOrNull { it.checkForTransition(entity, from, to) }?.let { + val handler = getTeleportHandler(entity, it) + val entity = handler.entity + when { + entity is Player -> when { + handler.isValidTeleport() -> it.toEvent(entity).call { handler.handleTeleport() } + else -> handler.handleTeleport() + } + else -> { + if (handler.isValidTeleport()) entity.passengers.filterIsInstance().forEach { p -> + if (!it.toEvent(p).callEvent()) p.leaveVehicle() + }.also { handler.handleTeleport() } + else handler.handleTeleport() + } } } - } else player.applyOutOfBoundsDamage() + } else (entity as? Player)?.applyOutOfBoundsDamage() } //TODO abstract this away. Should instead do out of bounds action if out of bounds. @@ -58,34 +71,25 @@ object MovementHandler { private fun getTeleportHandler( - player: Player, + entity: Entity, sectionTransition: SectionTransition ): TeleportHandler { - if (sectionTransition.teleportUnnecessary || player.uniqueId in teleportCooldown) return object : TeleportHandler { + val entity = entity.vehicle ?: entity + if (sectionTransition.teleportUnnecessary || entity.uniqueId in teleportCooldown) return object : TeleportHandler { + override val entity: Entity = entity override fun handleTeleport() {} - override fun isValidTeleport() = true + override fun isValidTeleport() = false } + teleportCooldown += entity.uniqueId + teleportCooldown += entity.passengers.map { it.uniqueId } - val teleportEntity = player.vehicle ?: player - teleportCooldown += teleportEntity.uniqueId - - if (player.gameMode != GameMode.SPECTATOR && sectionTransition.to.block.isSolid) { + if (entity is LivingEntity && (entity !is Player || entity.gameMode != GameMode.SPECTATOR) && sectionTransition.to.block.isSolid) { return if (sectionTransition.kind == TransitionKind.ASCEND) { - UndoMovementInvalidTeleportHandler( - player, - sectionTransition.from, - sectionTransition.to - ) - } else { - BedrockBlockingInvalidTeleportHandler( - player, - sectionTransition.from, - sectionTransition.to - ) - } + UndoMovementInvalidTeleportHandler(entity, sectionTransition.from, sectionTransition.to) + } else BedrockBlockingInvalidTeleportHandler(entity, sectionTransition.from, sectionTransition.to) } - return TransitionTeleportHandler(teleportEntity, sectionTransition.from, sectionTransition.to) + return TransitionTeleportHandler(entity, sectionTransition.from, sectionTransition.to) } } diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/movement/TeleportHandler.kt b/src/main/kotlin/com/mineinabyss/deeperworld/movement/TeleportHandler.kt index be4f67b..5812433 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/movement/TeleportHandler.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/movement/TeleportHandler.kt @@ -1,6 +1,9 @@ package com.mineinabyss.deeperworld.movement +import org.bukkit.entity.Entity + interface TeleportHandler { + val entity: Entity fun handleTeleport() fun isValidTeleport() : Boolean } diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/movement/TransitionTeleportHandler.kt b/src/main/kotlin/com/mineinabyss/deeperworld/movement/TransitionTeleportHandler.kt index 1103363..1253252 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/movement/TransitionTeleportHandler.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/movement/TransitionTeleportHandler.kt @@ -12,12 +12,12 @@ import org.bukkit.entity.LivingEntity import org.bukkit.entity.Player import org.bukkit.event.player.PlayerTeleportEvent -class TransitionTeleportHandler(val teleportEntity: Entity, val from: Location, val to: Location) : TeleportHandler { +class TransitionTeleportHandler(override val entity: Entity, val from: Location, val to: Location) : TeleportHandler { override fun handleTeleport() { val oldLeashedEntities = leashedEntities() val spectators = spectatorEntities() - val oldVelocity = teleportEntity.velocity + val oldVelocity = entity.velocity val teleportFlags: Array = listOf(TeleportFlag.Relative.YAW, TeleportFlag.Relative.PITCH, TeleportFlag.Relative.X, TeleportFlag.Relative.Y, TeleportFlag.Relative.Z, TeleportFlag.EntityState.RETAIN_PASSENGERS, TeleportFlag.EntityState.RETAIN_VEHICLE).toTypedArray() // Unleash all the leashed entities before teleporting them, to prevent leads from dropping. @@ -26,23 +26,24 @@ class TransitionTeleportHandler(val teleportEntity: Entity, val from: Location, spectators.values.flatten().forEach { it.spectatorTarget = null } deeperWorld.plugin.launch { - teleportEntity.teleportAsync(to, PlayerTeleportEvent.TeleportCause.PLUGIN, *teleportFlags).asDeferred().await() - teleportEntity.velocity = oldVelocity + entity.teleportAsync(to, PlayerTeleportEvent.TeleportCause.PLUGIN, *teleportFlags).asDeferred().await() oldLeashedEntities.forEach { (leashHolder, leashEntities) -> leashEntities.forEach { - it.teleportAsync(teleportEntity.location, PlayerTeleportEvent.TeleportCause.PLUGIN, *teleportFlags).asDeferred().await() + it.teleportAsync(entity.location, PlayerTeleportEvent.TeleportCause.PLUGIN, *teleportFlags).asDeferred().await() it.setLeashHolder(leashHolder) } } spectators.forEach { (spectatorTarget, spectators) -> spectators.forEach { - it.teleportAsync(teleportEntity.location, PlayerTeleportEvent.TeleportCause.PLUGIN, *teleportFlags).asDeferred().await() + it.teleportAsync(entity.location, PlayerTeleportEvent.TeleportCause.PLUGIN, *teleportFlags).asDeferred().await() it.spectatorTarget = spectatorTarget } } delay(10.ticks) - MovementHandler.teleportCooldown -= teleportEntity.uniqueId + entity.velocity = oldVelocity + MovementHandler.teleportCooldown -= entity.uniqueId + MovementHandler.teleportCooldown -= entity.passengers.map { it.uniqueId }.toSet() } } @@ -51,9 +52,9 @@ class TransitionTeleportHandler(val teleportEntity: Entity, val from: Location, } private fun spectatorEntities(): Map> { - return when (teleportEntity) { - is Player -> mapOf(teleportEntity to teleportEntity.world.players.filter { it.spectatorTarget?.uniqueId == teleportEntity.uniqueId }) - else -> teleportEntity.passengers.associateWith { p -> + return when (entity) { + is Player -> mapOf(entity to entity.world.players.filter { it.spectatorTarget?.uniqueId == entity.uniqueId }) + else -> entity.passengers.associateWith { p -> p.world.players.filter { it.spectatorTarget?.uniqueId == p.uniqueId } } } @@ -61,19 +62,15 @@ class TransitionTeleportHandler(val teleportEntity: Entity, val from: Location, private fun leashedEntities(): Map> { // Max leashed entity range is 10 blocks, therefore these parameter values - return when (teleportEntity) { - is Player -> mapOf(teleportEntity to teleportEntity.location + return when (entity) { + is Player -> mapOf(entity to entity.location .getNearbyEntitiesByType(LivingEntity::class.java, 20.0) - .filter { it.isLeashed && it.leashHolder.uniqueId == teleportEntity.uniqueId }) + .filter { it.isLeashed && it.leashHolder.uniqueId == entity.uniqueId }) - else -> teleportEntity.passengers.filterIsInstance().associateWith { + else -> entity.passengers.filterIsInstance().associateWith { it.location.getNearbyEntitiesByType(LivingEntity::class.java, 20.0) - .filter { it.isLeashed && it.leashHolder.uniqueId == teleportEntity.uniqueId } + .filter { it.isLeashed && it.leashHolder.uniqueId == entity.uniqueId } } } } - - private fun Entity.recursiveLeashEntities(): List { - return location.getNearbyEntitiesByType(LivingEntity::class.java, 20.0).filter { it.isLeashed && it.leashHolder.uniqueId == this.uniqueId } - } } diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/movement/UndoMovementInvalidTeleportHandler.kt b/src/main/kotlin/com/mineinabyss/deeperworld/movement/UndoMovementInvalidTeleportHandler.kt index 3086ac3..7e54404 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/movement/UndoMovementInvalidTeleportHandler.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/movement/UndoMovementInvalidTeleportHandler.kt @@ -1,11 +1,12 @@ package com.mineinabyss.deeperworld.movement import org.bukkit.Location +import org.bukkit.entity.Entity import org.bukkit.entity.Player -class UndoMovementInvalidTeleportHandler(player: Player, from: Location, to: Location) : - InvalidTeleportHandler(player, from, to) { +class UndoMovementInvalidTeleportHandler(override val entity: Entity, from: Location, to: Location) : + InvalidTeleportHandler(from, to) { override fun handleInvalidTeleport() { - player.teleport(from) + entity.teleport(from) } } diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/movement/transition/ConfigSectionChecker.kt b/src/main/kotlin/com/mineinabyss/deeperworld/movement/transition/ConfigSectionChecker.kt index d311497..495a2ca 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/movement/transition/ConfigSectionChecker.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/movement/transition/ConfigSectionChecker.kt @@ -4,15 +4,16 @@ import com.mineinabyss.deeperworld.world.section.correspondingLocation import com.mineinabyss.deeperworld.world.section.inSectionTransition import com.mineinabyss.deeperworld.world.section.section import org.bukkit.Location +import org.bukkit.entity.Entity import org.bukkit.entity.Player object ConfigSectionChecker : SectionChecker { - override fun inSection(player: Player): Boolean { - return player.location.section != null + override fun inSection(entity: Entity): Boolean { + return entity.location.section != null } override fun checkForTransition( - player: Player, + entity: Entity, from: Location, to: Location ): SectionTransition? { diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/movement/transition/SectionChecker.kt b/src/main/kotlin/com/mineinabyss/deeperworld/movement/transition/SectionChecker.kt index f02f113..455059a 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/movement/transition/SectionChecker.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/movement/transition/SectionChecker.kt @@ -1,14 +1,15 @@ package com.mineinabyss.deeperworld.movement.transition import org.bukkit.Location +import org.bukkit.entity.Entity import org.bukkit.entity.Player interface SectionChecker { - fun inSection(player: Player) : Boolean + fun inSection(entity: Entity) : Boolean fun checkForTransition( - player: Player, + entity: Entity, from: Location, to: Location ): SectionTransition?