Compare commits
No commits in common. "2d9e35312b418e48dd5a33028968869bee73af24" and "a074ba56ae5a832d45f6511427c6cbe0ab774db2" have entirely different histories.
2d9e35312b
...
a074ba56ae
9 changed files with 13 additions and 174 deletions
|
|
@ -1,7 +1,6 @@
|
||||||
package ch.offbeatwit.bestbuds
|
package ch.offbeatwit.bestbuds
|
||||||
|
|
||||||
import ch.offbeatwit.bestbuds.managers.Context
|
import ch.offbeatwit.bestbuds.managers.Context
|
||||||
import ch.offbeatwit.bestbuds.modules.AdoptionModule
|
|
||||||
import ch.offbeatwit.bestbuds.modules.AntiGriefModule
|
import ch.offbeatwit.bestbuds.modules.AntiGriefModule
|
||||||
import ch.offbeatwit.bestbuds.modules.CommandsModule
|
import ch.offbeatwit.bestbuds.modules.CommandsModule
|
||||||
import ch.offbeatwit.bestbuds.modules.InteractionModule
|
import ch.offbeatwit.bestbuds.modules.InteractionModule
|
||||||
|
|
@ -17,7 +16,6 @@ class BestBudsPlugin : JavaPlugin() {
|
||||||
moduleLoader.load(::InteractionModule)
|
moduleLoader.load(::InteractionModule)
|
||||||
moduleLoader.load(::CommandsModule)
|
moduleLoader.load(::CommandsModule)
|
||||||
moduleLoader.load(::AntiGriefModule)
|
moduleLoader.load(::AntiGriefModule)
|
||||||
moduleLoader.load(::AdoptionModule)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDisable() {
|
override fun onDisable() {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
package ch.offbeatwit.bestbuds
|
|
||||||
|
|
||||||
import org.bukkit.NamespacedKey
|
|
||||||
|
|
||||||
val ADOPTION_TARGET = NamespacedKey("bestbuds", "adoption_target")
|
|
||||||
val IS_ADOPTABLE = NamespacedKey("bestbuds", "is_adoptable")
|
|
||||||
|
|
@ -1,106 +0,0 @@
|
||||||
package ch.offbeatwit.bestbuds.modules
|
|
||||||
|
|
||||||
import ch.offbeatwit.bestbuds.ADOPTION_TARGET
|
|
||||||
import ch.offbeatwit.bestbuds.isOwnerOf
|
|
||||||
import ch.offbeatwit.bestbuds.managers.Context
|
|
||||||
import ch.offbeatwit.bestbuds.pet.PetInfo
|
|
||||||
import ch.offbeatwit.bestbuds.util.UUIDDataType
|
|
||||||
import ch.offbeatwit.bestbuds.util.error
|
|
||||||
import ch.offbeatwit.bestbuds.util.tr
|
|
||||||
import net.kyori.adventure.text.Component
|
|
||||||
import net.kyori.adventure.text.Component.text
|
|
||||||
import net.kyori.adventure.text.JoinConfiguration
|
|
||||||
import org.bukkit.Material
|
|
||||||
import org.bukkit.entity.Player
|
|
||||||
import org.bukkit.entity.Tameable
|
|
||||||
import org.bukkit.event.EventHandler
|
|
||||||
import org.bukkit.event.Listener
|
|
||||||
import org.bukkit.event.player.PlayerInteractEntityEvent
|
|
||||||
import org.bukkit.inventory.EquipmentSlot
|
|
||||||
import org.bukkit.inventory.ItemStack
|
|
||||||
import org.bukkit.inventory.meta.BookMeta
|
|
||||||
|
|
||||||
class AdoptionModule(ctx: Context) : BestBudsModule(ctx), Listener {
|
|
||||||
val adoptionItem = Material.PAPER
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
fun onInteract(ev: PlayerInteractEntityEvent) {
|
|
||||||
val target = ev.rightClicked
|
|
||||||
if (target !is Tameable || !target.isTamed) return
|
|
||||||
val info = PetInfo(target)
|
|
||||||
|
|
||||||
val heldItem = ev.player.inventory.getItem(ev.hand)
|
|
||||||
|
|
||||||
if (ev.player.isSneaking && ev.player.isOwnerOf(target) && heldItem.type == adoptionItem) {
|
|
||||||
ev.isCancelled = true
|
|
||||||
setupAdoption(ev.player, ev.hand, target)
|
|
||||||
} else if (heldItem.type == Material.WRITTEN_BOOK) {
|
|
||||||
val bookTarget = heldItem.persistentDataContainer[ADOPTION_TARGET, UUIDDataType] ?: return
|
|
||||||
ev.isCancelled = true
|
|
||||||
|
|
||||||
if (target.uniqueId == bookTarget && info.isAdoptable) {
|
|
||||||
info.isAdoptable = false
|
|
||||||
heldItem.subtract()
|
|
||||||
|
|
||||||
if (ev.player.isOwnerOf(target)) {
|
|
||||||
ev.player.sendActionBar(tr(info.nameComponent, text("is no longer adoptable")))
|
|
||||||
} else {
|
|
||||||
target.owner = ev.player
|
|
||||||
|
|
||||||
ev.player.sendActionBar(
|
|
||||||
tr(
|
|
||||||
text("Adopted ")
|
|
||||||
.append(info.nameComponent)
|
|
||||||
.append(text("! Take good care of them!"))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else if (target.uniqueId == bookTarget) {
|
|
||||||
ev.player.sendActionBar(error("That pet is not currently adoptable"))
|
|
||||||
} else {
|
|
||||||
ev.player.sendActionBar(error("Those papers aren't for this pet!"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setupAdoption(sender: Player, hand: EquipmentSlot, pet: Tameable) {
|
|
||||||
val info = PetInfo(pet)
|
|
||||||
val stack = sender.inventory.getItem(hand)
|
|
||||||
if (stack.type != adoptionItem) return // sanity check
|
|
||||||
if (stack.amount == 0) return
|
|
||||||
|
|
||||||
stack.subtract()
|
|
||||||
|
|
||||||
val adoptionPaper = ItemStack(Material.WRITTEN_BOOK, 1).apply {
|
|
||||||
editMeta(BookMeta::class.java) {
|
|
||||||
it.title(Component.join(JoinConfiguration.spaces(),
|
|
||||||
text("Adoption papers for"), info.nameComponent))
|
|
||||||
it.author(sender.displayName())
|
|
||||||
|
|
||||||
Component.join(JoinConfiguration.newlines(),
|
|
||||||
text("Adopt ").append(info.nameComponent).append(text(" today!")),
|
|
||||||
text(""),
|
|
||||||
text("Right-click on ").append(info.nameComponent)
|
|
||||||
.append(text(" with this book to adopt them."))
|
|
||||||
).apply { it.addPages(this) }
|
|
||||||
}
|
|
||||||
|
|
||||||
editPersistentDataContainer {
|
|
||||||
it.set(ADOPTION_TARGET, UUIDDataType, pet.uniqueId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stack.isEmpty) {
|
|
||||||
sender.inventory.setItem(hand, adoptionPaper)
|
|
||||||
} else {
|
|
||||||
val res = sender.inventory.addItem(adoptionPaper)
|
|
||||||
if (res.isNotEmpty()) {
|
|
||||||
sender.world.dropItem(pet.location, adoptionPaper)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
info.isAdoptable = true
|
|
||||||
|
|
||||||
sender.sendActionBar(tr("Set pet as adoptable!"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -24,8 +24,8 @@ class CommandsModule(ctx: Context) : BestBudsModule(ctx), CommandRegistrar {
|
||||||
val root = literal("bestbuds")
|
val root = literal("bestbuds")
|
||||||
.then(transfer())
|
.then(transfer())
|
||||||
.then(release())
|
.then(release())
|
||||||
.then(trust())
|
.then(allow())
|
||||||
.then(untrust())
|
.then(disallow())
|
||||||
.executes(BestBudsHelpTopic)
|
.executes(BestBudsHelpTopic)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
|
@ -78,8 +78,8 @@ class CommandsModule(ctx: Context) : BestBudsModule(ctx), CommandRegistrar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun trust(): CommandNode<CommandSourceStack> {
|
fun allow(): CommandNode<CommandSourceStack> {
|
||||||
return literal("trust")
|
return literal("allow")
|
||||||
.then(argument("player", ArgumentTypes.playerProfiles())
|
.then(argument("player", ArgumentTypes.playerProfiles())
|
||||||
.executes { ctx ->
|
.executes { ctx ->
|
||||||
val sender = ctx.source.sender
|
val sender = ctx.source.sender
|
||||||
|
|
@ -95,7 +95,7 @@ class CommandsModule(ctx: Context) : BestBudsModule(ctx), CommandRegistrar {
|
||||||
if (this.ctx.whitelistManager.addToWhitelist(sender, target)) {
|
if (this.ctx.whitelistManager.addToWhitelist(sender, target)) {
|
||||||
sender.sendMessage(tr("${target.name} can now interact with your pets"))
|
sender.sendMessage(tr("${target.name} can now interact with your pets"))
|
||||||
} else {
|
} else {
|
||||||
sender.sendMessage(error("${target.name} is already trusted"))
|
sender.sendMessage(error("${target.name} is already on the allowlist"))
|
||||||
}
|
}
|
||||||
|
|
||||||
Command.SINGLE_SUCCESS
|
Command.SINGLE_SUCCESS
|
||||||
|
|
@ -103,8 +103,8 @@ class CommandsModule(ctx: Context) : BestBudsModule(ctx), CommandRegistrar {
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun untrust(): CommandNode<CommandSourceStack> {
|
fun disallow(): CommandNode<CommandSourceStack> {
|
||||||
return literal("untrust")
|
return literal("disallow")
|
||||||
.then(argument("player", ArgumentTypes.playerProfiles())
|
.then(argument("player", ArgumentTypes.playerProfiles())
|
||||||
.executes { ctx ->
|
.executes { ctx ->
|
||||||
val sender = ctx.source.sender
|
val sender = ctx.source.sender
|
||||||
|
|
@ -120,7 +120,7 @@ class CommandsModule(ctx: Context) : BestBudsModule(ctx), CommandRegistrar {
|
||||||
if (this.ctx.whitelistManager.removeFromWhitelist(sender, target)) {
|
if (this.ctx.whitelistManager.removeFromWhitelist(sender, target)) {
|
||||||
sender.sendMessage(tr("${target.name} can no longer interact with your pets"))
|
sender.sendMessage(tr("${target.name} can no longer interact with your pets"))
|
||||||
} else {
|
} else {
|
||||||
sender.sendMessage(error("${target.name} isn't trusted"))
|
sender.sendMessage(error("${target.name} isn't on the allowlist"))
|
||||||
}
|
}
|
||||||
|
|
||||||
Command.SINGLE_SUCCESS
|
Command.SINGLE_SUCCESS
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,8 @@ object BestBudsHelpTopic : HelpTopic(), Command<CommandSourceStack> {
|
||||||
val commands = listOf(
|
val commands = listOf(
|
||||||
CommandHelp("/bb transfer <player>", "Change the owner of a pet to another player"),
|
CommandHelp("/bb transfer <player>", "Change the owner of a pet to another player"),
|
||||||
CommandHelp("/bb release", "Un-tame a pet, releasing them back into the wild"),
|
CommandHelp("/bb release", "Un-tame a pet, releasing them back into the wild"),
|
||||||
CommandHelp("/bb trust <player>", "Allow another player to ride, leash, hurt and rename your pets"),
|
CommandHelp("/bb allow <player>", "Allow another player to ride, leash, hurt and rename your pets"),
|
||||||
CommandHelp("/bb untrust <player>", "Remove a player from your trusted list"),
|
CommandHelp("/bb disallow <player>", "Remove a player from your allowlist"),
|
||||||
)
|
)
|
||||||
|
|
||||||
return Component.join(JoinConfiguration.newlines(), commands.map {
|
return Component.join(JoinConfiguration.newlines(), commands.map {
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ import org.bukkit.entity.ChestedHorse
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.entity.Tameable
|
import org.bukkit.entity.Tameable
|
||||||
import org.bukkit.event.EventHandler
|
import org.bukkit.event.EventHandler
|
||||||
import org.bukkit.event.EventPriority
|
|
||||||
import org.bukkit.event.Listener
|
import org.bukkit.event.Listener
|
||||||
import org.bukkit.event.player.PlayerInteractEntityEvent
|
import org.bukkit.event.player.PlayerInteractEntityEvent
|
||||||
import org.bukkit.util.Transformation
|
import org.bukkit.util.Transformation
|
||||||
|
|
@ -24,9 +23,8 @@ import org.joml.Vector3f
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
class InteractionModule(ctx: Context) : BestBudsModule(ctx), Listener {
|
class InteractionModule(ctx: Context) : BestBudsModule(ctx), Listener {
|
||||||
@EventHandler(priority = EventPriority.HIGH)
|
@EventHandler
|
||||||
fun onClickPet(ev: PlayerInteractEntityEvent) {
|
fun onClickPet(ev: PlayerInteractEntityEvent) {
|
||||||
if (ev.isCancelled) return
|
|
||||||
if (!ev.player.isSneaking) return
|
if (!ev.player.isSneaking) return
|
||||||
|
|
||||||
val target = ev.rightClicked
|
val target = ev.rightClicked
|
||||||
|
|
@ -56,13 +54,11 @@ class InteractionModule(ctx: Context) : BestBudsModule(ctx), Listener {
|
||||||
?.also { it.completeFromCache() }
|
?.also { it.completeFromCache() }
|
||||||
?.let { text(it.name ?: "unknown", NamedTextColor.GOLD) }
|
?.let { text(it.name ?: "unknown", NamedTextColor.GOLD) }
|
||||||
?: text("nobody", NamedTextColor.RED)
|
?: text("nobody", NamedTextColor.RED)
|
||||||
|
|
||||||
val component = Component.join(
|
val component = Component.join(
|
||||||
JoinConfiguration.newlines(),
|
JoinConfiguration.newlines(),
|
||||||
info.nameComponent,
|
info.nameComponent,
|
||||||
text("Owned by ").append(owner),
|
text("Owned by ").append(owner),
|
||||||
text("Health: ").append(info.healthComponent),
|
text("Health: ").append(info.healthComponent)
|
||||||
*(if (info.isAdoptable) arrayOf(text("Adoptable").color(NamedTextColor.GREEN)) else emptyArray())
|
|
||||||
).style(INFO_TEXT_STYLE)
|
).style(INFO_TEXT_STYLE)
|
||||||
|
|
||||||
ctx.hologramManager.showSingle(this, pet.location, component) {
|
ctx.hologramManager.showSingle(this, pet.location, component) {
|
||||||
|
|
|
||||||
|
|
@ -18,15 +18,10 @@ class InfoDialog(val pet: Tameable) : Supplier<DialogLike> {
|
||||||
@Suppress("UnstableApiUsage")
|
@Suppress("UnstableApiUsage")
|
||||||
override fun get(): DialogLike {
|
override fun get(): DialogLike {
|
||||||
return Dialog.create { builder ->
|
return Dialog.create { builder ->
|
||||||
val body = mutableListOf(
|
val body = listOf(
|
||||||
DialogBody.plainMessage(text("Type: ").append(text(pet.type.name, NamedTextColor.GOLD))),
|
DialogBody.plainMessage(text("Type: ").append(text(pet.type.name, NamedTextColor.GOLD))),
|
||||||
DialogBody.plainMessage(text("Health: ").append(info.healthComponent)),
|
DialogBody.plainMessage(text("Health: ").append(info.healthComponent)),
|
||||||
)
|
)
|
||||||
|
|
||||||
if (info.isAdoptable) {
|
|
||||||
body.add(DialogBody.plainMessage(text("Adoptable!", NamedTextColor.GREEN)))
|
|
||||||
}
|
|
||||||
|
|
||||||
val base = DialogBase.builder(text("Managing ").append(pet.customName() ?: text(pet.name)))
|
val base = DialogBase.builder(text("Managing ").append(pet.customName() ?: text(pet.name)))
|
||||||
.body(body)
|
.body(body)
|
||||||
.canCloseWithEscape(true)
|
.canCloseWithEscape(true)
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
package ch.offbeatwit.bestbuds.pet
|
package ch.offbeatwit.bestbuds.pet
|
||||||
|
|
||||||
import ch.offbeatwit.bestbuds.IS_ADOPTABLE
|
|
||||||
import ch.offbeatwit.bestbuds.util.PET_NAME_STYLE
|
import ch.offbeatwit.bestbuds.util.PET_NAME_STYLE
|
||||||
import net.kyori.adventure.text.Component
|
import net.kyori.adventure.text.Component
|
||||||
import net.kyori.adventure.text.JoinConfiguration
|
import net.kyori.adventure.text.JoinConfiguration
|
||||||
import net.kyori.adventure.text.format.NamedTextColor
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
import org.bukkit.attribute.Attribute
|
import org.bukkit.attribute.Attribute
|
||||||
import org.bukkit.entity.Tameable
|
import org.bukkit.entity.Tameable
|
||||||
import org.bukkit.persistence.PersistentDataType
|
|
||||||
|
|
||||||
class PetInfo(val pet: Tameable) {
|
class PetInfo(val pet: Tameable) {
|
||||||
val nameComponent get() = (pet.customName() ?: Component.text(pet.name)).style(PET_NAME_STYLE)
|
val nameComponent get() = (pet.customName() ?: Component.text(pet.name)).style(PET_NAME_STYLE)
|
||||||
|
|
@ -23,8 +21,4 @@ class PetInfo(val pet: Tameable) {
|
||||||
Component.text(pet.health, healthColor), Component.text(maxHealth?.toString() ?: "???", healthColor)
|
Component.text(pet.health, healthColor), Component.text(maxHealth?.toString() ?: "???", healthColor)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
var isAdoptable
|
|
||||||
get() = pet.persistentDataContainer[IS_ADOPTABLE, PersistentDataType.BOOLEAN] ?: false
|
|
||||||
set(value) = pet.persistentDataContainer.set(IS_ADOPTABLE, PersistentDataType.BOOLEAN, value)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
package ch.offbeatwit.bestbuds.util
|
|
||||||
|
|
||||||
import org.bukkit.persistence.PersistentDataAdapterContext
|
|
||||||
import org.bukkit.persistence.PersistentDataType
|
|
||||||
import java.lang.Long
|
|
||||||
import java.nio.ByteBuffer
|
|
||||||
import java.util.*
|
|
||||||
import kotlin.ByteArray
|
|
||||||
|
|
||||||
object UUIDDataType : PersistentDataType<ByteArray, UUID> {
|
|
||||||
override fun getPrimitiveType(): Class<ByteArray> {
|
|
||||||
return ByteArray::class.java
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getComplexType(): Class<UUID> {
|
|
||||||
return UUID::class.java
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toPrimitive(complex: UUID, context: PersistentDataAdapterContext): ByteArray {
|
|
||||||
val bb = ByteBuffer.allocate(Long.BYTES * 2)
|
|
||||||
bb.putLong(complex.mostSignificantBits)
|
|
||||||
bb.putLong(complex.leastSignificantBits)
|
|
||||||
return bb.array()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun fromPrimitive(primitive: ByteArray, context: PersistentDataAdapterContext): UUID {
|
|
||||||
val bb = ByteBuffer.wrap(primitive)
|
|
||||||
val msb = bb.getLong()
|
|
||||||
val lsb = bb.getLong()
|
|
||||||
return UUID(msb, lsb)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue