mirror of
https://github.com/Auxilor/EcoEnchants.git
synced 2024-11-25 15:35:11 +01:00
Enchantments will now work when used by entities
This commit is contained in:
parent
fd064e31c8
commit
9a41250b35
@ -32,15 +32,15 @@ import com.willfp.ecoenchants.mechanics.ExtraItemSupport
|
|||||||
import com.willfp.ecoenchants.mechanics.GrindstoneSupport
|
import com.willfp.ecoenchants.mechanics.GrindstoneSupport
|
||||||
import com.willfp.ecoenchants.mechanics.LootSupport
|
import com.willfp.ecoenchants.mechanics.LootSupport
|
||||||
import com.willfp.ecoenchants.mechanics.VillagerSupport
|
import com.willfp.ecoenchants.mechanics.VillagerSupport
|
||||||
import com.willfp.ecoenchants.target.EnchantLookup.clearEnchantCache
|
import com.willfp.ecoenchants.target.EnchantFinder
|
||||||
import com.willfp.ecoenchants.target.EnchantLookup.heldEnchantLevels
|
import com.willfp.ecoenchants.target.EnchantFinder.clearEnchantmentCache
|
||||||
import com.willfp.libreforge.NamedValue
|
import com.willfp.libreforge.NamedValue
|
||||||
import com.willfp.libreforge.loader.LibreforgePlugin
|
import com.willfp.libreforge.loader.LibreforgePlugin
|
||||||
import com.willfp.libreforge.loader.configs.ConfigCategory
|
import com.willfp.libreforge.loader.configs.ConfigCategory
|
||||||
import com.willfp.libreforge.registerHolderPlaceholderProvider
|
import com.willfp.libreforge.registerHolderPlaceholderProvider
|
||||||
import com.willfp.libreforge.registerSpecificHolderProvider
|
import com.willfp.libreforge.registerHolderProvider
|
||||||
import com.willfp.libreforge.registerSpecificRefreshFunction
|
import com.willfp.libreforge.registerSpecificRefreshFunction
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.LivingEntity
|
||||||
import org.bukkit.event.Listener
|
import org.bukkit.event.Listener
|
||||||
|
|
||||||
internal lateinit var plugin: EcoEnchantsPlugin
|
internal lateinit var plugin: EcoEnchantsPlugin
|
||||||
@ -75,12 +75,10 @@ class EcoEnchantsPlugin : LibreforgePlugin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun handleEnable() {
|
override fun handleEnable() {
|
||||||
registerSpecificHolderProvider<Player> {
|
registerHolderProvider(EnchantFinder.toHolderProvider())
|
||||||
it.heldEnchantLevels
|
|
||||||
}
|
|
||||||
|
|
||||||
registerSpecificRefreshFunction<Player> {
|
registerSpecificRefreshFunction<LivingEntity> {
|
||||||
it.clearEnchantCache()
|
it.clearEnchantmentCache()
|
||||||
}
|
}
|
||||||
|
|
||||||
registerHolderPlaceholderProvider<FoundEcoEnchantLevel> { it, _ ->
|
registerHolderPlaceholderProvider<FoundEcoEnchantLevel> { it, _ ->
|
||||||
|
@ -3,8 +3,8 @@ package com.willfp.ecoenchants.enchant.impl.hardcoded
|
|||||||
import com.willfp.eco.util.DurabilityUtils
|
import com.willfp.eco.util.DurabilityUtils
|
||||||
import com.willfp.ecoenchants.EcoEnchantsPlugin
|
import com.willfp.ecoenchants.EcoEnchantsPlugin
|
||||||
import com.willfp.ecoenchants.enchant.impl.HardcodedEcoEnchant
|
import com.willfp.ecoenchants.enchant.impl.HardcodedEcoEnchant
|
||||||
import com.willfp.ecoenchants.target.EnchantLookup.getActiveEnchantLevelInSlot
|
import com.willfp.ecoenchants.target.EnchantFinder.getItemsWithEnchantActive
|
||||||
import com.willfp.ecoenchants.target.EnchantLookup.hasEnchantActive
|
import com.willfp.ecoenchants.target.EnchantFinder.hasEnchantActive
|
||||||
import com.willfp.libreforge.slot.impl.SlotTypeHands
|
import com.willfp.libreforge.slot.impl.SlotTypeHands
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
|
|
||||||
@ -29,18 +29,10 @@ class EnchantmentRepairing(
|
|||||||
if (player.hasEnchantActive(this)) {
|
if (player.hasEnchantActive(this)) {
|
||||||
val repairPerLevel = config.getIntFromExpression("repair-per-level", player)
|
val repairPerLevel = config.getIntFromExpression("repair-per-level", player)
|
||||||
|
|
||||||
for ((slot, item) in player.inventory.withIndex()) {
|
for ((item, level) in player.getItemsWithEnchantActive(this)) {
|
||||||
if (item == null) {
|
val isHolding = item in SlotTypeHands.getItems(player)
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notWhileHolding && slot in SlotTypeHands.getItemSlots(player)) {
|
if (notWhileHolding && isHolding) {
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
val level = player.getActiveEnchantLevelInSlot(this, slot)
|
|
||||||
|
|
||||||
if (level == 0) {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import com.willfp.eco.core.EcoPlugin
|
|||||||
import com.willfp.ecoenchants.EcoEnchantsPlugin
|
import com.willfp.ecoenchants.EcoEnchantsPlugin
|
||||||
import com.willfp.ecoenchants.enchant.EcoEnchant
|
import com.willfp.ecoenchants.enchant.EcoEnchant
|
||||||
import com.willfp.ecoenchants.enchant.impl.HardcodedEcoEnchant
|
import com.willfp.ecoenchants.enchant.impl.HardcodedEcoEnchant
|
||||||
import com.willfp.ecoenchants.target.EnchantLookup.hasEnchantActive
|
import com.willfp.ecoenchants.target.EnchantFinder.hasEnchantActive
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
import org.bukkit.Material
|
import org.bukkit.Material
|
||||||
import org.bukkit.block.BlockFace
|
import org.bukkit.block.BlockFace
|
||||||
|
@ -11,8 +11,7 @@ import com.willfp.eco.core.items.Items
|
|||||||
import com.willfp.ecoenchants.EcoEnchantsPlugin
|
import com.willfp.ecoenchants.EcoEnchantsPlugin
|
||||||
import com.willfp.ecoenchants.enchant.EcoEnchant
|
import com.willfp.ecoenchants.enchant.EcoEnchant
|
||||||
import com.willfp.ecoenchants.enchant.impl.HardcodedEcoEnchant
|
import com.willfp.ecoenchants.enchant.impl.HardcodedEcoEnchant
|
||||||
import com.willfp.ecoenchants.target.EnchantLookup.getActiveEnchantLevelInSlot
|
import com.willfp.ecoenchants.target.EnchantFinder.getItemsWithEnchantActive
|
||||||
import com.willfp.ecoenchants.target.EnchantLookup.hasEnchantActive
|
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.event.EventHandler
|
import org.bukkit.event.EventHandler
|
||||||
import org.bukkit.event.EventPriority
|
import org.bukkit.event.EventPriority
|
||||||
@ -20,7 +19,6 @@ import org.bukkit.event.Listener
|
|||||||
import org.bukkit.event.entity.PlayerDeathEvent
|
import org.bukkit.event.entity.PlayerDeathEvent
|
||||||
import org.bukkit.event.player.PlayerJoinEvent
|
import org.bukkit.event.player.PlayerJoinEvent
|
||||||
import org.bukkit.event.player.PlayerRespawnEvent
|
import org.bukkit.event.player.PlayerRespawnEvent
|
||||||
import org.bukkit.inventory.ItemStack
|
|
||||||
import org.bukkit.persistence.PersistentDataType
|
import org.bukkit.persistence.PersistentDataType
|
||||||
|
|
||||||
class EnchantmentSoulbound(
|
class EnchantmentSoulbound(
|
||||||
@ -61,25 +59,7 @@ class EnchantmentSoulbound(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val player = event.entity
|
val player = event.entity
|
||||||
val items = mutableListOf<ItemStack>()
|
val items = player.getItemsWithEnchantActive(enchant).keys
|
||||||
|
|
||||||
if (!player.hasEnchantActive(enchant)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for ((slot, item) in player.inventory.withIndex()) {
|
|
||||||
if (item == null) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
val level = player.getActiveEnchantLevelInSlot(enchant, slot)
|
|
||||||
|
|
||||||
if (level == 0) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
items.add(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (items.isEmpty()) {
|
if (items.isEmpty()) {
|
||||||
return
|
return
|
||||||
|
@ -0,0 +1,72 @@
|
|||||||
|
package com.willfp.ecoenchants.target
|
||||||
|
|
||||||
|
import com.github.benmanes.caffeine.cache.Caffeine
|
||||||
|
import com.willfp.eco.core.fast.fast
|
||||||
|
import com.willfp.ecoenchants.enchant.EcoEnchant
|
||||||
|
import com.willfp.ecoenchants.enchant.EcoEnchantLevel
|
||||||
|
import com.willfp.libreforge.ProvidedHolder
|
||||||
|
import com.willfp.libreforge.slot.ItemHolderFinder
|
||||||
|
import com.willfp.libreforge.slot.SlotType
|
||||||
|
import com.willfp.libreforge.toDispatcher
|
||||||
|
import org.bukkit.entity.LivingEntity
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import java.util.UUID
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
object EnchantFinder : ItemHolderFinder<EcoEnchantLevel>() {
|
||||||
|
private val provider = this.toHolderProvider()
|
||||||
|
private val levelCache = Caffeine.newBuilder()
|
||||||
|
.expireAfterWrite(1, TimeUnit.SECONDS)
|
||||||
|
.build<UUID, List<ProvidedLevel>>()
|
||||||
|
|
||||||
|
override fun find(item: ItemStack): List<EcoEnchantLevel> {
|
||||||
|
val enchantMap = item.fast().enchants
|
||||||
|
val enchants = mutableListOf<EcoEnchantLevel>()
|
||||||
|
|
||||||
|
for ((enchant, level) in enchantMap) {
|
||||||
|
if (enchant !is EcoEnchant) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
enchants += enchant.getLevel(level)
|
||||||
|
}
|
||||||
|
|
||||||
|
return enchants
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isValidInSlot(holder: EcoEnchantLevel, slot: SlotType): Boolean {
|
||||||
|
return slot in holder.enchant.targets.map { it.slot }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun LivingEntity.clearEnchantmentCache() = levelCache.invalidate(this.uniqueId)
|
||||||
|
|
||||||
|
private val LivingEntity.cachedLevels: List<ProvidedLevel>
|
||||||
|
get() = levelCache.get(this.uniqueId) {
|
||||||
|
provider.provide(this.toDispatcher())
|
||||||
|
.mapNotNull {
|
||||||
|
val level = it.holder as? EcoEnchantLevel ?: return@mapNotNull null
|
||||||
|
val item = it.provider as? ItemStack ?: return@mapNotNull null
|
||||||
|
|
||||||
|
ProvidedLevel(level, item, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun LivingEntity.hasEnchantActive(enchant: EcoEnchant): Boolean {
|
||||||
|
return this.cachedLevels
|
||||||
|
.filter { it.level.enchant == enchant }
|
||||||
|
.any { it.level.conditions.areMet(this.toDispatcher(), it.holder) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun LivingEntity.getItemsWithEnchantActive(enchant: EcoEnchant): Map<ItemStack, Int> {
|
||||||
|
return this.cachedLevels
|
||||||
|
.filter { it.level.enchant == enchant }
|
||||||
|
.filter { it.level.conditions.areMet(this.toDispatcher(), it.holder) }
|
||||||
|
.associate { it.item to it.level.level }
|
||||||
|
}
|
||||||
|
|
||||||
|
private data class ProvidedLevel(
|
||||||
|
val level: EcoEnchantLevel,
|
||||||
|
val item: ItemStack,
|
||||||
|
val holder: ProvidedHolder
|
||||||
|
)
|
||||||
|
}
|
@ -1,345 +0,0 @@
|
|||||||
package com.willfp.ecoenchants.target
|
|
||||||
|
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine
|
|
||||||
import com.willfp.eco.core.fast.fast
|
|
||||||
import com.willfp.eco.core.items.HashedItem
|
|
||||||
import com.willfp.ecoenchants.enchant.EcoEnchant
|
|
||||||
import com.willfp.ecoenchants.enchant.EcoEnchantLevel
|
|
||||||
import com.willfp.ecoenchants.enchant.FoundEcoEnchantLevel
|
|
||||||
import com.willfp.ecoenchants.plugin
|
|
||||||
import com.willfp.libreforge.ItemProvidedHolder
|
|
||||||
import com.willfp.libreforge.slot.SlotType
|
|
||||||
import com.willfp.libreforge.slot.SlotTypes
|
|
||||||
import com.willfp.libreforge.toDispatcher
|
|
||||||
import org.bukkit.entity.Player
|
|
||||||
import org.bukkit.inventory.ItemStack
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
// The Int is the inventory slot ID
|
|
||||||
typealias SlotProvider = (Player) -> Map<ItemInNumericSlot, ItemInSlot>
|
|
||||||
|
|
||||||
data class ItemInSlot internal constructor(
|
|
||||||
val item: ItemStack, val slot: Collection<SlotType>
|
|
||||||
) {
|
|
||||||
constructor(
|
|
||||||
item: ItemStack, slot: SlotType
|
|
||||||
) : this(item, listOf(slot))
|
|
||||||
}
|
|
||||||
|
|
||||||
data class ItemInNumericSlot internal constructor(
|
|
||||||
val item: ItemStack, val slot: Int
|
|
||||||
) {
|
|
||||||
override fun hashCode(): Int {
|
|
||||||
return HashedItem.of(item).hash * (slot + 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private data class HeldEnchant(
|
|
||||||
val enchant: EcoEnchant, val level: Int
|
|
||||||
)
|
|
||||||
|
|
||||||
object EnchantLookup {
|
|
||||||
private val slotProviders = mutableSetOf<SlotProvider>()
|
|
||||||
|
|
||||||
private val itemCache =
|
|
||||||
Caffeine.newBuilder().expireAfterWrite(2, TimeUnit.SECONDS).build<Player, Map<ItemInNumericSlot, ItemInSlot>>()
|
|
||||||
|
|
||||||
private val enchantCache = Caffeine.newBuilder().expireAfterWrite(2, TimeUnit.SECONDS)
|
|
||||||
.build<Player, Map<ItemInNumericSlot, Collection<HeldEnchant>>>()
|
|
||||||
|
|
||||||
// Higher frequency cache as less intensive
|
|
||||||
private val enchantLevelCache = Caffeine.newBuilder().expireAfterWrite(200, TimeUnit.MILLISECONDS)
|
|
||||||
.build<Player, Map<ItemInNumericSlot, Map<EcoEnchant, Int>>>()
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun registerProvider(provider: SlotProvider) {
|
|
||||||
slotProviders.add {
|
|
||||||
val found = mutableMapOf<ItemInNumericSlot, ItemInSlot>()
|
|
||||||
for ((slot, inSlot) in provider(it)) {
|
|
||||||
found[slot] = inSlot
|
|
||||||
}
|
|
||||||
found
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun provide(player: Player): Map<ItemInNumericSlot, ItemInSlot> {
|
|
||||||
return itemCache.get(player) {
|
|
||||||
val found = mutableMapOf<ItemInNumericSlot, ItemInSlot>()
|
|
||||||
|
|
||||||
for (provider in slotProviders) {
|
|
||||||
val fromProvider = provider(player)
|
|
||||||
for ((slot, item) in fromProvider) {
|
|
||||||
// Basically a multimap
|
|
||||||
val current = found[slot]
|
|
||||||
|
|
||||||
if (current == null) {
|
|
||||||
found[slot] = item
|
|
||||||
} else {
|
|
||||||
found[slot] = ItemInSlot(item.item, listOf(current.slot, item.slot).flatten())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
found
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The inventory slot IDs mapped to HeldEnchants found in that slot.
|
|
||||||
*/
|
|
||||||
private val Player.slotHeldEnchants: Map<ItemInNumericSlot, Collection<HeldEnchant>>
|
|
||||||
get() {
|
|
||||||
return enchantCache.get(this) {
|
|
||||||
val found = mutableMapOf<ItemInNumericSlot, MutableCollection<HeldEnchant>>()
|
|
||||||
|
|
||||||
for ((slotID, inSlot) in provide(this)) {
|
|
||||||
val (item, slot) = inSlot
|
|
||||||
|
|
||||||
val enchants = item.fast().enchants
|
|
||||||
|
|
||||||
for ((enchant, level) in enchants) {
|
|
||||||
if (enchant !is EcoEnchant) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slot.none { it in enchant.slots }) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
val held = HeldEnchant(enchant, level)
|
|
||||||
|
|
||||||
// Prevent repeating slot IDs found in multiple TargetSlots (e.g. HANDS and ANY)
|
|
||||||
if (held in found.getOrDefault(slotID, mutableListOf())) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Basically a multimap
|
|
||||||
found[slotID] =
|
|
||||||
(found.getOrDefault(slotID, mutableListOf()) + HeldEnchant(enchant, level)).toMutableList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
found
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Slot IDs mapped to HeldEnchants found in that slot.
|
|
||||||
*/
|
|
||||||
private val Player.slotIDHeldEnchants: Map<Int, Collection<HeldEnchant>>
|
|
||||||
get() {
|
|
||||||
return this.slotHeldEnchants.mapKeys { it.key.slot }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All slots holding EcoEnchants mapped to their IDs, regardless of conditions.
|
|
||||||
*/
|
|
||||||
val Player.heldEnchantsInSlots: Map<ItemInNumericSlot, Map<EcoEnchant, Int>>
|
|
||||||
get() {
|
|
||||||
return enchantLevelCache.get(this) {
|
|
||||||
val found = mutableMapOf<ItemInNumericSlot, MutableMap<EcoEnchant, Int>>()
|
|
||||||
|
|
||||||
for ((inSlot, enchants) in this.slotHeldEnchants) {
|
|
||||||
val map = mutableMapOf<EcoEnchant, Int>()
|
|
||||||
for ((enchant, level) in enchants) {
|
|
||||||
map[enchant] = level
|
|
||||||
}
|
|
||||||
found[inSlot] = map
|
|
||||||
}
|
|
||||||
|
|
||||||
found
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All EcoEnchants mapped to their IDs, regardless of conditions.
|
|
||||||
*/
|
|
||||||
val Player.heldEnchants: Map<EcoEnchant, Int>
|
|
||||||
get() {
|
|
||||||
val found = mutableMapOf<EcoEnchant, Int>()
|
|
||||||
for ((_, enchants) in this.heldEnchantsInSlots) {
|
|
||||||
for ((enchant, level) in enchants) {
|
|
||||||
found[enchant] = level
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return found
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All slots mapped to EcoEnchants mapped to their IDs, respecting conditions.
|
|
||||||
*/
|
|
||||||
val Player.activeEnchantsInSlots: Map<ItemInNumericSlot, Map<EcoEnchant, Int>>
|
|
||||||
get() {
|
|
||||||
val found = mutableMapOf<ItemInNumericSlot, MutableMap<EcoEnchant, Int>>()
|
|
||||||
for ((slot, enchants) in this.heldEnchantsInSlots) {
|
|
||||||
val inSlot = mutableMapOf<EcoEnchant, Int>()
|
|
||||||
for ((enchant, level) in enchants) {
|
|
||||||
val enchantLevel = enchant.getLevel(level)
|
|
||||||
val providedHolder = ItemProvidedHolder(enchantLevel, slot.item)
|
|
||||||
if (enchantLevel.conditions.areMet(this.toDispatcher(), providedHolder)) {
|
|
||||||
inSlot[enchant] = level
|
|
||||||
}
|
|
||||||
}
|
|
||||||
found[slot] = inSlot
|
|
||||||
}
|
|
||||||
|
|
||||||
return found
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All EcoEnchants mapped to their IDs, respecting conditions.
|
|
||||||
*/
|
|
||||||
val Player.activeEnchants: Map<EcoEnchant, Int>
|
|
||||||
get() {
|
|
||||||
val found = mutableMapOf<EcoEnchant, Int>()
|
|
||||||
for ((_, enchants) in this.activeEnchantsInSlots) {
|
|
||||||
for ((enchant, level) in enchants) {
|
|
||||||
found[enchant] = level
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return found
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the enchantment level on a player, ignoring conditions.
|
|
||||||
*
|
|
||||||
* @return The level, or 0 if not found.
|
|
||||||
*/
|
|
||||||
fun Player.getEnchantLevel(enchant: EcoEnchant): Int {
|
|
||||||
return this.heldEnchants[enchant] ?: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the enchantment level on a player, respecting.
|
|
||||||
*
|
|
||||||
* @return The level, or 0 if not found.
|
|
||||||
*/
|
|
||||||
fun Player.getActiveEnchantLevel(enchant: EcoEnchant): Int {
|
|
||||||
return this.activeEnchants[enchant] ?: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the enchantment level on a player in a specific slot, ignoring conditions.
|
|
||||||
*
|
|
||||||
* @return The level, or 0 if not found.
|
|
||||||
*/
|
|
||||||
fun Player.getEnchantLevelInSlot(enchant: EcoEnchant, slot: Int): Int {
|
|
||||||
val inSlot = this.slotIDHeldEnchants[slot] ?: return 0
|
|
||||||
val heldEnchant = inSlot.firstOrNull { it.enchant == enchant } ?: return 0
|
|
||||||
return heldEnchant.level
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the enchantment level on a player in a specific slot, respecting conditions.
|
|
||||||
*
|
|
||||||
* @return The level, or 0 if not found.
|
|
||||||
*/
|
|
||||||
fun Player.getActiveEnchantLevelInSlot(enchant: EcoEnchant, slot: Int): Int {
|
|
||||||
val level = getEnchantLevelInSlot(enchant, slot)
|
|
||||||
|
|
||||||
if (level == 0) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
val enchantLevel = enchant.getLevel(level)
|
|
||||||
val item = this.inventory.getItem(slot) ?: return 0
|
|
||||||
val providedHolder = ItemProvidedHolder(enchantLevel, item)
|
|
||||||
|
|
||||||
if (!enchantLevel.conditions.areMet(this.toDispatcher(), providedHolder)) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return level
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get if a player has an enchantment, ignoring conditions.
|
|
||||||
*
|
|
||||||
* @return If the player has the enchantment.
|
|
||||||
*/
|
|
||||||
fun Player.hasEnchant(enchant: EcoEnchant): Boolean {
|
|
||||||
return this.getEnchantLevel(enchant) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get if a player has an enchantment, respecting conditions.
|
|
||||||
*
|
|
||||||
* @return If the player has the enchantment.
|
|
||||||
*/
|
|
||||||
fun Player.hasEnchantActive(enchant: EcoEnchant): Boolean {
|
|
||||||
return this.getActiveEnchantLevel(enchant) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get if a player has an enchantment in a slot, ignoring conditions.
|
|
||||||
*
|
|
||||||
* @return If the player has the enchantment.
|
|
||||||
*/
|
|
||||||
fun Player.hasEnchantInSlot(enchant: EcoEnchant, slot: Int): Boolean {
|
|
||||||
return this.getEnchantLevelInSlot(enchant, slot) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get if a player has an enchantment in a slot, respecting conditions.
|
|
||||||
*
|
|
||||||
* @return If the player has the enchantment.
|
|
||||||
*/
|
|
||||||
fun Player.hasEnchantActiveInSlot(enchant: EcoEnchant, slot: Int): Boolean {
|
|
||||||
return this.getActiveEnchantLevelInSlot(enchant, slot) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
val Player.heldEnchantLevels: List<ItemProvidedHolder>
|
|
||||||
get() {
|
|
||||||
val found = mutableListOf<ItemProvidedHolder>()
|
|
||||||
|
|
||||||
for ((slot, enchants) in this.heldEnchantsInSlots) {
|
|
||||||
for ((enchant, level) in enchants) {
|
|
||||||
found.add(ItemProvidedHolder(enchant.getLevel(level), slot.item))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is such a fucking disgusting way of implementing %active_level%,
|
|
||||||
// and it's probably quite slow too.
|
|
||||||
return if (plugin.configYml.getBool("extra-placeholders.active-level")) {
|
|
||||||
found.map {
|
|
||||||
val level = it.holder as EcoEnchantLevel
|
|
||||||
|
|
||||||
ItemProvidedHolder(
|
|
||||||
FoundEcoEnchantLevel(level, this.getActiveEnchantLevel(level.enchant)), it.provider
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
found
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear item and enchant cache.
|
|
||||||
*/
|
|
||||||
fun Player.clearEnchantCache() {
|
|
||||||
itemCache.invalidate(player)
|
|
||||||
enchantCache.invalidate(player)
|
|
||||||
enchantLevelCache.invalidate(player)
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
fun createProvider(slot: SlotType): SlotProvider {
|
|
||||||
return { player: Player ->
|
|
||||||
val found = mutableMapOf<ItemInNumericSlot, ItemInSlot>()
|
|
||||||
|
|
||||||
for (slotID in slot.getItemSlots(player)) {
|
|
||||||
val item = player.inventory.getItem(slotID) ?: continue
|
|
||||||
found[ItemInNumericSlot(item, slotID)] = ItemInSlot(item, slot)
|
|
||||||
}
|
|
||||||
|
|
||||||
found
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (slot in SlotTypes.values()) {
|
|
||||||
registerProvider(createProvider(slot))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
#libreforge-updater
|
#libreforge-updater
|
||||||
#Wed Dec 27 14:18:03 CET 2023
|
#Wed Dec 27 14:18:03 CET 2023
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
libreforge-version=4.51.1
|
libreforge-version=4.52.0
|
||||||
version=11.2.1
|
version=12.0.0
|
||||||
|
Loading…
Reference in New Issue
Block a user