diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml index 8a39c187d..5596fa788 100644 --- a/.idea/dictionaries/project.xml +++ b/.idea/dictionaries/project.xml @@ -38,6 +38,7 @@ unloadinv userdev vanillaplus + veinmine worldedit xodium xparser diff --git a/.idea/libraries/Gradle__io_papermc_paper_paper_api_1_21_10_R0_1_SNAPSHOT.xml b/.idea/libraries/Gradle__io_papermc_paper_paper_api_1_21_10_R0_1_SNAPSHOT.xml index 9cef7876f..5b9ccd7c3 100644 --- a/.idea/libraries/Gradle__io_papermc_paper_paper_api_1_21_10_R0_1_SNAPSHOT.xml +++ b/.idea/libraries/Gradle__io_papermc_paper_paper_api_1_21_10_R0_1_SNAPSHOT.xml @@ -6,6 +6,7 @@ + diff --git a/.idea/modules/VanillaPlus.main.iml b/.idea/modules/VanillaPlus.main.iml index db9206a2c..167b72c2b 100644 --- a/.idea/modules/VanillaPlus.main.iml +++ b/.idea/modules/VanillaPlus.main.iml @@ -11,7 +11,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/.idea/modules/VanillaPlus.test.iml b/.idea/modules/VanillaPlus.test.iml index 4c8849308..3712be1c4 100644 --- a/.idea/modules/VanillaPlus.test.iml +++ b/.idea/modules/VanillaPlus.test.iml @@ -12,7 +12,7 @@ - + VanillaPlus:main @@ -54,7 +54,7 @@ - + diff --git a/build.gradle.kts b/build.gradle.kts index 82b7e6027..9284e7051 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -62,6 +62,7 @@ paperPluginYaml { main.set(group.toString()) authors.add("Xodium") apiVersion.set(version) + bootstrapper.set("org.xodium.vanillaplus.VanillaPlusBootstrap") dependencies { server(name = "WorldEdit", load = PaperPluginYaml.Load.BEFORE, required = false, joinClasspath = true) } diff --git a/src/main/kotlin/org/xodium/vanillaplus/VanillaPlusBootstrap.kt b/src/main/kotlin/org/xodium/vanillaplus/VanillaPlusBootstrap.kt new file mode 100644 index 000000000..c47877f34 --- /dev/null +++ b/src/main/kotlin/org/xodium/vanillaplus/VanillaPlusBootstrap.kt @@ -0,0 +1,49 @@ +package org.xodium.vanillaplus + +import io.papermc.paper.plugin.bootstrap.BootstrapContext +import io.papermc.paper.plugin.bootstrap.PluginBootstrap +import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents +import io.papermc.paper.registry.RegistryKey +import io.papermc.paper.registry.event.RegistryEvents +import io.papermc.paper.registry.keys.tags.EnchantmentTagKeys +import io.papermc.paper.registry.keys.tags.ItemTypeTagKeys +import org.xodium.vanillaplus.enchantments.DriftEnchantment +import org.xodium.vanillaplus.enchantments.FortitudeEnchantment +import org.xodium.vanillaplus.enchantments.NimbusEnchantment +import org.xodium.vanillaplus.enchantments.ZephyrEnchantment + +/** Main bootstrap class of the plugin. */ +@Suppress("UnstableApiUsage", "Unused") +internal class VanillaPlusBootstrap : PluginBootstrap { + companion object { + const val INSTANCE = "vanillaplus" + val DRIFT = DriftEnchantment.key + val FORTITUDE = FortitudeEnchantment.key + val NIMBUS = NimbusEnchantment.key + val ZEPHYR = ZephyrEnchantment.key + val ENCHANTS = setOf(DRIFT, FORTITUDE, NIMBUS, ZEPHYR) + } + + override fun bootstrap(ctx: BootstrapContext) { + ctx.lifecycleManager.apply { + registerEventHandler( + RegistryEvents.ENCHANTMENT.compose().newHandler { event -> + val harnessesTag = event.getOrCreateTag(ItemTypeTagKeys.HARNESSES) + event.registry().apply { + register(DRIFT) { DriftEnchantment.init(it).supportedItems(harnessesTag) } + register(FORTITUDE) { FortitudeEnchantment.init(it).supportedItems(harnessesTag) } + register(NIMBUS) { NimbusEnchantment.init(it).supportedItems(harnessesTag) } + register(ZEPHYR) { ZephyrEnchantment.init(it).supportedItems(harnessesTag) } + } + }, + ) + registerEventHandler(LifecycleEvents.TAGS.postFlatten(RegistryKey.ENCHANTMENT)) { event -> + event.registrar().apply { + 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/DriftEnchantment.kt b/src/main/kotlin/org/xodium/vanillaplus/enchantments/DriftEnchantment.kt new file mode 100644 index 000000000..d3c5a0ea9 --- /dev/null +++ b/src/main/kotlin/org/xodium/vanillaplus/enchantments/DriftEnchantment.kt @@ -0,0 +1,43 @@ +package org.xodium.vanillaplus.enchantments + +import io.papermc.paper.registry.RegistryKey +import io.papermc.paper.registry.TypedKey +import io.papermc.paper.registry.data.EnchantmentRegistryEntry +import net.kyori.adventure.key.Key +import org.bukkit.enchantments.Enchantment +import org.bukkit.entity.Player +import org.bukkit.inventory.EquipmentSlotGroup +import org.bukkit.potion.PotionEffect +import org.bukkit.potion.PotionEffectType +import org.xodium.vanillaplus.VanillaPlusBootstrap.Companion.INSTANCE +import org.xodium.vanillaplus.interfaces.EnchantmentInterface +import org.xodium.vanillaplus.utils.ExtUtils.mm + +@Suppress("UnstableApiUsage") +internal object DriftEnchantment : EnchantmentInterface { + override val key: TypedKey = TypedKey.create(RegistryKey.ENCHANTMENT, Key.key(INSTANCE, "drift")) + + override fun init(builder: EnchantmentRegistryEntry.Builder) = + builder + .description(key.value().replaceFirstChar { it.uppercase() }.mm()) + .anvilCost(2) + .maxLevel(2) + .weight(5) + .minimumCost(EnchantmentRegistryEntry.EnchantmentCost.of(4, 6)) + .maximumCost(EnchantmentRegistryEntry.EnchantmentCost.of(24, 6)) + .activeSlots(EquipmentSlotGroup.BODY) + + fun effect(): PotionEffect = + PotionEffect( + PotionEffectType.SLOW_FALLING, + 100, + 0, + true, + true, + true, + ) + + fun Player.drift() { + addPotionEffect(effect()) + } +} diff --git a/src/main/kotlin/org/xodium/vanillaplus/enchantments/FortitudeEnchantment.kt b/src/main/kotlin/org/xodium/vanillaplus/enchantments/FortitudeEnchantment.kt new file mode 100644 index 000000000..26770f345 --- /dev/null +++ b/src/main/kotlin/org/xodium/vanillaplus/enchantments/FortitudeEnchantment.kt @@ -0,0 +1,47 @@ +package org.xodium.vanillaplus.enchantments + +import io.papermc.paper.datacomponent.DataComponentTypes +import io.papermc.paper.datacomponent.item.ItemAttributeModifiers +import io.papermc.paper.registry.RegistryKey +import io.papermc.paper.registry.TypedKey +import io.papermc.paper.registry.data.EnchantmentRegistryEntry +import net.kyori.adventure.key.Key +import org.bukkit.NamespacedKey +import org.bukkit.attribute.Attribute +import org.bukkit.attribute.AttributeModifier +import org.bukkit.enchantments.Enchantment +import org.bukkit.inventory.EquipmentSlotGroup +import org.bukkit.inventory.ItemStack +import org.xodium.vanillaplus.VanillaPlusBootstrap.Companion.FORTITUDE +import org.xodium.vanillaplus.VanillaPlusBootstrap.Companion.INSTANCE +import org.xodium.vanillaplus.interfaces.EnchantmentInterface +import org.xodium.vanillaplus.utils.ExtUtils.mm + +@Suppress("UnstableApiUsage") +internal object FortitudeEnchantment : EnchantmentInterface { + override val key: TypedKey = TypedKey.create(RegistryKey.ENCHANTMENT, Key.key(INSTANCE, "fortitude")) + + override fun init(builder: EnchantmentRegistryEntry.Builder) = + builder + .description(FORTITUDE.value().replaceFirstChar { it.uppercase() }.mm()) + .anvilCost(2) + .maxLevel(4) + .weight(5) + .minimumCost(EnchantmentRegistryEntry.EnchantmentCost.of(4, 6)) + .maximumCost(EnchantmentRegistryEntry.EnchantmentCost.of(24, 6)) + .activeSlots(EquipmentSlotGroup.BODY) + + fun effect(level: Int): AttributeModifier = + AttributeModifier( + NamespacedKey(INSTANCE, "fortitude_armor"), + 2.0 + (level - 1.0) * 2.0, + AttributeModifier.Operation.ADD_NUMBER, + ) + + fun ItemStack.fortitude(level: Int) { + setData( + DataComponentTypes.ATTRIBUTE_MODIFIERS, + ItemAttributeModifiers.itemAttributes().addModifier(Attribute.ARMOR, effect(level)), + ) + } +} 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..cc3b6bc30 --- /dev/null +++ b/src/main/kotlin/org/xodium/vanillaplus/enchantments/NimbusEnchantment.kt @@ -0,0 +1,55 @@ +package org.xodium.vanillaplus.enchantments + +import io.papermc.paper.datacomponent.DataComponentTypes +import io.papermc.paper.datacomponent.item.ItemAttributeModifiers +import io.papermc.paper.registry.RegistryKey +import io.papermc.paper.registry.TypedKey +import io.papermc.paper.registry.data.EnchantmentRegistryEntry +import io.papermc.paper.registry.set.RegistrySet +import net.kyori.adventure.key.Key +import org.bukkit.NamespacedKey +import org.bukkit.attribute.Attribute +import org.bukkit.attribute.AttributeModifier +import org.bukkit.enchantments.Enchantment +import org.bukkit.inventory.EquipmentSlotGroup +import org.bukkit.inventory.ItemStack +import org.xodium.vanillaplus.VanillaPlusBootstrap.Companion.INSTANCE +import org.xodium.vanillaplus.VanillaPlusBootstrap.Companion.NIMBUS +import org.xodium.vanillaplus.VanillaPlusBootstrap.Companion.ZEPHYR +import org.xodium.vanillaplus.interfaces.EnchantmentInterface +import org.xodium.vanillaplus.utils.ExtUtils.mm + +@Suppress("UnstableApiUsage") +internal object NimbusEnchantment : EnchantmentInterface { + override val key: TypedKey = TypedKey.create(RegistryKey.ENCHANTMENT, Key.key(INSTANCE, "nimbus")) + + override fun init(builder: EnchantmentRegistryEntry.Builder) = + builder + .description(NIMBUS.value().replaceFirstChar { it.uppercase() }.mm()) + .anvilCost(2) + .maxLevel(3) + .weight(5) + .minimumCost(EnchantmentRegistryEntry.EnchantmentCost.of(4, 6)) + .maximumCost(EnchantmentRegistryEntry.EnchantmentCost.of(24, 6)) + .activeSlots(EquipmentSlotGroup.BODY) + .exclusiveWith( + RegistrySet.keySet( + RegistryKey.ENCHANTMENT, + setOf(RegistryKey.ENCHANTMENT.typedKey(ZEPHYR)), + ), + ) + + fun effect(level: Int): AttributeModifier = + AttributeModifier( + NamespacedKey(INSTANCE, "nimbus_flying_speed"), + 0.85 + (level - 1.0) * 0.25, + AttributeModifier.Operation.ADD_SCALAR, + ) + + fun ItemStack.nimbus(level: Int) { + setData( + DataComponentTypes.ATTRIBUTE_MODIFIERS, + ItemAttributeModifiers.itemAttributes().addModifier(Attribute.ARMOR, effect(level)), + ) + } +} diff --git a/src/main/kotlin/org/xodium/vanillaplus/enchantments/ZephyrEnchantment.kt b/src/main/kotlin/org/xodium/vanillaplus/enchantments/ZephyrEnchantment.kt new file mode 100644 index 000000000..7835595c7 --- /dev/null +++ b/src/main/kotlin/org/xodium/vanillaplus/enchantments/ZephyrEnchantment.kt @@ -0,0 +1,55 @@ +package org.xodium.vanillaplus.enchantments + +import io.papermc.paper.datacomponent.DataComponentTypes +import io.papermc.paper.datacomponent.item.ItemAttributeModifiers +import io.papermc.paper.registry.RegistryKey +import io.papermc.paper.registry.TypedKey +import io.papermc.paper.registry.data.EnchantmentRegistryEntry +import io.papermc.paper.registry.set.RegistrySet +import net.kyori.adventure.key.Key +import org.bukkit.NamespacedKey +import org.bukkit.attribute.Attribute +import org.bukkit.attribute.AttributeModifier +import org.bukkit.enchantments.Enchantment +import org.bukkit.inventory.EquipmentSlotGroup +import org.bukkit.inventory.ItemStack +import org.xodium.vanillaplus.VanillaPlusBootstrap.Companion.INSTANCE +import org.xodium.vanillaplus.VanillaPlusBootstrap.Companion.NIMBUS +import org.xodium.vanillaplus.VanillaPlusBootstrap.Companion.ZEPHYR +import org.xodium.vanillaplus.interfaces.EnchantmentInterface +import org.xodium.vanillaplus.utils.ExtUtils.mm + +@Suppress("UnstableApiUsage") +internal object ZephyrEnchantment : EnchantmentInterface { + override val key: TypedKey = TypedKey.create(RegistryKey.ENCHANTMENT, Key.key(INSTANCE, "zephyr")) + + override fun init(builder: EnchantmentRegistryEntry.Builder) = + builder + .description(ZEPHYR.value().replaceFirstChar { it.uppercase() }.mm()) + .anvilCost(2) + .maxLevel(5) + .weight(5) + .minimumCost(EnchantmentRegistryEntry.EnchantmentCost.of(4, 6)) + .maximumCost(EnchantmentRegistryEntry.EnchantmentCost.of(24, 6)) + .activeSlots(EquipmentSlotGroup.BODY) + .exclusiveWith( + RegistrySet.keySet( + RegistryKey.ENCHANTMENT, + setOf(RegistryKey.ENCHANTMENT.typedKey(NIMBUS)), + ), + ) + + fun effect(level: Int): AttributeModifier = + AttributeModifier( + NamespacedKey(INSTANCE, "zephyr_flying_speed"), + 0.25 + (level - 1.0) * 0.15, + AttributeModifier.Operation.ADD_SCALAR, + ) + + fun ItemStack.zephyr(level: Int) { + setData( + DataComponentTypes.ATTRIBUTE_MODIFIERS, + ItemAttributeModifiers.itemAttributes().addModifier(Attribute.ARMOR, effect(level)), + ) + } +} diff --git a/src/main/kotlin/org/xodium/vanillaplus/interfaces/DataInterface.kt b/src/main/kotlin/org/xodium/vanillaplus/interfaces/DataInterface.kt index 1928ceede..0383f3fcc 100644 --- a/src/main/kotlin/org/xodium/vanillaplus/interfaces/DataInterface.kt +++ b/src/main/kotlin/org/xodium/vanillaplus/interfaces/DataInterface.kt @@ -74,7 +74,7 @@ interface DataInterface { * @param key the UUID key whose associated value is to be returned. * @return the value associated with the specified key, or `null` if no mapping exists. */ - fun get(key: K): T? { + operator fun get(key: K): T? { if (cache.isEmpty() && filePath.toFile().exists()) load() return cache[key] } diff --git a/src/main/kotlin/org/xodium/vanillaplus/interfaces/EnchantmentInterface.kt b/src/main/kotlin/org/xodium/vanillaplus/interfaces/EnchantmentInterface.kt new file mode 100644 index 000000000..e252fb96d --- /dev/null +++ b/src/main/kotlin/org/xodium/vanillaplus/interfaces/EnchantmentInterface.kt @@ -0,0 +1,32 @@ +package org.xodium.vanillaplus.interfaces + +import io.papermc.paper.registry.RegistryAccess +import io.papermc.paper.registry.RegistryKey +import io.papermc.paper.registry.TypedKey +import io.papermc.paper.registry.data.EnchantmentRegistryEntry +import org.bukkit.enchantments.Enchantment + +/** Represents a contract for enchantments within the system. */ +@Suppress("UnstableApiUsage") +internal interface EnchantmentInterface { + /** + * The unique typed key that identifies this enchantment in the registry. + * @see TypedKey + * @see RegistryKey.ENCHANTMENT + */ + val key: TypedKey + + /** + * Initializes the Drift enchantment. + * @param builder The builder used to define the enchantment properties. + * @return The builder for method chaining. + */ + fun init(builder: EnchantmentRegistryEntry.Builder): EnchantmentRegistryEntry.Builder + + /** + * Retrieves the enchantment from the registry. + * @return The [Enchantment] instance corresponding to the key. + * @throws NoSuchElementException if the enchantment is not found in the registry. + */ + fun get(): Enchantment = RegistryAccess.registryAccess().getRegistry(RegistryKey.ENCHANTMENT).getOrThrow(key) +} diff --git a/src/main/kotlin/org/xodium/vanillaplus/modules/EntityModule.kt b/src/main/kotlin/org/xodium/vanillaplus/modules/EntityModule.kt index 45a49cdf8..b413ba3ef 100644 --- a/src/main/kotlin/org/xodium/vanillaplus/modules/EntityModule.kt +++ b/src/main/kotlin/org/xodium/vanillaplus/modules/EntityModule.kt @@ -2,14 +2,15 @@ package org.xodium.vanillaplus.modules +import io.papermc.paper.event.entity.EntityMoveEvent import org.bukkit.Material import org.bukkit.entity.* import org.bukkit.event.EventHandler 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.interfaces.ModuleInterface +import org.bukkit.inventory.ItemStack import kotlin.random.Random /** Represents a module handling entity mechanics within the system. */ @@ -29,11 +30,16 @@ internal class EntityModule : ModuleInterface { } @EventHandler - fun on(event: EntityDeathEvent) { - if (!enabled() || event.entity.killer == null) return + fun on(event: EntityMoveEvent) { + if (!enabled()) return + if (event.entity.killer == null) return //FIX: make it inside the if statement below. if (Random.nextDouble() <= config.entityEggDropChance) { event.drops.add(ItemStack.of(Material.matchMaterial("${event.entity.type.name}_SPAWN_EGG") ?: return)) } + val entity = event.entity as? HappyGhast ?: return + val location = entity.location + if (location.y <= 187) return + // TODO: implement nimbus } /**