Skip to content

Commit 94005ce

Browse files
authored
Merge pull request #117 from pylonmc/random-stuff
Random stuff
2 parents 20aa329 + 271c5ff commit 94005ce

59 files changed

Lines changed: 731 additions & 312 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/PylonCore.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import co.aikar.commands.PaperCommandManager
44
import io.github.pylonmc.pylon.core.addon.PylonAddon
55
import io.github.pylonmc.pylon.core.addon.PylonAddonListener
66
import io.github.pylonmc.pylon.core.block.*
7+
import io.github.pylonmc.pylon.core.block.base.PylonEntityHolderBlock
8+
import io.github.pylonmc.pylon.core.block.base.PylonGuiBlock
79
import io.github.pylonmc.pylon.core.block.base.PylonSimpleMultiblock
810
import io.github.pylonmc.pylon.core.block.waila.Waila
911
import io.github.pylonmc.pylon.core.command.PylonCommand
@@ -45,6 +47,9 @@ object PylonCore : JavaPlugin(), PylonAddon {
4547
Bukkit.getPluginManager().registerEvents(EntityListener, this)
4648
Bukkit.getPluginManager().registerEvents(Waila, this)
4749
Bukkit.getPluginManager().registerEvents(Research, this)
50+
Bukkit.getPluginManager().registerEvents(PylonGuiBlock, this)
51+
Bukkit.getPluginManager().registerEvents(PylonEntityHolderBlock, this)
52+
Bukkit.getPluginManager().registerEvents(PylonSimpleMultiblock, this)
4853

4954
Bukkit.getScheduler().runTaskTimer(
5055
this,

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/block/BlockListener.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import com.destroystokyo.paper.event.block.BeaconEffectEvent
44
import com.destroystokyo.paper.event.player.PlayerJumpEvent
55
import io.github.pylonmc.pylon.core.block.base.*
66
import io.github.pylonmc.pylon.core.block.context.BlockBreakContext
7-
import io.github.pylonmc.pylon.core.event.PylonBlockUnloadEvent
87
import io.github.pylonmc.pylon.core.block.context.BlockCreateContext
8+
import io.github.pylonmc.pylon.core.event.PylonBlockUnloadEvent
99
import io.github.pylonmc.pylon.core.item.PylonItem
1010
import io.github.pylonmc.pylon.core.util.position.position
1111
import io.papermc.paper.event.block.*
@@ -27,8 +27,8 @@ import org.bukkit.event.entity.EntityExplodeEvent
2727
import org.bukkit.event.inventory.BrewingStandFuelEvent
2828
import org.bukkit.event.inventory.FurnaceBurnEvent
2929
import org.bukkit.event.inventory.FurnaceExtractEvent
30-
import org.bukkit.event.player.PlayerTakeLecternBookEvent
3130
import org.bukkit.event.player.PlayerInteractEvent
31+
import org.bukkit.event.player.PlayerTakeLecternBookEvent
3232
import org.bukkit.event.player.PlayerToggleSneakEvent
3333

3434

@@ -49,12 +49,12 @@ internal object BlockListener : Listener {
4949
val player = event.player
5050

5151
val pylonItem = PylonItem.fromStack(item)
52-
val context = BlockCreateContext.PlayerPlace(player, item)
52+
val pylonBlock = pylonItem?.place(BlockCreateContext.PlayerPlace(player, item, event))
5353

54-
val pylonBlock = pylonItem?.place(context, event.block)
5554
if (pylonItem != null && pylonBlock == null) {
5655
event.isCancelled = true
5756
}
57+
5858
if (pylonBlock != null && player.gameMode != GameMode.CREATIVE) {
5959
player.inventory.getItem(event.hand).subtract()
6060
}

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/block/BlockStorage.kt

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ object BlockStorage : Listener {
176176
fun placeBlock(
177177
blockPosition: BlockPosition,
178178
key: NamespacedKey,
179-
context: BlockCreateContext = BlockCreateContext.Default
179+
context: BlockCreateContext = BlockCreateContext.Default(blockPosition.block)
180180
): PylonBlock? {
181181
require(blockPosition.chunk.isLoaded) { "You can only place Pylon blocks in loaded chunks" }
182182
require(!isPylonBlock(blockPosition)) { "You cannot place a new Pylon block in place of an existing Pylon blocks" }
@@ -218,7 +218,7 @@ object BlockStorage : Listener {
218218
fun placeBlock(
219219
block: Block,
220220
key: NamespacedKey,
221-
context: BlockCreateContext = BlockCreateContext.Default
221+
context: BlockCreateContext = BlockCreateContext.Default(block)
222222
) = placeBlock(block.position, key, context)
223223

224224
/**
@@ -233,7 +233,7 @@ object BlockStorage : Listener {
233233
fun placeBlock(
234234
location: Location,
235235
key: NamespacedKey,
236-
context: BlockCreateContext = BlockCreateContext.Default
236+
context: BlockCreateContext = BlockCreateContext.Default(location.block)
237237
) = placeBlock(BlockPosition(location), key, context)
238238

239239
/**
@@ -276,11 +276,11 @@ object BlockStorage : Listener {
276276
block.postBreak()
277277
}
278278

279+
PylonBlockBreakEvent(blockPosition.block, block, context, drops).callEvent()
280+
279281
for (drop in drops) {
280282
block.block.world.dropItemNaturally(block.block.location.add(0.5, 0.1, 0.5), drop)
281283
}
282-
283-
PylonBlockBreakEvent(blockPosition.block, block, context).callEvent()
284284
}
285285

286286
/**
@@ -377,13 +377,11 @@ object BlockStorage : Listener {
377377

378378
save(event.chunk, chunkBlocks)
379379

380-
Bukkit.getScheduler().runTask(PylonCore, Runnable {
381-
for (block in chunkBlocks) {
382-
PylonBlockUnloadEvent(block.block, block).callEvent()
383-
}
380+
for (block in chunkBlocks) {
381+
PylonBlockUnloadEvent(block.block, block).callEvent()
382+
}
384383

385-
PylonChunkBlocksUnloadEvent(event.chunk, chunkBlocks.toList()).callEvent()
386-
})
384+
PylonChunkBlocksUnloadEvent(event.chunk, chunkBlocks.toList()).callEvent()
387385
}
388386

389387
/**

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/block/PhantomBlock.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ import io.github.pylonmc.pylon.core.block.context.BlockItemContext
55
import io.github.pylonmc.pylon.core.block.waila.WailaConfig
66
import io.github.pylonmc.pylon.core.datatypes.PylonSerializers
77
import io.github.pylonmc.pylon.core.item.PylonItem
8-
import io.github.pylonmc.pylon.core.item.PylonItemSchema
98
import io.github.pylonmc.pylon.core.item.builder.ItemStackBuilder
10-
import io.github.pylonmc.pylon.core.util.editData
119
import io.github.pylonmc.pylon.core.util.pylonKey
1210
import net.kyori.adventure.bossbar.BossBar
1311
import net.kyori.adventure.text.Component

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/block/PylonBlock.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ import io.github.pylonmc.pylon.core.block.waila.WailaConfig
77
import io.github.pylonmc.pylon.core.config.Config
88
import io.github.pylonmc.pylon.core.config.Settings
99
import io.github.pylonmc.pylon.core.datatypes.PylonSerializers
10+
import io.github.pylonmc.pylon.core.event.PylonBlockDeserializeEvent
11+
import io.github.pylonmc.pylon.core.event.PylonBlockSerializeEvent
1012
import io.github.pylonmc.pylon.core.i18n.AddonTranslator
11-
import io.github.pylonmc.pylon.core.item.PylonItemSchema
1213
import io.github.pylonmc.pylon.core.registry.PylonRegistry
1314
import io.github.pylonmc.pylon.core.util.position.BlockPosition
1415
import io.github.pylonmc.pylon.core.util.position.position
@@ -37,6 +38,8 @@ open class PylonBlock protected constructor(val block: Block) {
3738
constructor(block: Block, context: BlockCreateContext) : this(block)
3839
constructor(block: Block, pdc: PersistentDataContainer) : this(block)
3940

41+
protected open fun postLoad() {}
42+
4043
open fun getWaila(player: Player): WailaConfig {
4144
return WailaConfig(name)
4245
}
@@ -110,6 +113,8 @@ open class PylonBlock protected constructor(val block: Block) {
110113
}
111114

112115
block.write(pdc)
116+
PylonBlockSerializeEvent(block.block, block, pdc).callEvent()
117+
113118
return pdc
114119
}
115120

@@ -146,6 +151,8 @@ open class PylonBlock protected constructor(val block: Block) {
146151
block.errorBlock = pdc.get(pylonBlockErrorKey, PylonSerializers.UUID)
147152
?.let { world.getEntity(it) as? BlockDisplay }
148153

154+
PylonBlockDeserializeEvent(block.block, block, pdc).callEvent()
155+
block.postLoad()
149156
return block
150157
} catch (t: Throwable) {
151158
PylonCore.logger.severe("Error while loading block $key at $position")

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/block/TickManager.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import kotlinx.coroutines.Job
1616
import kotlinx.coroutines.cancel
1717
import kotlinx.coroutines.delay
1818
import kotlinx.coroutines.withContext
19-
import org.bukkit.Bukkit
2019
import org.bukkit.Color.RED
2120
import org.bukkit.entity.BlockDisplay
2221
import org.bukkit.event.EventHandler
Lines changed: 65 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
package io.github.pylonmc.pylon.core.block.base
22

3+
import io.github.pylonmc.pylon.core.block.context.BlockCreateContext
4+
import io.github.pylonmc.pylon.core.datatypes.PylonSerializers
35
import io.github.pylonmc.pylon.core.entity.EntityStorage
46
import io.github.pylonmc.pylon.core.entity.PylonEntity
5-
import io.github.pylonmc.pylon.core.datatypes.PylonSerializers
7+
import io.github.pylonmc.pylon.core.event.PylonBlockDeserializeEvent
8+
import io.github.pylonmc.pylon.core.event.PylonBlockPlaceEvent
9+
import io.github.pylonmc.pylon.core.event.PylonBlockSerializeEvent
10+
import io.github.pylonmc.pylon.core.event.PylonBlockUnloadEvent
611
import io.github.pylonmc.pylon.core.util.pylonKey
7-
import org.bukkit.persistence.PersistentDataContainer
12+
import org.bukkit.event.EventHandler
13+
import org.bukkit.event.Listener
14+
import org.jetbrains.annotations.ApiStatus
15+
import org.jetbrains.annotations.MustBeInvokedByOverriders
16+
import java.util.IdentityHashMap
817
import java.util.UUID
9-
import javax.annotation.CheckReturnValue
10-
import javax.annotation.OverridingMethodsMustInvokeSuper
1118

1219
/**
1320
* A block that has one or more associated Pylon entities. For example, a pedestal that
@@ -18,17 +25,20 @@ import javax.annotation.OverridingMethodsMustInvokeSuper
1825
*/
1926
interface PylonEntityHolderBlock : PylonBreakHandler {
2027

21-
/**
22-
* Must be set in your create constructor when you spawn in the entity.
23-
*/
28+
fun createEntities(context: BlockCreateContext): Map<String, PylonEntity<*>> = emptyMap()
29+
30+
@get:ApiStatus.NonExtendable
2431
val heldEntities: MutableMap<String, UUID>
32+
get() = holders[this] ?: error("You cannot access held entities before the block is placed")
2533

26-
fun getHeldEntityUuid(name: String)
27-
= heldEntities[name] ?: throw IllegalArgumentException("Entity $name not found")
34+
@ApiStatus.NonExtendable
35+
fun getHeldEntityUuid(name: String) = heldEntities[name] ?: throw IllegalArgumentException("Entity $name not found")
2836

37+
@ApiStatus.NonExtendable
2938
fun getHeldEntity(name: String): PylonEntity<*>?
3039
= EntityStorage.get(getHeldEntityUuid(name))
3140

41+
@ApiStatus.NonExtendable
3242
fun <T: PylonEntity<*>> getHeldEntity(clazz: Class<T>, name: String): T?
3343
= EntityStorage.getAs(clazz, getHeldEntityUuid(name))
3444

@@ -37,40 +47,63 @@ interface PylonEntityHolderBlock : PylonBreakHandler {
3747
*
3848
* Will error if there is no entity with the provided name.
3949
*/
40-
fun isHeldEntityPresent(name: String)
41-
= EntityStorage.isPylonEntity(getHeldEntityUuid(name))
50+
@ApiStatus.NonExtendable
51+
fun isHeldEntityPresent(name: String) = EntityStorage.isPylonEntity(getHeldEntityUuid(name))
4252

4353
/**
4454
* Returns false if any entity is unloaded or does not exist.
4555
*/
46-
fun areAllHeldEntitiesLoaded()
47-
= heldEntities.keys.all { isHeldEntityPresent(it) }
48-
49-
/**
50-
* Must be called in your load constructor.
51-
*/
52-
@CheckReturnValue
53-
fun loadHeldEntities(pdc: PersistentDataContainer): Map<String, UUID> {
54-
return pdc.get(entityKey, PylonSerializers.MAP.mapTypeFrom(PylonSerializers.STRING, PylonSerializers.UUID))
55-
?: throw IllegalStateException("Failed to load entity holder; did you forget to call saveHeldEntities() in your write() method?")
56-
}
57-
58-
/**
59-
* Must be called in your write() method.
60-
*/
61-
fun saveHeldEntities(pdc: PersistentDataContainer) {
62-
pdc.set(entityKey, PylonSerializers.MAP.mapTypeFrom(PylonSerializers.STRING, PylonSerializers.UUID), heldEntities)
63-
}
56+
@ApiStatus.NonExtendable
57+
fun areAllHeldEntitiesLoaded() = heldEntities.keys.all { isHeldEntityPresent(it) }
6458

65-
@OverridingMethodsMustInvokeSuper
59+
@MustBeInvokedByOverriders
6660
override fun postBreak() {
6761
// Best-effort removal; unlikely to cause issues
6862
for (name in heldEntities.keys) {
6963
getHeldEntity(name)?.entity?.remove()
7064
}
7165
}
7266

73-
companion object {
74-
val entityKey = pylonKey("entity_holder_entity_uuids")
67+
companion object : Listener {
68+
private val entityKey = pylonKey("entity_holder_entity_uuids")
69+
private val entityType = PylonSerializers.MAP.mapTypeFrom(PylonSerializers.STRING, PylonSerializers.UUID)
70+
71+
private val holders = IdentityHashMap<PylonEntityHolderBlock, MutableMap<String, UUID>>()
72+
73+
@EventHandler
74+
private fun onPlace(event: PylonBlockPlaceEvent) {
75+
val block = event.pylonBlock
76+
if (block !is PylonEntityHolderBlock) return
77+
val entities = mutableMapOf<String, UUID>()
78+
for ((name, entity) in block.createEntities(event.context)) {
79+
val uuid = entity.uuid
80+
if (!EntityStorage.isPylonEntity(uuid)) {
81+
EntityStorage.add(entity)
82+
}
83+
entities[name] = uuid
84+
}
85+
holders[block] = entities
86+
}
87+
88+
@EventHandler
89+
private fun onDeserialize(event: PylonBlockDeserializeEvent) {
90+
val block = event.pylonBlock
91+
if (block !is PylonEntityHolderBlock) return
92+
holders[block] = event.pdc.get(entityKey, entityType)?.toMutableMap() ?: error("Held entities not found for ${block.key}")
93+
}
94+
95+
@EventHandler
96+
private fun onSerialize(event: PylonBlockSerializeEvent) {
97+
val block = event.pylonBlock
98+
if (block !is PylonEntityHolderBlock) return
99+
event.pdc.set(entityKey, entityType, holders[block]!!)
100+
}
101+
102+
@EventHandler
103+
private fun onUnload(event: PylonBlockUnloadEvent) {
104+
val block = event.pylonBlock
105+
if (block !is PylonEntityHolderBlock) return
106+
holders.remove(block)
107+
}
75108
}
76109
}

0 commit comments

Comments
 (0)