Skip to content

Commit

Permalink
✨ support preview of chiseled bookshelf
Browse files Browse the repository at this point in the history
  • Loading branch information
XiYang6666 committed Aug 7, 2024
1 parent 410a4d3 commit 0e19579
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 3 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ repositories {
}

dependencies {
compileOnly("io.papermc.paper:paper-api:1.20-R0.1-SNAPSHOT")
compileOnly("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT")
compileOnly("dev.jorel:commandapi-bukkit-core:9.4.2")
compileOnly("de.tr7zw:item-nbt-api-plugin:2.9.1")
compileOnly("net.kyori:adventure-text-minimessage:4.17.0") {}
Expand Down
7 changes: 5 additions & 2 deletions src/main/kotlin/xyz/xasmc/hashbook/HashBook.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,24 @@ import org.bukkit.plugin.java.JavaPlugin
import xyz.xasmc.hashbook.command.HashBookCommand
import xyz.xasmc.hashbook.config.ConfigLoader
import xyz.xasmc.hashbook.config.PluginConfig
import xyz.xasmc.hashbook.listener.BookshelfListener
import xyz.xasmc.hashbook.listener.OpenBookListener
import xyz.xasmc.hashbook.service.ItemDataServices
import xyz.xasmc.hashbook.service.StorageServices
import xyz.xasmc.hashbook.util.MarkUtil

class HashBook : JavaPlugin() {
override fun onEnable() {
HashBook.instance = this
instance = this
this.load()

Bukkit.getPluginManager().registerEvents(BookshelfListener(), this)
Bukkit.getPluginManager().registerEvents(OpenBookListener(), this)
HashBookCommand.create().register(this)
}

override fun onDisable() {

MarkUtil.clearAllMark()
}

fun load() {
Expand Down
61 changes: 61 additions & 0 deletions src/main/kotlin/xyz/xasmc/hashbook/listener/BookshelfListener.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package xyz.xasmc.hashbook.listener

import org.bukkit.Material
import org.bukkit.block.ChiseledBookshelf
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.player.PlayerMoveEvent
import org.bukkit.inventory.meta.BookMeta
import org.bukkit.inventory.meta.BookMeta.Generation.*
import xyz.xasmc.hashbook.util.MarkUtil


class BookshelfListener : Listener {


@EventHandler
fun onPlayerMode(event: PlayerMoveEvent) {
val player = event.player
val world = player.world
val direction = player.eyeLocation.direction
val maxDistance = 4.0
val result = player.world.rayTraceBlocks(player.eyeLocation, direction, maxDistance)
if (result == null) {
MarkUtil.removeMark(player)
return
}
val hitBlock = result.hitBlock
if (hitBlock == null) {
MarkUtil.removeMark(player)
return
}
val hitPosition = result.hitPosition
if (hitBlock.type != Material.CHISELED_BOOKSHELF) {
MarkUtil.removeMark(player)
return
}
val bookshelf = hitBlock.state as ChiseledBookshelf
val blockHitPosition = hitPosition.clone().subtract(hitBlock.location.toVector())
val item = bookshelf.inventory.getItem(bookshelf.getSlot(blockHitPosition))
if (item == null) {
MarkUtil.removeMark(player)
return
}
val normalizedEyeDirection = player.eyeLocation.direction.clone().normalize()
val markLocation = hitPosition.clone().subtract(normalizedEyeDirection.multiply(0.1))
val nameSb = StringBuilder(item.type.name)
if (item.type == Material.WRITTEN_BOOK) {
val meta = item.itemMeta as BookMeta
nameSb.append("\n<aqua>${meta.title}\n<gray>${meta.author}")
val generation = when (meta.generation) {
ORIGINAL -> "原稿"
COPY_OF_ORIGINAL -> "原稿的副本"
COPY_OF_COPY -> "副本的副本"
TATTERED -> "破烂不堪"
null -> "原稿"
}
nameSb.append("\n<gray>$generation")
}
MarkUtil.updateMark(player, markLocation.toLocation(world), nameSb.toString())
}
}
55 changes: 55 additions & 0 deletions src/main/kotlin/xyz/xasmc/hashbook/util/MarkUtil.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package xyz.xasmc.hashbook.util

import net.kyori.adventure.text.minimessage.MiniMessage
import org.bukkit.Location
import org.bukkit.World
import org.bukkit.entity.ArmorStand
import org.bukkit.entity.EntityType
import org.bukkit.entity.Player

object MarkUtil {
private val mm = MiniMessage.miniMessage()
private val playerMark = mutableMapOf<Player, MutableList<ArmorStand>>()

fun updateMark(player: Player, location: Location, name: String) {
val world = player.world
val textList = name.split("\n")
val count = textList.size
val interval = 0.2
val offset = -0.4

val marks = playerMark[player] ?: mutableListOf<ArmorStand>().also { playerMark[player] = it }

val currentCount = marks.size
when {
count > currentCount -> repeat(count - currentCount) { marks.add(createArmorStand(world)) }
count < currentCount -> repeat(currentCount - count) { marks.removeLast()?.remove() }
}

val top = location.clone().add(0.0, interval * count / 2 + offset, 0.0)
textList.forEachIndexed { i, it ->
val mark = playerMark[player]!![i]
mark.teleport(top.clone().add(0.0, -i * interval, 0.0))
mark.customName(mm.deserialize(it))
}
}

fun removeMark(player: Player) {
playerMark[player]?.forEach { it.remove() }
playerMark.remove(player)
}

fun clearAllMark() {
playerMark.forEach { it.value.forEach { it.remove() } }
playerMark.clear()
}

private fun createArmorStand(world: World): ArmorStand {
return (world.spawnEntity(Location(world, .0, .0, .0), EntityType.ARMOR_STAND) as ArmorStand).apply {
isVisible = false
isMarker = true
isCustomNameVisible = true
setGravity(false)
}
}
}

0 comments on commit 0e19579

Please sign in to comment.