diff --git a/src/main/kotlin/network/warzone/mars/Mars.kt b/src/main/kotlin/network/warzone/mars/Mars.kt index 45b732c..5bcb82c 100644 --- a/src/main/kotlin/network/warzone/mars/Mars.kt +++ b/src/main/kotlin/network/warzone/mars/Mars.kt @@ -27,6 +27,8 @@ import network.warzone.mars.player.decoration.PrefixDecorationProvider import network.warzone.mars.player.feature.PlayerService import network.warzone.mars.player.models.PlayerStats import network.warzone.mars.player.tablist.overrideTabManager +import network.warzone.mars.player.listeners.tasks.ChairRotationTask +import network.warzone.mars.player.controllers.SitController import org.bukkit.Bukkit import org.bukkit.event.Listener import org.bukkit.plugin.java.JavaPlugin @@ -37,6 +39,7 @@ import java.util.concurrent.CompletableFuture class Mars : JavaPlugin() { companion object { lateinit var instance: Mars + var sitController = SitController(); fun async(block: suspend() -> Unit) { Bukkit.getScheduler().runTaskAsynchronously(get(), Runnable { @@ -99,6 +102,7 @@ class Mars : JavaPlugin() { BukkitIntake(this@Mars, commandGraph).register() + ChairRotationTask().start() overrideDefaultProviders() } @@ -108,8 +112,9 @@ class Mars : JavaPlugin() { val sessionLength = Date().time - activeSession.createdAt.time PlayerService.logout(it.uniqueId, it.name, activeSession._id, sessionLength) } - AchievementManager.unload() + sitController.clearAllSeats() + ChairRotationTask().cancel() } private fun overrideDefaultProviders() { diff --git a/src/main/kotlin/network/warzone/mars/player/PlayerManager.kt b/src/main/kotlin/network/warzone/mars/player/PlayerManager.kt index 8aa564d..117cf65 100644 --- a/src/main/kotlin/network/warzone/mars/player/PlayerManager.kt +++ b/src/main/kotlin/network/warzone/mars/player/PlayerManager.kt @@ -8,6 +8,7 @@ import network.warzone.mars.player.listeners.InventoryListener import network.warzone.mars.player.models.Session import network.warzone.mars.player.settings.SettingsListener import network.warzone.mars.punishment.models.Punishment +import network.warzone.mars.player.listeners.DismountListener import org.bukkit.entity.Player import java.util.* @@ -20,6 +21,7 @@ object PlayerManager { Mars.registerEvents(LevelDisplayListener()) Mars.registerEvents(CombatListener()) Mars.registerEvents(SettingsListener()) + Mars.registerEvents(DismountListener()) } fun createPlayer(player: Player, session: Session, activePunishments: List): PlayerContext { diff --git a/src/main/kotlin/network/warzone/mars/player/commands/MiscCommands.kt b/src/main/kotlin/network/warzone/mars/player/commands/MiscCommands.kt index 56a72d9..d89a2a6 100644 --- a/src/main/kotlin/network/warzone/mars/player/commands/MiscCommands.kt +++ b/src/main/kotlin/network/warzone/mars/player/commands/MiscCommands.kt @@ -11,6 +11,7 @@ import net.kyori.adventure.text.format.NamedTextColor import network.warzone.mars.Mars import network.warzone.mars.commands.providers.PlayerName import network.warzone.mars.player.achievements.gui.AchievementMenu +import network.warzone.mars.player.controllers.SitController import network.warzone.mars.utils.matchPlayer import network.warzone.mars.utils.menu.open import org.bukkit.Bukkit @@ -64,6 +65,16 @@ class MiscCommands { else sender.sendMessage("${ChatColor.AQUA}$possessive ${ChatColor.GRAY}ping is ${ChatColor.AQUA}${ping}ms") } + val sitController = Mars.sitController + @Command(aliases = ["sit"], desc = "Sit down to get comfortable!", perms = ["mars.sit"]) + fun onPlayerSit(@Sender sender: Player) { + if (!sitController.isSitting(sender)) { + sitController.sit(sender) + } else { + sitController.unSit(sender) + } + } + @Command( aliases = ["ach", "achievement", "achievements"], desc = "Open the achievements menu" diff --git a/src/main/kotlin/network/warzone/mars/player/controllers/SitController.kt b/src/main/kotlin/network/warzone/mars/player/controllers/SitController.kt new file mode 100644 index 0000000..6885a81 --- /dev/null +++ b/src/main/kotlin/network/warzone/mars/player/controllers/SitController.kt @@ -0,0 +1,102 @@ +package network.warzone.mars.player.controllers + +import app.ashcon.intake.CommandException +import org.bukkit.Bukkit +import org.bukkit.ChatColor +import org.bukkit.Location +import org.bukkit.Material +import org.bukkit.block.Block +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity +import org.bukkit.entity.ArmorStand +import org.bukkit.entity.Entity +import org.bukkit.entity.EntityType +import org.bukkit.entity.Player +import java.util.* +import kotlin.math.floor + +class SitController { + val sitting: HashMap> = HashMap() + + fun sit(player: Player) { + if (isSitting(player)) { + return; + } + val block = getBlockBelow(player) + if(!validSeatLocation(player, block)) { + throw CommandException("You were unable to sit!") + } + val chair = createChair(player.location, player) + sitting.put(player.uniqueId, Pair(chair, block)) + player.sendActionBar("${ChatColor.GREEN}You are now sitting!") + } + + fun isSitting(player: Player): Boolean { + return sitting.contains(player.uniqueId); + } + + fun unSit(player: Player) { + if (player.vehicle is ArmorStand) { + unSit(player, player.vehicle as ArmorStand) + } + } + + fun unSit(player: Player, seat: ArmorStand) { + if (!isSitting(player)) { + return; + } + player.sendActionBar("${ChatColor.DARK_RED}You are no longer sitting!") + sitting.remove(player.uniqueId) + seat.remove() + } + + fun validSeatLocation(player: Player, block: Block?): Boolean { + return !(block?.type == Material.AIR || block == null || !player.isOnGround); + } + + fun clearAllSeats() { + for ((uuid) in sitting) { + val player = Bukkit.getPlayer(uuid) ?: continue + unSit(player) + } + } + + private fun createChair(loc: Location, player: Player): ArmorStand { + val world = loc.world + val chair = world.spawnEntity(loc.add(0.0, 0.05, 0.0), EntityType.ARMOR_STAND) as ArmorStand + chair.setGravity(false) + chair.isMarker = true + chair.isSmall = true + chair.passenger = player + chair.isVisible = false + return chair + } + + fun getBlockBelow(entity: Entity): Block? { + val bb = (entity as CraftEntity).handle.boundingBox + val minX = floor(bb.a).toInt() + val maxX = floor(bb.d).toInt() + val minZ = floor(bb.c).toInt() + val maxZ = floor(bb.f).toInt() + val y = floor(bb.b - 0.02).toInt() + val world = entity.world + for (x in minX..maxX) { + for (z in minZ..maxZ) { + val block = world.getBlockAt(x, y, z) + if (block.type == Material.AIR) { + val belowBlock = world.getBlockAt(x,y - 1,z) + val type = belowBlock.type + if (type == Material.FENCE || + type == Material.NETHER_FENCE || + type == Material.COBBLE_WALL || + type == Material.STEP || + type == Material.FENCE_GATE) { + return belowBlock + } + } else { + return block + } + } + } + return null; + } +} \ No newline at end of file diff --git a/src/main/kotlin/network/warzone/mars/player/listeners/ChatListener.kt b/src/main/kotlin/network/warzone/mars/player/listeners/ChatListener.kt index 2c7a8c1..b42123d 100644 --- a/src/main/kotlin/network/warzone/mars/player/listeners/ChatListener.kt +++ b/src/main/kotlin/network/warzone/mars/player/listeners/ChatListener.kt @@ -252,4 +252,4 @@ class ChatListener : Listener { } return component.hoverEvent(hoverComponent.build()) } -} +} \ No newline at end of file diff --git a/src/main/kotlin/network/warzone/mars/player/listeners/DismountListener.kt b/src/main/kotlin/network/warzone/mars/player/listeners/DismountListener.kt new file mode 100644 index 0000000..6991505 --- /dev/null +++ b/src/main/kotlin/network/warzone/mars/player/listeners/DismountListener.kt @@ -0,0 +1,58 @@ +package network.warzone.mars.player.listeners + +import network.warzone.mars.Mars +import network.warzone.mars.feature.ResourceType +import network.warzone.mars.player.controllers.SitController +import org.bukkit.Bukkit +import org.bukkit.Location +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftArmorStand +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer +import org.bukkit.entity.ArmorStand +import org.bukkit.entity.Player +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener +import org.bukkit.event.block.BlockBreakEvent +import org.bukkit.event.entity.EntityDamageByEntityEvent +import org.bukkit.event.player.PlayerQuitEvent +import org.spigotmc.event.entity.EntityDismountEvent + +class DismountListener : Listener { + + + val sitController = Mars.sitController + @EventHandler + fun onDismount(event: EntityDismountEvent) { + if (event.entity is Player && event.dismounted is ArmorStand && sitController.isSitting(event.entity as Player)) { + val player = (event.entity as CraftPlayer).handle + val armorStand = (event.dismounted as CraftArmorStand).handle + sitController.unSit(event.entity as CraftPlayer) + player.setPositionRotation(armorStand.locX, armorStand.locY,armorStand.locZ, player.yaw, player.pitch) + } + } + + @EventHandler + fun onPlayerQuit(event: PlayerQuitEvent) { + if (sitController.isSitting(event.player)) { + sitController.unSit(event.player) + } + } + + @EventHandler + fun onPlayerDamaged(event: EntityDamageByEntityEvent) { + if (event.entity !is Player) return + val player = event.entity as Player + sitController.unSit(player); + } + + @EventHandler + fun onBlockBreak(event: BlockBreakEvent) { + val block = event.block + for ((uuid) in sitController.sitting) { + val player = Bukkit.getPlayer(uuid) + if (block == sitController.sitting.get(player.uniqueId)?.second) { + sitController.unSit(player) + } + } + } + +} \ No newline at end of file diff --git a/src/main/kotlin/network/warzone/mars/player/listeners/tasks/ChairRotationTask.kt b/src/main/kotlin/network/warzone/mars/player/listeners/tasks/ChairRotationTask.kt new file mode 100644 index 0000000..8ae1169 --- /dev/null +++ b/src/main/kotlin/network/warzone/mars/player/listeners/tasks/ChairRotationTask.kt @@ -0,0 +1,31 @@ +package network.warzone.mars.player.listeners.tasks + +import network.warzone.mars.Mars +import network.warzone.mars.player.controllers.SitController +import org.bukkit.Bukkit +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftArmorStand +import org.bukkit.scheduler.BukkitRunnable + +class ChairRotationTask : BukkitRunnable() { + + val sitController = Mars.sitController + + override fun run() { + for ((uuid) in sitController.sitting) { + val player = Bukkit.getPlayer(uuid) ?: continue + val armorStand = sitController.sitting.get(uuid)?.first ?: continue + val entityArmorStand = (armorStand as CraftArmorStand).handle + entityArmorStand.setPositionRotation( + entityArmorStand.locX, + entityArmorStand.locY, + entityArmorStand.locZ, + player.location.yaw, + entityArmorStand.pitch + ) + } + } + + fun start() { + this.runTaskTimer(Mars.Companion.get(), 0L, 1L) + } +} \ No newline at end of file