diff --git a/src/main/kotlin/net/axay/kspigot/items/KSpigotItems.kt b/src/main/kotlin/net/axay/kspigot/items/KSpigotItems.kt index 2111bad0..3709b2cb 100644 --- a/src/main/kotlin/net/axay/kspigot/items/KSpigotItems.kt +++ b/src/main/kotlin/net/axay/kspigot/items/KSpigotItems.kt @@ -1,92 +1,139 @@ package net.axay.kspigot.items +import org.bukkit.Bukkit import org.bukkit.Material -import org.bukkit.attribute.Attribute -import org.bukkit.attribute.AttributeModifier -import org.bukkit.enchantments.Enchantment import org.bukkit.inventory.ItemFlag import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.meta.ItemMeta -object KSpigotItems { +/* + ITEM STACK + */ - inline fun buildItem(material: Material, builder: KSpigotItemBuilder.() -> Unit): ItemStack { - return KSpigotItemBuilder(material).apply(builder).build() +// creation + +/** + * Creates a new [ItemStack] and opens a builder for it. + */ +inline fun itemStack(material: Material, builder: ItemStack.() -> Unit) = ItemStack(material).apply(builder) + +// extensions + +/** + * Opens a builder with the current meta. + * @param T the specific type of the meta + */ +inline fun ItemStack.meta(builder: T.() -> Unit) { + val curMeta = itemMeta as? T + itemMeta = if (curMeta != null) { + curMeta.apply(builder) + curMeta + } else { + itemMeta(type, builder) } - } -class KSpigotItemBuilder(material: Material) { - - private val itemStack = ItemStack(material, 1) - - var amount: Int? = null - - fun addEnchantment(enchantment: Enchantment, level: Int = 1) { - itemStack.addEnchantment(enchantment, level) - } - - fun itemMeta(builder: ItemMetaBuilder.() -> Unit) { - ItemMetaBuilder(itemStack).apply(builder).applyToItemStack() - } - - fun build(): ItemStack { - - amount?.let { itemStack.amount = it } - - return itemStack - - } +/** @see meta */ +@JvmName("simpleMeta") +inline fun ItemStack.meta(builder: ItemMeta.() -> Unit) = meta(builder) +/** + * Resets the meta and opens a builder to create the new one. + * @param T the specific type of the meta + */ +inline fun ItemStack.setMeta(builder: T.() -> Unit) { + itemMeta = itemMeta(type, builder) } -class ItemMetaBuilder(val itemStack: ItemStack) { +/** @see setMeta */ +@JvmName("simpleSetMeta") +inline fun ItemStack.setMeta(builder: ItemMeta.() -> Unit) = setMeta(builder) - private val itemMeta = itemStack.itemMeta +/* + ITEM META + */ - var lore = ArrayList() - var flags = ArrayList() - - var displayName: String? = null - var customModelData: Int? = null - var unbreakable: Boolean? = null - var localizedName: String? = null - - inline fun addLore(builder: ItemMetaLoreBuilder.() -> Unit) { - lore.addAll(ItemMetaLoreBuilder().apply(builder).lorelist) - } - - fun addAttributeModifier(attribute: Attribute, attributeModifier: AttributeModifier) { - itemMeta?.addAttributeModifier(attribute, attributeModifier) - } - - infix fun flag(itemFlag: ItemFlag) { - flags.add(itemFlag) - } - - fun applyToItemStack() { - itemMeta?.let { meta -> - - meta.lore = lore - meta.addItemFlags(*flags.toTypedArray()) - - displayName?.let { meta.setDisplayName(it) } - meta.setCustomModelData(customModelData) - unbreakable?.let { meta.isUnbreakable = it } - localizedName?.let { meta.setLocalizedName(it) } - - itemStack.itemMeta = meta - - } - } +// creation +/** + * Creates new a [ItemMeta] instance of the given material and opens a builder for it. + * @param T the specific type of the meta + */ +inline fun itemMeta(material: Material, builder: T.() -> Unit): T? { + val meta = Bukkit.getItemFactory().getItemMeta(material) + return if (meta is T) meta.apply(builder) else null } +/** @see itemMeta */ +@JvmName("simpleItemMeta") +inline fun itemMeta(material: Material, builder: ItemMeta.() -> Unit) = itemMeta(material, builder) + +// extensions + +/** + * Sets the lore (description) of the item. + */ +inline fun ItemMeta.setLore(builder: ItemMetaLoreBuilder.() -> Unit) { + lore = ItemMetaLoreBuilder().apply(builder).lorelist +} + +/** + * Adds new lines to the lore (description) of the item. + */ +inline fun ItemMeta.addLore(builder: ItemMetaLoreBuilder.() -> Unit) { + val newLore = lore ?: mutableListOf() + newLore.addAll(ItemMetaLoreBuilder().apply(builder).lorelist) + lore = newLore +} + +/** + * Lore builder which uses an [ArrayList] under the hood. + * It exists to provide overloaded operator functions. + */ class ItemMetaLoreBuilder { - val lorelist = ArrayList() - operator fun String.unaryPlus() { lorelist += this } +} -} \ No newline at end of file +/** + * Add a new [ItemFlag] to the item flags. + */ +fun ItemMeta.flag(itemFlag: ItemFlag) = addItemFlags(itemFlag) + +/** + * Add several [ItemFlag]s to the item flags. + */ +fun ItemMeta.flags(vararg itemFlag: ItemFlag) = addItemFlags(*itemFlag) + +/** + * Removes a [ItemFlag] from the item flags. + */ +fun ItemMeta.removeFlag(itemFlag: ItemFlag) = removeItemFlags(itemFlag) + +/** + * Removes several [ItemFlag]s from the item flags. + */ +fun ItemMeta.removeFlags(vararg itemFlag: ItemFlag) = removeItemFlags(*itemFlag) + +/** + * Provides safe access to the items' displayName. + */ +var ItemMeta.name: String? + get() = if (hasDisplayName()) displayName else null + set(value) = setDisplayName(value) + +/** + * Provides safe access to the items' customModelData. + */ +var ItemMeta.customModel: Int? + get() = if (hasCustomModelData()) customModelData else null + set(value) = setCustomModelData(value) + +/** + * Provides more consistent access to the items' localizedName. + */ +var ItemMeta.localName: String + get() = localizedName + set(value) = setLocalizedName(value) \ No newline at end of file