diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml
index 1b9931fdd..f348421e9 100644
--- a/.idea/dictionaries/project.xml
+++ b/.idea/dictionaries/project.xml
@@ -14,6 +14,7 @@
fawe
foojay
ghast
+ ghasts
glorp
gradleup
griefing
diff --git a/src/main/kotlin/org/xodium/vanillaplus/VanillaPlusBootstrap.kt b/src/main/kotlin/org/xodium/vanillaplus/VanillaPlusBootstrap.kt
index 7c1eb9ad6..fa704d08d 100644
--- a/src/main/kotlin/org/xodium/vanillaplus/VanillaPlusBootstrap.kt
+++ b/src/main/kotlin/org/xodium/vanillaplus/VanillaPlusBootstrap.kt
@@ -14,6 +14,7 @@ import io.papermc.paper.registry.tag.TagKey
import io.papermc.paper.tag.TagEntry
import net.kyori.adventure.key.Key
import org.xodium.vanillaplus.enchantments.NightVisionEnchantment
+import org.xodium.vanillaplus.enchantments.NimbusEnchantment
import org.xodium.vanillaplus.enchantments.PickupEnchantment
import org.xodium.vanillaplus.enchantments.ReplantEnchantment
@@ -81,12 +82,23 @@ internal class VanillaPlusBootstrap : PluginBootstrap {
.invoke(builder)
.supportedItems(event.getOrCreateTag(ItemTypeTagKeys.HEAD_ARMOR))
}
+ register(NimbusEnchantment.key) { builder ->
+ NimbusEnchantment
+ .invoke(builder)
+ .supportedItems(event.getOrCreateTag(ItemTypeTagKeys.HARNESSES))
+ }
}
},
)
registerEventHandler(LifecycleEvents.TAGS.postFlatten(RegistryKey.ENCHANTMENT)) { event ->
event.registrar().apply {
- val enchants = setOf(ReplantEnchantment.key, PickupEnchantment.key, NightVisionEnchantment.key)
+ val enchants =
+ setOf(
+ ReplantEnchantment.key,
+ PickupEnchantment.key,
+ NightVisionEnchantment.key,
+ NimbusEnchantment.key,
+ )
addToTag(EnchantmentTagKeys.TRADEABLE, enchants)
addToTag(EnchantmentTagKeys.NON_TREASURE, enchants)
addToTag(EnchantmentTagKeys.IN_ENCHANTING_TABLE, enchants)
diff --git a/src/main/kotlin/org/xodium/vanillaplus/enchantments/NimbusEnchantment.kt b/src/main/kotlin/org/xodium/vanillaplus/enchantments/NimbusEnchantment.kt
new file mode 100644
index 000000000..39f6c0660
--- /dev/null
+++ b/src/main/kotlin/org/xodium/vanillaplus/enchantments/NimbusEnchantment.kt
@@ -0,0 +1,59 @@
+package org.xodium.vanillaplus.enchantments
+
+import io.papermc.paper.event.entity.EntityEquipmentChangedEvent
+import io.papermc.paper.registry.data.EnchantmentRegistryEntry
+import org.bukkit.attribute.Attribute
+import org.bukkit.entity.HappyGhast
+import org.bukkit.inventory.EquipmentSlot
+import org.bukkit.inventory.EquipmentSlotGroup
+import org.xodium.vanillaplus.interfaces.EnchantmentInterface
+import org.xodium.vanillaplus.utils.ExtUtils.mm
+
+/** Represents an object handling nimbus enchantment implementation within the system. */
+@Suppress("UnstableApiUsage")
+internal object NimbusEnchantment : EnchantmentInterface {
+ const val DEFAULT_FLY_SPEED = 0.05
+
+ override fun invoke(builder: EnchantmentRegistryEntry.Builder): EnchantmentRegistryEntry.Builder =
+ builder
+ .description(key.value().replaceFirstChar { it.uppercase() }.mm())
+ .anvilCost(2)
+ .maxLevel(5)
+ .weight(2)
+ .minimumCost(EnchantmentRegistryEntry.EnchantmentCost.of(25, 5))
+ .maximumCost(EnchantmentRegistryEntry.EnchantmentCost.of(75, 10))
+ .activeSlots(EquipmentSlotGroup.SADDLE)
+
+ /**
+ * Handles the event when an entity's equipment changes, specifically for Happy Ghasts with the nimbus enchantment.
+ * @param event The event representing the change in entity equipment.
+ */
+ fun nimbus(event: EntityEquipmentChangedEvent) {
+ val entity = event.entity as? HappyGhast ?: return
+ val harness = entity.equipment.getItem(EquipmentSlot.BODY)
+ val attribute = entity.getAttribute(Attribute.FLYING_SPEED)
+
+ if (harness.hasItemMeta() && harness.itemMeta.hasEnchant(get())) {
+ val level = harness.itemMeta.getEnchantLevel(get())
+ val speedMultiplier = getSpeedMultiplier(level)
+ attribute?.baseValue = DEFAULT_FLY_SPEED * speedMultiplier
+ } else {
+ attribute?.baseValue = DEFAULT_FLY_SPEED
+ }
+ }
+
+ /**
+ * Calculates the flying speed multiplier based on the enchantment level.
+ * @param level The enchantment level (1-5)
+ * @return The flying speed multiplier for the given level
+ */
+ private fun getSpeedMultiplier(level: Int): Double =
+ when (level) {
+ 1 -> 1.5
+ 2 -> 2.0
+ 3 -> 2.5
+ 4 -> 3.0
+ 5 -> 3.5
+ else -> 1.0
+ }
+}
diff --git a/src/main/kotlin/org/xodium/vanillaplus/modules/EntityModule.kt b/src/main/kotlin/org/xodium/vanillaplus/modules/EntityModule.kt
index 45a49cdf8..cfe49c7d9 100644
--- a/src/main/kotlin/org/xodium/vanillaplus/modules/EntityModule.kt
+++ b/src/main/kotlin/org/xodium/vanillaplus/modules/EntityModule.kt
@@ -2,6 +2,7 @@
package org.xodium.vanillaplus.modules
+import io.papermc.paper.event.entity.EntityEquipmentChangedEvent
import org.bukkit.Material
import org.bukkit.entity.*
import org.bukkit.event.EventHandler
@@ -9,6 +10,7 @@ import org.bukkit.event.entity.EntityChangeBlockEvent
import org.bukkit.event.entity.EntityDeathEvent
import org.bukkit.event.entity.EntityExplodeEvent
import org.bukkit.inventory.ItemStack
+import org.xodium.vanillaplus.enchantments.NimbusEnchantment
import org.xodium.vanillaplus.interfaces.ModuleInterface
import kotlin.random.Random
@@ -36,6 +38,13 @@ internal class EntityModule : ModuleInterface {
}
}
+ @EventHandler
+ fun on(event: EntityEquipmentChangedEvent) {
+ if (!enabled()) return
+
+ NimbusEnchantment.nimbus(event)
+ }
+
/**
* Determines whether an entity's griefing behaviour should be cancelled based on configuration settings.
* @param entity The entity whose griefing behaviour is being evaluated.