Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
871fe861f1 | ||
|
|
9e328231e1 | ||
|
|
baa051f67d | ||
|
|
bf1d3b9ae0 | ||
|
|
20d927cc2c | ||
|
|
49f2e27ef2 | ||
|
|
f44ffca6cc | ||
|
|
8c6e22e93d | ||
|
|
505e6f35ac | ||
|
|
b969c3e054 | ||
|
|
140eab592e | ||
|
|
0c24d6be21 | ||
|
|
281e605ce1 | ||
|
|
95438d151f | ||
|
|
d2a00f3c2d | ||
|
|
18c7635232 | ||
|
|
a17c412a5c | ||
|
|
5c62b3b467 | ||
|
|
bef67355a6 | ||
|
|
8f8036a518 | ||
|
|
3fe0a8071d | ||
|
|
de7339ac84 | ||
|
|
e902c65dd0 | ||
|
|
9207babde5 | ||
|
|
8919ab0d2a | ||
|
|
776abef5e2 |
@@ -39,7 +39,7 @@ allprojects {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation("com.willfp:ecomponent:1.4.1")
|
implementation("com.willfp:ecomponent:1.4.1")
|
||||||
|
|
||||||
compileOnly("com.willfp:eco:6.71.0")
|
compileOnly("com.willfp:eco:6.73.0")
|
||||||
compileOnly("org.jetbrains:annotations:23.0.0")
|
compileOnly("org.jetbrains:annotations:23.0.0")
|
||||||
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:1.9.20")
|
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:1.9.20")
|
||||||
compileOnly("com.github.ben-manes.caffeine:caffeine:3.1.5")
|
compileOnly("com.github.ben-manes.caffeine:caffeine:3.1.5")
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.willfp.ecoscrolls
|
|||||||
import com.willfp.eco.core.command.impl.PluginCommand
|
import com.willfp.eco.core.command.impl.PluginCommand
|
||||||
import com.willfp.eco.core.display.DisplayModule
|
import com.willfp.eco.core.display.DisplayModule
|
||||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
|
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
|
||||||
|
import com.willfp.eco.core.items.Items
|
||||||
import com.willfp.eco.core.placeholder.context.PlaceholderContext
|
import com.willfp.eco.core.placeholder.context.PlaceholderContext
|
||||||
import com.willfp.eco.core.placeholder.templates.DynamicPlaceholder
|
import com.willfp.eco.core.placeholder.templates.DynamicPlaceholder
|
||||||
import com.willfp.ecoscrolls.commands.CommandEcoScrolls
|
import com.willfp.ecoscrolls.commands.CommandEcoScrolls
|
||||||
@@ -17,6 +18,7 @@ import com.willfp.ecoscrolls.libreforge.TriggerInscribe
|
|||||||
import com.willfp.ecoscrolls.libreforge.TriggerTryInscribe
|
import com.willfp.ecoscrolls.libreforge.TriggerTryInscribe
|
||||||
import com.willfp.ecoscrolls.scrolls.InscriptionHandler
|
import com.willfp.ecoscrolls.scrolls.InscriptionHandler
|
||||||
import com.willfp.ecoscrolls.scrolls.ScrollLevel
|
import com.willfp.ecoscrolls.scrolls.ScrollLevel
|
||||||
|
import com.willfp.ecoscrolls.scrolls.ScrollTag
|
||||||
import com.willfp.ecoscrolls.scrolls.Scrolls
|
import com.willfp.ecoscrolls.scrolls.Scrolls
|
||||||
import com.willfp.ecoscrolls.target.ScrollFinder
|
import com.willfp.ecoscrolls.target.ScrollFinder
|
||||||
import com.willfp.ecoscrolls.target.Targets
|
import com.willfp.ecoscrolls.target.Targets
|
||||||
@@ -54,6 +56,8 @@ class EcoScrollsPlugin : LibreforgePlugin() {
|
|||||||
Triggers.register(TriggerInscribe)
|
Triggers.register(TriggerInscribe)
|
||||||
Triggers.register(TriggerTryInscribe)
|
Triggers.register(TriggerTryInscribe)
|
||||||
|
|
||||||
|
Items.registerTag(ScrollTag(this))
|
||||||
|
|
||||||
registerHolderProvider(ScrollFinder.toHolderProvider())
|
registerHolderProvider(ScrollFinder.toHolderProvider())
|
||||||
|
|
||||||
registerHolderPlaceholderProvider<ScrollLevel> { it, _ ->
|
registerHolderPlaceholderProvider<ScrollLevel> { it, _ ->
|
||||||
@@ -63,7 +67,7 @@ class EcoScrollsPlugin : LibreforgePlugin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PlaceholderManager.registerPlaceholder(
|
PlaceholderManager.registerPlaceholder(
|
||||||
object : DynamicPlaceholder(plugin, Pattern.compile("scroll_([a-z]+)_([a-zA-Z0-9_]+)")) {
|
object : DynamicPlaceholder(plugin, Pattern.compile("scroll_([a-z0-9_]+):([a-zA-Z0-9_]+)")) {
|
||||||
override fun getValue(args: String, context: PlaceholderContext): String? {
|
override fun getValue(args: String, context: PlaceholderContext): String? {
|
||||||
val matcher = pattern.matcher(args)
|
val matcher = pattern.matcher(args)
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class CommandEcoScrolls(plugin: EcoPlugin) : PluginCommand(
|
|||||||
init {
|
init {
|
||||||
this.addSubcommand(CommandReload(plugin))
|
this.addSubcommand(CommandReload(plugin))
|
||||||
.addSubcommand(CommandGive(plugin))
|
.addSubcommand(CommandGive(plugin))
|
||||||
|
.addSubcommand(CommandInscribeDirect(plugin))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onExecute(sender: CommandSender, args: List<String>) {
|
override fun onExecute(sender: CommandSender, args: List<String>) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.willfp.eco.core.command.impl.Subcommand
|
|||||||
import com.willfp.eco.core.drops.DropQueue
|
import com.willfp.eco.core.drops.DropQueue
|
||||||
import com.willfp.eco.core.items.Items.toSNBT
|
import com.willfp.eco.core.items.Items.toSNBT
|
||||||
import com.willfp.eco.core.items.toSNBT
|
import com.willfp.eco.core.items.toSNBT
|
||||||
|
import com.willfp.eco.util.StringUtils
|
||||||
import com.willfp.ecoscrolls.scrolls.Scrolls
|
import com.willfp.ecoscrolls.scrolls.Scrolls
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
import org.bukkit.command.CommandSender
|
import org.bukkit.command.CommandSender
|
||||||
@@ -65,9 +66,9 @@ class CommandGive(
|
|||||||
.forceTelekinesis()
|
.forceTelekinesis()
|
||||||
.push()
|
.push()
|
||||||
|
|
||||||
val message = plugin.langYml.getMessage("give-success")
|
val message = plugin.langYml.getMessage("give-success", StringUtils.FormatOption.WITHOUT_PLACEHOLDERS)
|
||||||
.replace("%scroll%", scroll.name)
|
.replace("%scroll%", scroll.name)
|
||||||
.replace("%recipient%", reciever.name)
|
.replace("%player%", reciever.name)
|
||||||
|
|
||||||
sender.sendMessage(message)
|
sender.sendMessage(message)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
package com.willfp.ecoscrolls.commands
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.command.impl.Subcommand
|
||||||
|
import com.willfp.eco.util.StringUtils
|
||||||
|
import com.willfp.eco.util.savedDisplayName
|
||||||
|
import com.willfp.ecoscrolls.scrolls.Scrolls
|
||||||
|
import com.willfp.ecoscrolls.scrolls.getScrollLevel
|
||||||
|
import org.bukkit.command.CommandSender
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.util.StringUtil
|
||||||
|
|
||||||
|
class CommandInscribeDirect(
|
||||||
|
plugin: EcoPlugin
|
||||||
|
) : Subcommand(
|
||||||
|
plugin,
|
||||||
|
"inscribe",
|
||||||
|
"ecoscrolls.command.incscribedirect",
|
||||||
|
false
|
||||||
|
) {
|
||||||
|
override fun onExecute(sender: CommandSender, rawArgs: List<String>) {
|
||||||
|
var args = rawArgs
|
||||||
|
var player = sender as? Player
|
||||||
|
|
||||||
|
if (sender !is Player) {
|
||||||
|
player = notifyPlayerRequired(args.getOrNull(0), "invalid-player")
|
||||||
|
args = rawArgs.subList(1, rawArgs.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val scroll = notifyNull(
|
||||||
|
args.getOrNull(0)?.lowercase()?.let { Scrolls[it] },
|
||||||
|
"invalid-scroll"
|
||||||
|
)
|
||||||
|
|
||||||
|
val item = player.inventory.itemInMainHand
|
||||||
|
|
||||||
|
val level = args.getOrNull(1)?.toIntOrNull() ?: 1
|
||||||
|
val currentLevel = item.getScrollLevel(scroll)?.level ?: 0
|
||||||
|
val levelsToAdd = level - currentLevel
|
||||||
|
|
||||||
|
repeat(levelsToAdd) {
|
||||||
|
scroll.inscribe(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.sendMessage(
|
||||||
|
plugin.langYml.getMessage("inscribed-item", StringUtils.FormatOption.WITHOUT_PLACEHOLDERS)
|
||||||
|
.replace("%scroll%", scroll.name)
|
||||||
|
.replace("%player%", player.savedDisplayName)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun tabComplete(sender: CommandSender, rawArgs: List<String>): List<String> {
|
||||||
|
val completions = mutableListOf<String>()
|
||||||
|
|
||||||
|
var args = rawArgs
|
||||||
|
|
||||||
|
if (sender !is Player) {
|
||||||
|
args = rawArgs.subList(1, rawArgs.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.size == 1) {
|
||||||
|
StringUtil.copyPartialMatches(
|
||||||
|
args[0],
|
||||||
|
Scrolls.values().map { it.id },
|
||||||
|
completions
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.size == 2) {
|
||||||
|
val scroll = Scrolls[args[0].lowercase()]
|
||||||
|
|
||||||
|
val levels = if (scroll != null) {
|
||||||
|
val maxLevel = scroll.maxLevel
|
||||||
|
(0..maxLevel).toList()
|
||||||
|
} else {
|
||||||
|
(0..5).toList()
|
||||||
|
}
|
||||||
|
|
||||||
|
StringUtil.copyPartialMatches(
|
||||||
|
args[1],
|
||||||
|
levels.map { it.toString() },
|
||||||
|
completions
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return completions
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -58,12 +58,12 @@ internal fun updateInscribeMenu(plugin: EcoScrollsPlugin) {
|
|||||||
|
|
||||||
val violationContext = ViolationContext(plugin, "Inscription Table")
|
val violationContext = ViolationContext(plugin, "Inscription Table")
|
||||||
|
|
||||||
val openEffects = Effects.compile(
|
val openEffects = Effects.compileChain(
|
||||||
plugin.configYml.getSubsections("gui.open-effects"),
|
plugin.configYml.getSubsections("gui.open-effects"),
|
||||||
violationContext.with("Open Effects")
|
violationContext.with("Open Effects")
|
||||||
)
|
)
|
||||||
|
|
||||||
val closeEffects = Effects.compile(
|
val closeEffects = Effects.compileChain(
|
||||||
plugin.configYml.getSubsections("gui.close-effects"),
|
plugin.configYml.getSubsections("gui.close-effects"),
|
||||||
violationContext.with("Close Effects")
|
violationContext.with("Close Effects")
|
||||||
)
|
)
|
||||||
@@ -139,13 +139,13 @@ internal fun updateInscribeMenu(plugin: EcoScrollsPlugin) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onOpen { player, _ ->
|
onOpen { player, _ ->
|
||||||
openEffects.trigger(TriggerData(player = player).dispatch(player.toDispatcher()))
|
openEffects?.trigger(player.toDispatcher(), TriggerData(player = player))
|
||||||
}
|
}
|
||||||
|
|
||||||
onClose { event, menu ->
|
onClose { event, menu ->
|
||||||
val player = event.player as Player
|
val player = event.player as Player
|
||||||
|
|
||||||
closeEffects.trigger(TriggerData(player = player).dispatch(player.toDispatcher()))
|
closeEffects?.trigger(player.toDispatcher(), TriggerData(player = player))
|
||||||
|
|
||||||
DropQueue(player)
|
DropQueue(player)
|
||||||
.addItems(menu.getCaptiveItems(player))
|
.addItems(menu.getCaptiveItems(player))
|
||||||
@@ -299,10 +299,5 @@ private class AllowSlot(plugin: EcoScrollsPlugin) : MenuSlot(plugin, Inscription
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DenySlot(plugin: EcoScrollsPlugin) : MenuSlot(plugin, InscriptionStatus.DENY) {
|
private class DenySlot(plugin: EcoScrollsPlugin) : MenuSlot(plugin, InscriptionStatus.DENY)
|
||||||
|
private class EmptySlot(plugin: EcoScrollsPlugin) : MenuSlot(plugin, InscriptionStatus.EMPTY)
|
||||||
}
|
|
||||||
|
|
||||||
private class EmptySlot(plugin: EcoScrollsPlugin) : MenuSlot(plugin, InscriptionStatus.EMPTY) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -15,16 +15,14 @@ import com.willfp.libreforge.triggers.TriggerData
|
|||||||
import com.willfp.libreforge.triggers.TriggerParameter
|
import com.willfp.libreforge.triggers.TriggerParameter
|
||||||
|
|
||||||
object EffectInscribeItem : Effect<NoCompileData>("inscribe_item") {
|
object EffectInscribeItem : Effect<NoCompileData>("inscribe_item") {
|
||||||
override val parameters = setOf(
|
override val isPermanent = false
|
||||||
TriggerParameter.ITEM
|
|
||||||
)
|
|
||||||
|
|
||||||
override val arguments = arguments {
|
override val arguments = arguments {
|
||||||
require("scroll", "You must specify the scroll!")
|
require("scroll", "You must specify the scroll!")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTrigger(config: Config, data: TriggerData, compileData: NoCompileData): Boolean {
|
override fun onTrigger(config: Config, data: TriggerData, compileData: NoCompileData): Boolean {
|
||||||
val item = data.item ?: return false
|
val item = data.foundItem ?: return false
|
||||||
|
|
||||||
val scroll = Scrolls[config.getString("scroll")] ?: return false
|
val scroll = Scrolls[config.getString("scroll")] ?: return false
|
||||||
|
|
||||||
|
|||||||
@@ -3,34 +3,37 @@ package com.willfp.ecoscrolls.scrolls
|
|||||||
import com.willfp.ecoscrolls.EcoScrollsPlugin
|
import com.willfp.ecoscrolls.EcoScrollsPlugin
|
||||||
import com.willfp.ecoscrolls.scrolls.event.ScrollInscribeEvent
|
import com.willfp.ecoscrolls.scrolls.event.ScrollInscribeEvent
|
||||||
import com.willfp.ecoscrolls.scrolls.event.ScrollTryInscribeEvent
|
import com.willfp.ecoscrolls.scrolls.event.ScrollTryInscribeEvent
|
||||||
|
import com.willfp.ecoscrolls.target.Targets.targets
|
||||||
import com.willfp.libreforge.NamedValue
|
import com.willfp.libreforge.NamedValue
|
||||||
import com.willfp.libreforge.ViolationContext
|
import com.willfp.libreforge.ViolationContext
|
||||||
import com.willfp.libreforge.effects.EffectList
|
import com.willfp.libreforge.effects.Chain
|
||||||
import com.willfp.libreforge.effects.Effects
|
import com.willfp.libreforge.effects.Effects
|
||||||
import com.willfp.libreforge.toDispatcher
|
import com.willfp.libreforge.toDispatcher
|
||||||
import com.willfp.libreforge.triggers.TriggerData
|
import com.willfp.libreforge.triggers.TriggerData
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import java.util.Optional
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
class InscriptionHandler(private val plugin: EcoScrollsPlugin) {
|
class InscriptionHandler(private val plugin: EcoScrollsPlugin) {
|
||||||
private lateinit var applyEffects: EffectList
|
private lateinit var applyEffects: Optional<Chain>
|
||||||
private lateinit var denyEffects: EffectList
|
private lateinit var denyEffects: Optional<Chain>
|
||||||
|
|
||||||
val scrollLimit = plugin.configYml.getInt("inscription.scroll-limit")
|
private val globalScrollLimit = plugin.configYml.getInt("inscription.scroll-limit")
|
||||||
.let { if (it <= 0) Int.MAX_VALUE else it }
|
.let { if (it <= 0) Int.MAX_VALUE else it }
|
||||||
|
|
||||||
internal fun reload() {
|
internal fun reload() {
|
||||||
val context = ViolationContext(plugin, "Inscriptions")
|
val context = ViolationContext(plugin, "Inscriptions")
|
||||||
|
|
||||||
applyEffects = Effects.compile(
|
applyEffects = Optional.ofNullable(Effects.compileChain(
|
||||||
plugin.configYml.getSubsections("inscription.apply-effects"),
|
plugin.configYml.getSubsections("inscription.apply-effects"),
|
||||||
context.with("Apply Effects")
|
context.with("Apply Effects")
|
||||||
)
|
))
|
||||||
|
|
||||||
denyEffects = Effects.compile(
|
denyEffects = Optional.ofNullable(Effects.compileChain(
|
||||||
plugin.configYml.getSubsections("inscription.deny-effects"),
|
plugin.configYml.getSubsections("inscription.deny-effects"),
|
||||||
context.with("Deny Effects")
|
context.with("Deny Effects")
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inscriptionTrigger(item: ItemStack, scroll: Scroll, player: Player) =
|
private fun inscriptionTrigger(item: ItemStack, scroll: Scroll, player: Player) =
|
||||||
@@ -72,14 +75,33 @@ class InscriptionHandler(private val plugin: EcoScrollsPlugin) {
|
|||||||
val didInscribe = scroll.inscribe(item, player)
|
val didInscribe = scroll.inscribe(item, player)
|
||||||
|
|
||||||
if (didInscribe) {
|
if (didInscribe) {
|
||||||
applyEffects.trigger(inscriptionTrigger(item, scroll, player))
|
applyEffects.ifPresent {
|
||||||
|
it.trigger(inscriptionTrigger(item, scroll, player))
|
||||||
|
}
|
||||||
|
|
||||||
val event = ScrollInscribeEvent(player, scroll, item)
|
val event = ScrollInscribeEvent(player, scroll, item)
|
||||||
plugin.server.pluginManager.callEvent(event)
|
plugin.server.pluginManager.callEvent(event)
|
||||||
} else {
|
} else {
|
||||||
denyEffects.trigger(inscriptionTrigger(item, scroll, player))
|
denyEffects.ifPresent {
|
||||||
|
it.trigger(inscriptionTrigger(item, scroll, player))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return didInscribe
|
return didInscribe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getScrollLimit(item: ItemStack): Int {
|
||||||
|
val targets = item.targets
|
||||||
|
|
||||||
|
var highest = Int.MAX_VALUE
|
||||||
|
|
||||||
|
for (target in targets) {
|
||||||
|
val limit = target.scrollLimit ?: continue
|
||||||
|
if (limit < highest) {
|
||||||
|
highest = limit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return min(highest, globalScrollLimit)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import org.bukkit.persistence.PersistentDataContainer
|
|||||||
import org.bukkit.persistence.PersistentDataType
|
import org.bukkit.persistence.PersistentDataType
|
||||||
|
|
||||||
private val SCROLL_KEY = plugin.createNamespacedKey("scroll")
|
private val SCROLL_KEY = plugin.createNamespacedKey("scroll")
|
||||||
private val SCROLL_USES_KEY = plugin.createNamespacedKey("scroll_uses")
|
private val SCROLL_USES_LEFT_KEY = plugin.createNamespacedKey("scroll_uses_left")
|
||||||
private val SCROLLS_KEY = plugin.createNamespacedKey("scrolls")
|
private val SCROLLS_KEY = plugin.createNamespacedKey("scrolls")
|
||||||
private val SCROLL_ID_KEY = plugin.createNamespacedKey("scroll")
|
private val SCROLL_ID_KEY = plugin.createNamespacedKey("scroll")
|
||||||
private val SCROLL_LEVEL_KEY = plugin.createNamespacedKey("level")
|
private val SCROLL_LEVEL_KEY = plugin.createNamespacedKey("level")
|
||||||
@@ -40,37 +40,39 @@ var PersistentDataContainer.scroll: Scroll?
|
|||||||
this.set(SCROLL_KEY, PersistentDataType.STRING, value.id)
|
this.set(SCROLL_KEY, PersistentDataType.STRING, value.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
var ItemStack.scrollUses: Int
|
var ItemStack.scrollUsesLeft: Int
|
||||||
get() = this.fast().scrollUses
|
get() = this.fast().scrollUsesLeft
|
||||||
set(value) {
|
set(value) {
|
||||||
this.fast().scrollUses = value
|
this.fast().scrollUsesLeft = value
|
||||||
}
|
}
|
||||||
|
|
||||||
var FastItemStack.scrollUses: Int
|
var FastItemStack.scrollUsesLeft: Int
|
||||||
get() = this.persistentDataContainer.scrollUses
|
get() = this.persistentDataContainer.scrollUsesLeft
|
||||||
set(value) {
|
set(value) {
|
||||||
this.persistentDataContainer.scrollUses = value
|
this.persistentDataContainer.scrollUsesLeft = value
|
||||||
}
|
}
|
||||||
|
|
||||||
var PersistentDataContainer.scrollUses: Int
|
var PersistentDataContainer.scrollUsesLeft: Int
|
||||||
get() {
|
get() {
|
||||||
return this.get(SCROLL_USES_KEY, PersistentDataType.INTEGER) ?: 0
|
return this.get(SCROLL_USES_LEFT_KEY, PersistentDataType.INTEGER) ?: 0
|
||||||
}
|
}
|
||||||
set(value) {
|
set(value) {
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
this.remove(SCROLL_USES_KEY)
|
this.remove(SCROLL_USES_LEFT_KEY)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set(SCROLL_USES_KEY, PersistentDataType.INTEGER, value)
|
this.set(SCROLL_USES_LEFT_KEY, PersistentDataType.INTEGER, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ItemStack.useScroll() {
|
fun ItemStack.useScroll() {
|
||||||
val scroll = this.scroll ?: return
|
if (this.scroll == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
this.scrollUses++
|
this.scrollUsesLeft--
|
||||||
|
|
||||||
if (this.scrollUses >= scroll.maxUses) {
|
if (this.scrollUsesLeft <= 0) {
|
||||||
this.amount--
|
this.amount--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.willfp.eco.core.config.interfaces.Config
|
|||||||
import com.willfp.eco.core.display.Display
|
import com.willfp.eco.core.display.Display
|
||||||
import com.willfp.eco.core.fast.FastItemStack
|
import com.willfp.eco.core.fast.FastItemStack
|
||||||
import com.willfp.eco.core.fast.fast
|
import com.willfp.eco.core.fast.fast
|
||||||
|
import com.willfp.eco.core.items.CustomItem
|
||||||
import com.willfp.eco.core.items.Items
|
import com.willfp.eco.core.items.Items
|
||||||
import com.willfp.eco.core.placeholder.InjectablePlaceholder
|
import com.willfp.eco.core.placeholder.InjectablePlaceholder
|
||||||
import com.willfp.eco.core.placeholder.PlaceholderInjectable
|
import com.willfp.eco.core.placeholder.PlaceholderInjectable
|
||||||
@@ -13,7 +14,6 @@ import com.willfp.eco.core.placeholder.templates.DynamicInjectablePlaceholder
|
|||||||
import com.willfp.eco.core.price.ConfiguredPrice
|
import com.willfp.eco.core.price.ConfiguredPrice
|
||||||
import com.willfp.eco.core.recipe.Recipes
|
import com.willfp.eco.core.recipe.Recipes
|
||||||
import com.willfp.eco.core.registry.KRegistrable
|
import com.willfp.eco.core.registry.KRegistrable
|
||||||
import com.willfp.eco.util.evaluateExpression
|
|
||||||
import com.willfp.eco.util.evaluateExpressionOrNull
|
import com.willfp.eco.util.evaluateExpressionOrNull
|
||||||
import com.willfp.eco.util.formatEco
|
import com.willfp.eco.util.formatEco
|
||||||
import com.willfp.eco.util.toNumeral
|
import com.willfp.eco.util.toNumeral
|
||||||
@@ -29,7 +29,6 @@ import org.bukkit.entity.Player
|
|||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
import java.util.Objects
|
import java.util.Objects
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
import kotlin.math.max
|
|
||||||
|
|
||||||
class Scroll(
|
class Scroll(
|
||||||
plugin: EcoScrollsPlugin,
|
plugin: EcoScrollsPlugin,
|
||||||
@@ -65,12 +64,19 @@ class Scroll(
|
|||||||
fis.scroll = this
|
fis.scroll = this
|
||||||
fis.displayName = itemName.formatEco()
|
fis.displayName = itemName.formatEco()
|
||||||
fis.lore = itemLore.formatEco().map { Display.PREFIX + it } + fis.lore
|
fis.lore = itemLore.formatEco().map { Display.PREFIX + it } + fis.lore
|
||||||
|
fis.scrollUsesLeft = maxUses
|
||||||
fis.unwrap()
|
fis.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
val item: ItemStack
|
val item: ItemStack
|
||||||
get() = _item.clone()
|
get() = _item.clone()
|
||||||
|
|
||||||
|
val customItem = CustomItem(
|
||||||
|
plugin.createNamespacedKey("scroll_$id"),
|
||||||
|
{ it.scroll == this },
|
||||||
|
_item
|
||||||
|
).apply { register() }
|
||||||
|
|
||||||
val recipe = if (config.getBool("item.craftable")) Recipes.createAndRegisterRecipe(
|
val recipe = if (config.getBool("item.craftable")) Recipes.createAndRegisterRecipe(
|
||||||
plugin,
|
plugin,
|
||||||
id,
|
id,
|
||||||
@@ -98,7 +104,7 @@ class Scroll(
|
|||||||
context.with("inscription conditions")
|
context.with("inscription conditions")
|
||||||
)
|
)
|
||||||
|
|
||||||
private val inscriptionEffects = Effects.compile(
|
private val inscriptionEffects = Effects.compileChain(
|
||||||
config.getSubsections("inscription.effects"),
|
config.getSubsections("inscription.effects"),
|
||||||
context.with("inscription effects")
|
context.with("inscription effects")
|
||||||
)
|
)
|
||||||
@@ -131,15 +137,15 @@ class Scroll(
|
|||||||
private val usesLeftPlaceholder = object : DynamicInjectablePlaceholder(Pattern.compile("uses_left")) {
|
private val usesLeftPlaceholder = object : DynamicInjectablePlaceholder(Pattern.compile("uses_left")) {
|
||||||
override fun getValue(p0: String, p1: PlaceholderContext): String? {
|
override fun getValue(p0: String, p1: PlaceholderContext): String? {
|
||||||
val item = p1.itemStack ?: return null
|
val item = p1.itemStack ?: return null
|
||||||
val scroll = item.scroll ?: return null
|
return item.scrollUsesLeft.toString()
|
||||||
return (scroll.maxUses - item.scrollUses).toString()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val usesPlaceholder = object : DynamicInjectablePlaceholder(Pattern.compile("uses")) {
|
private val usesPlaceholder = object : DynamicInjectablePlaceholder(Pattern.compile("uses")) {
|
||||||
override fun getValue(p0: String, p1: PlaceholderContext): String? {
|
override fun getValue(p0: String, p1: PlaceholderContext): String? {
|
||||||
val item = p1.itemStack ?: return null
|
val item = p1.itemStack ?: return null
|
||||||
return item.scrollUses.toString()
|
val scroll = item.scroll ?: return null
|
||||||
|
return (scroll.maxUses - item.scrollUsesLeft).toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +193,7 @@ class Scroll(
|
|||||||
|
|
||||||
val currentScrolls = itemStack.scrolls
|
val currentScrolls = itemStack.scrolls
|
||||||
|
|
||||||
if (currentScrolls.size >= plugin.inscriptionHandler.scrollLimit) {
|
if (currentScrolls.size >= plugin.inscriptionHandler.getScrollLimit(itemStack)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,12 +237,13 @@ class Scroll(
|
|||||||
|
|
||||||
inscribe(itemStack)
|
inscribe(itemStack)
|
||||||
|
|
||||||
inscriptionEffects.trigger(
|
inscriptionEffects?.trigger(
|
||||||
|
player.toDispatcher(),
|
||||||
TriggerData(
|
TriggerData(
|
||||||
player = player,
|
player = player,
|
||||||
item = itemStack,
|
item = itemStack,
|
||||||
value = itemStack.getScrollLevel(this)?.level?.toDouble() ?: 1.0
|
value = itemStack.getScrollLevel(this)?.level?.toDouble() ?: 1.0
|
||||||
).dispatch(player.toDispatcher())
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.willfp.ecoscrolls.scrolls
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.items.tag.CustomItemTag
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
|
||||||
|
class ScrollTag(plugin: EcoPlugin) : CustomItemTag(plugin.createNamespacedKey("scroll")) {
|
||||||
|
override fun matches(p0: ItemStack): Boolean {
|
||||||
|
return p0.scroll != null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getExampleItem(): ItemStack? {
|
||||||
|
return Scrolls.values().randomOrNull()?.item
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ interface Target : Registrable {
|
|||||||
val displayName: String
|
val displayName: String
|
||||||
val slot: SlotType
|
val slot: SlotType
|
||||||
val items: List<TestableItem>
|
val items: List<TestableItem>
|
||||||
|
val scrollLimit: Int?
|
||||||
|
|
||||||
fun matches(itemStack: ItemStack): Boolean {
|
fun matches(itemStack: ItemStack): Boolean {
|
||||||
for (item in items) {
|
for (item in items) {
|
||||||
@@ -45,6 +46,8 @@ class ConfiguredTarget(
|
|||||||
.map { Items.lookup(it) }
|
.map { Items.lookup(it) }
|
||||||
.filterNot { it is EmptyTestableItem }
|
.filterNot { it is EmptyTestableItem }
|
||||||
|
|
||||||
|
override val scrollLimit = config.getIntOrNull("scroll-limit")
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is Target) {
|
if (other !is Target) {
|
||||||
return false
|
return false
|
||||||
@@ -64,6 +67,7 @@ internal object AllTarget : Target {
|
|||||||
override val slot = SlotTypeAny
|
override val slot = SlotTypeAny
|
||||||
override var items = emptyList<TestableItem>()
|
override var items = emptyList<TestableItem>()
|
||||||
private set
|
private set
|
||||||
|
override val scrollLimit = null
|
||||||
|
|
||||||
fun updateItems() {
|
fun updateItems() {
|
||||||
items = Targets.values()
|
items = Targets.values()
|
||||||
|
|||||||
@@ -5,9 +5,6 @@ import com.willfp.eco.core.items.HashedItem
|
|||||||
import com.willfp.eco.core.registry.Registry
|
import com.willfp.eco.core.registry.Registry
|
||||||
import com.willfp.ecoscrolls.EcoScrollsPlugin
|
import com.willfp.ecoscrolls.EcoScrollsPlugin
|
||||||
import com.willfp.ecoscrolls.plugin
|
import com.willfp.ecoscrolls.plugin
|
||||||
import com.willfp.ecoscrolls.scrolls.Scroll
|
|
||||||
import com.willfp.ecoscrolls.scrolls.Scrolls
|
|
||||||
import org.bukkit.Material
|
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
@@ -23,14 +20,9 @@ object Targets : Registry<Target>() {
|
|||||||
.filter { it.matches(item) }
|
.filter { it.matches(item) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val ItemStack.isModifiable: Boolean
|
val ItemStack.targets: List<Target>
|
||||||
get() = modifiableCache.get(HashedItem.of(this)) {
|
get() = targetsCache.get(HashedItem.of(this)) {
|
||||||
getForItem(this).isNotEmpty() || this.type == Material.BOOK || this.type == Material.ENCHANTED_BOOK
|
getForItem(this)
|
||||||
}
|
|
||||||
|
|
||||||
val ItemStack.applicableScrolls: List<Scroll>
|
|
||||||
get() = canModifyCache.get(HashedItem.of(this)) {
|
|
||||||
Scrolls.values().filter { it.canInscribe(this) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun update(plugin: EcoScrollsPlugin) {
|
internal fun update(plugin: EcoScrollsPlugin) {
|
||||||
@@ -49,10 +41,6 @@ object Targets : Registry<Target>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val modifiableCache = Caffeine.newBuilder()
|
private val targetsCache = Caffeine.newBuilder()
|
||||||
.expireAfterAccess(5, TimeUnit.SECONDS)
|
.expireAfterAccess(5, TimeUnit.SECONDS)
|
||||||
.build<HashedItem, Boolean>()
|
.build<HashedItem, List<Target>>()
|
||||||
|
|
||||||
private val canModifyCache = Caffeine.newBuilder()
|
|
||||||
.expireAfterAccess(5, TimeUnit.SECONDS)
|
|
||||||
.build<HashedItem, List<Scroll>>()
|
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ environment:
|
|||||||
value: ${libreforgeVersion}
|
value: ${libreforgeVersion}
|
||||||
|
|
||||||
options:
|
options:
|
||||||
resource-id: 0
|
resource-id: 6131
|
||||||
bstats-id: 22538
|
bstats-id: 22538
|
||||||
color: "e3c72"
|
color: "e3c72"
|
||||||
|
|||||||
@@ -10,4 +10,4 @@ messages:
|
|||||||
needs-scroll: "&cYou must specify a scroll!"
|
needs-scroll: "&cYou must specify a scroll!"
|
||||||
invalid-player: "&cYou must specify a player!"
|
invalid-player: "&cYou must specify a player!"
|
||||||
invalid-scroll: "&cYou must specify a scroll!"
|
invalid-scroll: "&cYou must specify a scroll!"
|
||||||
give-success: "Gave %scroll%&r to %recipient%&r!"
|
give-success: "Gave %scroll%&r to %player%&r!"
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ permissions:
|
|||||||
ecoscrolls.command.reload: true
|
ecoscrolls.command.reload: true
|
||||||
ecoscrolls.command.inscribe: true
|
ecoscrolls.command.inscribe: true
|
||||||
ecoscrolls.command.give: true
|
ecoscrolls.command.give: true
|
||||||
|
ecoscrolls.command.inscribedirect: true
|
||||||
|
|
||||||
ecoscrolls.command.reload:
|
ecoscrolls.command.reload:
|
||||||
description: Allows reloading the config
|
description: Allows reloading the config
|
||||||
@@ -44,3 +45,7 @@ permissions:
|
|||||||
ecoscrolls.command.inscribe:
|
ecoscrolls.command.inscribe:
|
||||||
description: Allows opening the inscription table with /inscribe
|
description: Allows opening the inscription table with /inscribe
|
||||||
default: true
|
default: true
|
||||||
|
|
||||||
|
ecoscrolls.command.inscribedirect:
|
||||||
|
description: Allows directly inscribing an item with /ecoscrolls inscribe
|
||||||
|
default: op
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ item:
|
|||||||
lore:
|
lore:
|
||||||
- "&7This is an example scroll."
|
- "&7This is an example scroll."
|
||||||
- "&7It does nothing."
|
- "&7It does nothing."
|
||||||
|
|
||||||
|
# Options for crafting, read here: https://plugins.auxilor.io/all-plugins/the-item-lookup-system#crafting-recipes
|
||||||
craftable: false
|
craftable: false
|
||||||
recipe: [ ]
|
recipe: [ ]
|
||||||
|
|
||||||
@@ -32,6 +34,8 @@ inscription:
|
|||||||
conditions: [ ]
|
conditions: [ ]
|
||||||
|
|
||||||
# The effects that will be run when the item is inscribed
|
# The effects that will be run when the item is inscribed
|
||||||
|
# If your scroll works by modifying the item (e.g. adding enchantments, changing durability),
|
||||||
|
# then put those effects here.
|
||||||
effects: [ ]
|
effects: [ ]
|
||||||
|
|
||||||
# Read https://plugins.auxilor.io/all-plugins/prices
|
# Read https://plugins.auxilor.io/all-plugins/prices
|
||||||
@@ -73,7 +77,8 @@ lore:
|
|||||||
- "&6Example Scroll"
|
- "&6Example Scroll"
|
||||||
|
|
||||||
# Item placeholders for dynamic lore in plugins like EcoItems
|
# Item placeholders for dynamic lore in plugins like EcoItems
|
||||||
# The placeholder is %ecoscrolls_scroll_<scroll>_<placeholder>%
|
# The placeholder is %ecoscrolls_scroll_<scroll>:<placeholder>%, e.g.
|
||||||
|
# %ecoscrolls_scroll_example:bonus%
|
||||||
placeholders:
|
placeholders:
|
||||||
bonus: "%level% * 2"
|
bonus: "%level% * 2"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
# The ID of the scroll is the name of the .yml file,
|
||||||
|
# for example coins_on_kill.yml has the ID of coins_on_kill
|
||||||
|
# You can place scrolls anywhere in this folder,
|
||||||
|
# including in subfolders if you want to organize your scroll configs
|
||||||
|
# _example.yml is not loaded.
|
||||||
|
|
||||||
|
# The name of the scroll
|
||||||
|
name: "&cHot Potato Book"
|
||||||
|
|
||||||
|
max-level: 10
|
||||||
|
max-uses: 1
|
||||||
|
|
||||||
|
item:
|
||||||
|
item: book unbreaking:1 hide_enchants
|
||||||
|
name: "&cHot Potato Book"
|
||||||
|
lore:
|
||||||
|
- "&7When inscribed on armor, grants"
|
||||||
|
- "&f+2 %ecoskills_defense_name% &7and &f+1 %ecoskills_health_name%&7."
|
||||||
|
- ""
|
||||||
|
- "&7When inscribed to weapons, grants"
|
||||||
|
- "&f+2 %ecoskills_strength_name% &7and &f+4 %ecoskills_crit_damage_name%&7."
|
||||||
|
- ""
|
||||||
|
- "&7This can be inscribed up to &a10 &7times"
|
||||||
|
- "&7on an item!"
|
||||||
|
|
||||||
|
craftable: false
|
||||||
|
recipe: [ ]
|
||||||
|
|
||||||
|
inscription:
|
||||||
|
conditions: [ ]
|
||||||
|
|
||||||
|
effects: [ ]
|
||||||
|
|
||||||
|
price:
|
||||||
|
value: 100
|
||||||
|
type: coins
|
||||||
|
display: "&e%value% coins"
|
||||||
|
|
||||||
|
price-level-multiplier: "1 + %level% * 0.5"
|
||||||
|
|
||||||
|
drag-and-drop: false
|
||||||
|
inscription-table: true
|
||||||
|
|
||||||
|
targets:
|
||||||
|
- sword
|
||||||
|
- axe
|
||||||
|
- armor
|
||||||
|
|
||||||
|
placeholders:
|
||||||
|
# For EcoItems items, use %ecoscrolls_scroll_hot_potato_book:defense% in lore
|
||||||
|
defense: "&8(&e+{^{%level% * 2}}&8)"
|
||||||
|
# Same as above, but for health / strength / crit_damage
|
||||||
|
health: "&8(&e+{^{%level%}}&8)"
|
||||||
|
strength: "&8(&e+{^{%level% * 2}}&8)"
|
||||||
|
crit_damage: "&8(&e+{^{%level% * 4}}&8)"
|
||||||
|
|
||||||
|
effects:
|
||||||
|
# Armor effects
|
||||||
|
- id: add_stat
|
||||||
|
args:
|
||||||
|
stat: defense
|
||||||
|
amount: "%level% * 2"
|
||||||
|
conditions:
|
||||||
|
- id: in_slot
|
||||||
|
args:
|
||||||
|
slot: armor
|
||||||
|
- id: add_stat
|
||||||
|
args:
|
||||||
|
stat: health
|
||||||
|
amount: "%level%"
|
||||||
|
conditions:
|
||||||
|
- id: in_slot
|
||||||
|
args:
|
||||||
|
slot: armor
|
||||||
|
|
||||||
|
# Weapon effects
|
||||||
|
- id: add_stat
|
||||||
|
args:
|
||||||
|
stat: strength
|
||||||
|
amount: "%level% * 2"
|
||||||
|
conditions:
|
||||||
|
- id: in_slot
|
||||||
|
args:
|
||||||
|
slot: mainhand
|
||||||
|
- id: add_stat
|
||||||
|
args:
|
||||||
|
stat: crit_damage
|
||||||
|
amount: "%level% * 4"
|
||||||
|
conditions:
|
||||||
|
- id: in_slot
|
||||||
|
args:
|
||||||
|
slot: mainhand
|
||||||
|
|
||||||
|
conditions: [ ]
|
||||||
@@ -8,10 +8,15 @@
|
|||||||
# a target with slot "mainhand", the scroll will activate whenever the item is
|
# a target with slot "mainhand", the scroll will activate whenever the item is
|
||||||
# in your mainhand.
|
# in your mainhand.
|
||||||
|
|
||||||
|
# You can also specify a scroll limit for a target, for example you can limit
|
||||||
|
# pickaxes to only have 3 scrolls inscribed on them.
|
||||||
|
# If an item has multiple targets, the lowest limit will be used.
|
||||||
|
|
||||||
targets:
|
targets:
|
||||||
- id: pickaxe
|
- id: pickaxe
|
||||||
display-name: "Pickaxes"
|
display-name: "Pickaxes"
|
||||||
slot: mainhand
|
slot: mainhand
|
||||||
|
# scroll-limit: 10 # Example of a scroll limit
|
||||||
items:
|
items:
|
||||||
- "*wooden_pickaxe"
|
- "*wooden_pickaxe"
|
||||||
- "*stone_pickaxe"
|
- "*stone_pickaxe"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#libreforge-updater
|
#libreforge-updater
|
||||||
#Mon Jul 08 15:58:38 BST 2024
|
#Sun Sep 22 16:59:53 BST 2024
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
libreforge-version=4.65.0
|
libreforge-version=4.72.0
|
||||||
version=1.1.0
|
version=1.6.0
|
||||||
|
|||||||
Reference in New Issue
Block a user