Skip to content

Commit 3d38a7e

Browse files
authored
Merge pull request #153 from pylonmc/allow-disabling-items
Allow disabling items & change research disabling logic
2 parents f500194 + d22843f commit 3d38a7e

13 files changed

Lines changed: 274 additions & 45 deletions

File tree

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import io.github.pylonmc.pylon.core.block.context.BlockBreakContext
77
import io.github.pylonmc.pylon.core.block.context.BlockCreateContext
88
import io.github.pylonmc.pylon.core.event.PylonBlockUnloadEvent
99
import io.github.pylonmc.pylon.core.item.PylonItem
10+
import io.github.pylonmc.pylon.core.item.research.Research.Companion.canUse
1011
import io.github.pylonmc.pylon.core.util.position.position
1112
import io.papermc.paper.event.block.*
1213
import io.papermc.paper.event.entity.EntityCompostItemEvent
@@ -16,6 +17,7 @@ import io.papermc.paper.event.player.PlayerLecternPageChangeEvent
1617
import io.papermc.paper.event.player.PlayerOpenSignEvent
1718
import org.bukkit.GameMode
1819
import org.bukkit.Material
20+
import org.bukkit.block.BlockFace
1921
import org.bukkit.event.EventHandler
2022
import org.bukkit.event.EventPriority
2123
import org.bukkit.event.Listener
@@ -48,10 +50,17 @@ internal object BlockListener : Listener {
4850
val item = event.itemInHand
4951
val player = event.player
5052

51-
val pylonItem = PylonItem.fromStack(item)
52-
val pylonBlock = pylonItem?.place(BlockCreateContext.PlayerPlace(player, item, event))
53+
val pylonItem = PylonItem.fromStack(item) ?: return
54+
if (!event.player.canUse(pylonItem, true)) {
55+
event.isCancelled = true
56+
return
57+
}
58+
val relative = event.blockPlaced.position - event.blockAgainst.position
59+
val blockFace = BlockFace.entries.find { it.modX == relative.x && it.modY == relative.y && it.modZ == relative.z }
60+
?: BlockFace.SELF
61+
val pylonBlock = pylonItem.place(BlockCreateContext.PlayerPlace(player, item, event))
5362

54-
if (pylonItem != null && pylonBlock == null) {
63+
if (pylonBlock == null) {
5564
event.isCancelled = true
5665
}
5766

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import io.github.pylonmc.pylon.core.block.waila.Waila.Companion.wailaEnabled
1010
import io.github.pylonmc.pylon.core.debug.DebugWaxedWeatheredCutCopperStairs
1111
import io.github.pylonmc.pylon.core.guide.PylonGuide
1212
import io.github.pylonmc.pylon.core.i18n.PylonArgument
13+
import io.github.pylonmc.pylon.core.item.PylonItem
1314
import io.github.pylonmc.pylon.core.item.research.Research
1415
import io.github.pylonmc.pylon.core.item.research.Research.Companion.researchPoints
1516
import io.github.pylonmc.pylon.core.item.research.Research.Companion.researches
@@ -28,6 +29,7 @@ import org.bukkit.Material
2829
import org.bukkit.NamespacedKey
2930
import org.bukkit.command.CommandSender
3031
import org.bukkit.entity.Player
32+
import org.bukkit.inventory.EquipmentSlot
3133
import org.bukkit.permissions.Permission
3234
import org.bukkit.permissions.PermissionDefault
3335
import org.jetbrains.annotations.ApiStatus
@@ -83,6 +85,18 @@ internal class PylonCommand : BaseCommand() {
8385
player.give(DebugWaxedWeatheredCutCopperStairs.STACK)
8486
}
8587

88+
@Subcommand("key")
89+
@Description("Shows you the key of the item in your main hand")
90+
@CommandPermission("pylon.command.key")
91+
fun key(player: Player) {
92+
val item = PylonItem.fromStack(player.inventory.getItem(EquipmentSlot.HAND))
93+
if (item == null) {
94+
player.sendRichMessage("<red>You are not holding a Pylon item")
95+
return
96+
}
97+
player.sendRichMessage(item.key.toString())
98+
}
99+
86100
@Subcommand("setblock")
87101
@CommandCompletion("@blocks")
88102
@Description("Set a block to be a pylon block")

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.github.pylonmc.pylon.core.config
22

33
import io.github.pylonmc.pylon.core.PylonCore
4+
import org.bukkit.NamespacedKey
45

56
object PylonConfig {
67

@@ -32,4 +33,16 @@ object PylonConfig {
3233

3334
@JvmStatic
3435
val translationWrapLimit: Int by config
36+
37+
@JvmStatic
38+
val disabledItems: Set<NamespacedKey> =
39+
config.getOrThrow<List<String>>("disabled-items")
40+
.mapNotNull {
41+
val key = NamespacedKey.fromString(it)
42+
if (key == null) {
43+
PylonCore.logger.warning { "Invalid disabled-items key '$it'" }
44+
}
45+
key
46+
}
47+
.toSet()
3548
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package io.github.pylonmc.pylon.core.event
2+
3+
import io.github.pylonmc.pylon.core.block.PylonBlock
4+
import io.github.pylonmc.pylon.core.recipe.PylonRecipe
5+
import io.github.pylonmc.pylon.core.recipe.RecipeType
6+
import org.bukkit.entity.Player
7+
import org.bukkit.event.Cancellable
8+
import org.bukkit.event.Event
9+
import org.bukkit.event.HandlerList
10+
11+
/**
12+
* Called when a crafting recipe is started
13+
*/
14+
class PrePylonCraftEvent<T: PylonRecipe> @JvmOverloads constructor(
15+
val type: RecipeType<T>,
16+
val recipe: T,
17+
val block: PylonBlock? = null,
18+
val player: Player? = null
19+
) : Event(), Cancellable {
20+
21+
private var isCancelled = false
22+
23+
override fun isCancelled(): Boolean = isCancelled
24+
25+
override fun setCancelled(cancel: Boolean) {
26+
isCancelled = cancel
27+
}
28+
29+
override fun getHandlers(): HandlerList
30+
= handlerList
31+
32+
companion object {
33+
@JvmStatic
34+
val handlerList: HandlerList = HandlerList()
35+
}
36+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package io.github.pylonmc.pylon.core.event
2+
3+
import io.github.pylonmc.pylon.core.block.PylonBlock
4+
import io.github.pylonmc.pylon.core.recipe.PylonRecipe
5+
import io.github.pylonmc.pylon.core.recipe.RecipeType
6+
import org.bukkit.event.Event
7+
import org.bukkit.event.HandlerList
8+
9+
/**
10+
* Called when a crafting recipe is started
11+
*/
12+
class PylonCraftEvent<T: PylonRecipe> @JvmOverloads constructor(
13+
val type: RecipeType<T>,
14+
val recipe: T,
15+
val block: PylonBlock? = null,
16+
) : Event() {
17+
18+
override fun getHandlers(): HandlerList
19+
= handlerList
20+
21+
companion object {
22+
@JvmStatic
23+
val handlerList: HandlerList = HandlerList()
24+
}
25+
}

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/guide/button/ItemButton.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@ import io.github.pylonmc.pylon.core.i18n.PylonArgument
88
import io.github.pylonmc.pylon.core.item.PylonItem
99
import io.github.pylonmc.pylon.core.item.builder.ItemStackBuilder
1010
import io.github.pylonmc.pylon.core.item.research.Research.Companion.canUse
11+
import io.github.pylonmc.pylon.core.item.research.Research.Companion.canCraft
1112
import io.github.pylonmc.pylon.core.item.research.Research.Companion.research
1213
import io.github.pylonmc.pylon.core.item.research.Research.Companion.researchPoints
13-
import io.github.pylonmc.pylon.core.item.research.Research.Companion.researches
1414
import io.github.pylonmc.pylon.core.registry.PylonRegistry
1515
import io.papermc.paper.datacomponent.DataComponentTypes
1616
import io.papermc.paper.datacomponent.item.ItemLore
1717
import net.kyori.adventure.text.Component
1818
import net.kyori.adventure.text.TranslatableComponent
19-
import org.bukkit.Bukkit
2019
import org.bukkit.Material
2120
import org.bukkit.NamespacedKey
2221
import org.bukkit.entity.Player
@@ -57,7 +56,11 @@ class ItemButton(val stack: ItemStack) : AbstractItem() {
5756
builder.name(stackName.arguments(placeholders))
5857
}
5958

60-
if (!player.canUse(item)) {
59+
if (item.isDisabled) {
60+
builder.set(DataComponentTypes.ITEM_MODEL, Material.STRUCTURE_VOID.key)
61+
}
62+
63+
if (!player.canCraft(item)) {
6164
builder.set(DataComponentTypes.ITEM_MODEL, Material.BARRIER.key)
6265
.set(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, false)
6366
.lore(Component.translatable("pylon.pyloncore.guide.button.item.not-researched"))

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@ class PlayerTranslationHandler(val player: Player) {
2525
GlobalTranslator.render(attacher.render(it, Unit), player.locale())
2626
}
2727
item.stack.editData(DataComponentTypes.LORE) { lore ->
28-
val newLore: MutableList<Component> = (lore.lines() + item.addon.displayName).flatMapTo(mutableListOf()) { line ->
28+
val toTranslate = (lore.lines() + item.addon.displayName).toMutableList()
29+
if (item.isDisabled) {
30+
toTranslate.add(Component.translatable("pylon.pyloncore.message.disabled.lore"))
31+
}
32+
33+
val newLore: MutableList<Component> = toTranslate.flatMapTo(mutableListOf()) { line ->
2934
val translated = GlobalTranslator.render(attacher.render(line, Unit), player.locale())
3035
val encoded = LineWrapEncoder.encode(translated)
3136
val wrapped = encoded.copy(lines = encoded.lines.flatMap(wrapper::wrap))

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import io.github.pylonmc.pylon.core.PylonCore
44
import io.github.pylonmc.pylon.core.block.PylonBlock
55
import io.github.pylonmc.pylon.core.block.context.BlockCreateContext
66
import io.github.pylonmc.pylon.core.config.Config
7+
import io.github.pylonmc.pylon.core.config.PylonConfig
78
import io.github.pylonmc.pylon.core.config.Settings
89
import io.github.pylonmc.pylon.core.datatypes.PylonSerializers
910
import io.github.pylonmc.pylon.core.i18n.AddonTranslator
@@ -24,6 +25,7 @@ open class PylonItem(val stack: ItemStack) : Keyed {
2425
val researchBypassPermission = schema.researchBypassPermission
2526
val addon = schema.addon
2627
val pylonBlock = schema.pylonBlockKey
28+
val isDisabled: Boolean = PylonConfig.disabledItems.contains(key)
2729

2830
fun getSettings() = Settings.get(key)
2931

0 commit comments

Comments
 (0)