Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions rebar/src/main/kotlin/io/github/pylonmc/rebar/Rebar.kt
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ object Rebar : JavaPlugin(), RebarAddon {
RebarTool.register(this, pm)
RebarWeapon.register(this, pm)
VanillaCookingFuel.register(this, pm)
RebarPickupable.register(this, pm)
RebarDroppable.register(this, pm)

// Rebar Entities
EntityListener.register(this, pm)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import kotlin.random.Random
object BlockStorage : Listener {

val rebarBlocksKey = rebarKey("blocks")
val rebarBlocksType = RebarSerializers.LIST.listTypeFrom(RebarSerializers.TAG_CONTAINER)

// Access to blocks, blocksByChunk, blocksById fields must be synchronized
// to prevent them briefly going out of sync
Expand Down Expand Up @@ -510,8 +511,7 @@ object BlockStorage : Listener {
}

private fun load(world: World, chunk: Chunk): List<RebarBlock> {
val type = RebarSerializers.LIST.listTypeFrom(RebarSerializers.TAG_CONTAINER)
val chunkBlocks = chunk.persistentDataContainer.get(rebarBlocksKey, type)?.mapNotNull { element ->
val chunkBlocks = chunk.persistentDataContainer.get(rebarBlocksKey, rebarBlocksType)?.mapNotNull { element ->
RebarBlock.deserialize(world, element)
}?.toMutableList() ?: mutableListOf()

Expand All @@ -522,9 +522,7 @@ object BlockStorage : Listener {
val serializedBlocks = chunkBlocks.mapNotNull {
RebarBlock.serialize(it, chunk.persistentDataContainer.adapterContext)
}

val type = RebarSerializers.LIST.listTypeFrom(RebarSerializers.TAG_CONTAINER)
chunk.persistentDataContainer.set(rebarBlocksKey, type, serializedBlocks)
chunk.persistentDataContainer.set(rebarBlocksKey, rebarBlocksType, serializedBlocks)
}

@EventHandler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import io.github.pylonmc.rebar.util.isFromAddon
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.bukkit.Bukkit
import org.bukkit.NamespacedKey
import org.bukkit.entity.Entity
import org.bukkit.event.EventHandler
Expand All @@ -37,6 +38,7 @@ object EntityStorage : Listener {
private val entitiesByKey: MutableMap<NamespacedKey, MutableSet<RebarEntity<*>>> = ConcurrentHashMap()
private val entityAutosaveTasks: MutableMap<UUID, Job> = ConcurrentHashMap()
private val whenEntityLoadsTasks: MutableMap<UUID, MutableSet<Consumer<RebarEntity<*>>>> = ConcurrentHashMap()
private val whenVanillaEntityLoadsTasks: MutableMap<UUID, MutableSet<Consumer<Entity>>> = ConcurrentHashMap()

// Access to entities, entitiesById fields must be synchronized to prevent them
// briefly going out of sync
Expand Down Expand Up @@ -130,7 +132,6 @@ object EntityStorage : Listener {
consumer.accept(it)
}
}

}

/**
Expand Down Expand Up @@ -161,6 +162,52 @@ object EntityStorage : Listener {
inline fun <reified T> whenEntityLoads(uuid: UUID, crossinline consumer: (T) -> Unit)
= whenEntityLoads(uuid, T::class.java) { t -> consumer(t) }

/**
* Schedules a task to run when the vanilla entity with id [uuid] is loaded, or runs the task immediately
* if the entity is already loaded.
*
* Useful for when you don't know whether a block or one of its associated entity will be loaded first.
*/
@JvmStatic
fun whenVanillaEntityLoads(uuid: UUID, consumer: Consumer<Entity>) {
val entity = Bukkit.getEntity(uuid)
if (entity != null) {
consumer.accept(entity)
} else {
whenVanillaEntityLoadsTasks.getOrPut(uuid) { mutableSetOf() }.add {
consumer.accept(it)
}
}
}

/**
* Schedules a task to run when the vanilla entity with id [uuid] is loaded, or runs the task immediately
* if the entity is already loaded.
*
* Useful for when you don't know whether a block or one of its associated entity will be loaded first.
*/
@JvmStatic
fun <T> whenVanillaEntityLoads(uuid: UUID, clazz: Class<T>, consumer: Consumer<T>) {
val entity = Bukkit.getEntity(uuid)
if (entity != null && clazz.isInstance(entity)) {
consumer.accept(clazz.cast(entity))
} else {
whenVanillaEntityLoadsTasks.getOrPut(uuid) { mutableSetOf() }.add {
consumer.accept(if (clazz.isInstance(it)) clazz.cast(it) else throw IllegalStateException("Entity $uuid was not of expected type ${clazz.simpleName}"))
}
}
}

/**
* Schedules a task to run when the vanilla entity with id [uuid] is loaded, or runs the task immediately
* if the entity is already loaded
*
* Useful for when you don't know whether a block or one of its associated entity will be loaded first.
*/
@JvmStatic
inline fun <reified T> whenVanillaEntityLoads(uuid: UUID, crossinline consumer: (T) -> Unit)
= whenVanillaEntityLoads(uuid, T::class.java) { t -> consumer(t) }

/**
* Returns false if the entity is not a [RebarEntity] or does not exist.
*/
Expand Down Expand Up @@ -203,10 +250,21 @@ object EntityStorage : Listener {
@EventHandler
private fun onEntityLoad(event: EntitiesLoadEvent) {
for (entity in event.entities) {
val vanillaTasks = whenVanillaEntityLoadsTasks.remove(entity.uniqueId)
if (vanillaTasks != null) {
for (task in vanillaTasks) {
try {
task.accept(entity)
} catch (t: Throwable) {
t.printStackTrace()
}
}
}

val rebarEntity = RebarEntity.deserialize(entity) ?: continue
add(rebarEntity)

val tasks = whenEntityLoadsTasks[rebarEntity.uuid]
val tasks = whenEntityLoadsTasks.remove(rebarEntity.uuid)
if (tasks != null) {
for (task in tasks) {
try {
Expand All @@ -215,7 +273,6 @@ object EntityStorage : Listener {
t.printStackTrace()
}
}
whenEntityLoadsTasks.remove(rebarEntity.uuid)
}

RebarEntityLoadEvent(rebarEntity).callEvent()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.github.pylonmc.rebar.guide.button

import io.github.pylonmc.rebar.content.guide.RebarGuide
import io.github.pylonmc.rebar.item.builder.ItemStackBuilder
import io.github.pylonmc.rebar.item.research.Research.Companion.guideHints
import io.github.pylonmc.rebar.util.rebarKey
import io.papermc.paper.datacomponent.DataComponentTypes
import net.kyori.adventure.text.Component
Expand All @@ -20,7 +21,11 @@ class BackButton : AbstractItem() {
override fun getItemProvider(player: Player) =
ItemStackBuilder.gui(Material.ENCHANTED_BOOK, rebarKey("guide_back"))
.set(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, false)
.name(Component.translatable("rebar.guide.button.back.name"))
.name(Component.translatable("rebar.guide.button.back.name")).apply {
if (player.guideHints) {
lore(Component.translatable("rebar.guide.button.back.hints"))
}
}

override fun handleClick(clickType: ClickType, player: Player, click: Click) {
val history = RebarGuide.history.getOrPut(player.uniqueId) { mutableListOf() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ open class PageButton(val stack: ItemStack, val page: GuidePage) : GuideButton()

constructor(material: Material, page: GuidePage) : this(ItemStack(material), page)

override fun getItemProvider(viewer: Player): ItemProvider = ItemStackBuilder.gui(stack, "${rebarKey("guide_page")}:${page.key}")
override fun getItemProvider(viewer: Player): ItemProvider = ItemStackBuilder.gui(stack.clone(), "${rebarKey("guide_page")}:${page.key}")
.name(Component.translatable("${page.key.namespace}.guide.page.${page.key.key}"))
.clearLore()
.lore(Component.translatable("${page.key.namespace}.guide.button.${page.key.key}.lore", ""))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ abstract class SearchPage(key: NamespacedKey) : SimpleStaticGuidePage(key) {
val upperGui = Gui.builder()
.setStructure("# S #")
.addIngredient('S', searchSpecifiersStack)
.addIngredient('#', GuiItems.background(search))
.addIngredient('#', GuiItems.background())
.build()
loadCurrentPage(player, lowerGui)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.github.pylonmc.rebar.item.base

import io.github.pylonmc.rebar.event.api.MultiListener
import io.github.pylonmc.rebar.event.api.annotation.MultiHandlers
import io.github.pylonmc.rebar.event.api.annotation.UniversalHandler
import io.github.pylonmc.rebar.item.RebarItem
import io.github.pylonmc.rebar.item.RebarItemListener
import org.bukkit.event.EventPriority
import org.bukkit.event.player.PlayerDropItemEvent
import org.jetbrains.annotations.ApiStatus

interface RebarDroppable {
fun onDropped(event: PlayerDropItemEvent, priority: EventPriority)

@ApiStatus.Internal
companion object : MultiListener {
@UniversalHandler
private fun onDrop(event: PlayerDropItemEvent, priority: EventPriority) {
val rebarItem = RebarItem.fromStack(event.itemDrop.itemStack, RebarDroppable::class.java)
val droppable = rebarItem as? RebarItem ?: return

try {
MultiHandlers.handleEvent(droppable, "onDropped", event, priority)
} catch (e: Exception) {
RebarItemListener.logEventHandleErr(event, e, rebarItem)
}
}
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lmao

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.github.pylonmc.rebar.item.base

import io.github.pylonmc.rebar.event.api.MultiListener
import io.github.pylonmc.rebar.event.api.annotation.MultiHandlers
import io.github.pylonmc.rebar.event.api.annotation.UniversalHandler
import io.github.pylonmc.rebar.item.RebarItem
import io.github.pylonmc.rebar.item.RebarItemListener
import org.bukkit.event.EventPriority
import org.bukkit.event.player.PlayerAttemptPickupItemEvent
import org.jetbrains.annotations.ApiStatus

interface RebarPickupable {
fun onPickupAttempt(event: PlayerAttemptPickupItemEvent, priority: EventPriority)

@ApiStatus.Internal
companion object : MultiListener {
@UniversalHandler
private fun onPickupAttempt(event: PlayerAttemptPickupItemEvent, priority: EventPriority) {
val rebarItem = RebarItem.fromStack(event.item.itemStack, RebarPickupable::class.java)
val pickupable = rebarItem as? RebarItem ?: return

try {
MultiHandlers.handleEvent(pickupable, "onPickupAttempt", event, priority)
} catch (e: Exception) {
RebarItemListener.logEventHandleErr(event, e, rebarItem)
}
}
}
}
8 changes: 7 additions & 1 deletion rebar/src/main/kotlin/io/github/pylonmc/rebar/waila/Waila.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import io.github.pylonmc.rebar.util.delayTicks
import io.github.pylonmc.rebar.util.position.BlockPosition
import io.github.pylonmc.rebar.util.position.position
import io.github.pylonmc.rebar.util.rebarKey
import io.github.pylonmc.rebar.util.vanillaDisplayName
import io.github.pylonmc.rebar.waila.Waila.Companion.addWailaOverride
import io.papermc.paper.raytracing.RayTraceTarget
import kotlinx.coroutines.Job
Expand All @@ -23,6 +24,7 @@ import net.kyori.adventure.text.Component
import org.bukkit.attribute.Attribute
import org.bukkit.block.Block
import org.bukkit.entity.Entity
import org.bukkit.entity.Item
import org.bukkit.entity.Player
import org.bukkit.event.EventHandler
import org.bukkit.event.EventPriority
Expand Down Expand Up @@ -135,7 +137,11 @@ class Waila private constructor(private val player: Player, playerConfig: Player
?: entity.let(EntityStorage::get)?.getWaila(player)

if (display == null && player.wailaConfig.vanillaWailaEnabled) {
display = WailaDisplay(Component.translatable(entity.type.translationKey()))
display = if (entity is Item) {
WailaDisplay(entity.itemStack.effectiveName())
} else {
WailaDisplay(Component.translatable(entity.type.translationKey()))
}
}

if (display != null) {
Expand Down
4 changes: 4 additions & 0 deletions rebar/src/main/resources/lang/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ guide:
button:
back:
name: "<white>Back"
hints: |-

<u>Hints</u>
<guidearrow> <guideinsn>Shift left click</guideinsn> to go to the main menu
item-recipes: "<white>Recipe"
machine-recipes: "<white>Recipes made with this machine"
search-specifiers:
Expand Down
Loading