Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
da593bd
+
Oct 8, 2025
907bc9a
use jpenillas resource factory so the manual yml is unneeded.
Oct 9, 2025
a0dd4bf
stdlib instead of stdlib-jdk8
Oct 9, 2025
a4801a0
tweaking
Oct 9, 2025
db07d50
fix version and using JsonMapper instead
Oct 10, 2025
5f45371
making configmanager use datainterface and refactoring datainterface …
Oct 10, 2025
79495a5
woops
Oct 10, 2025
8b41ee1
added module.key() util
Oct 10, 2025
c3234ba
[ci-skip] Update gradle/actions digest to 6a96db5 (#259)
renovate[bot] Oct 11, 2025
441e561
[ci-skip] Update plugin xyz.jpenilla.run-paper to v3.0.2 (#260)
renovate[bot] Oct 11, 2025
17a1866
fmt
Oct 11, 2025
9541b36
[ci-skip] Update softprops/action-gh-release digest to 6da8fa9 (#261)
renovate[bot] Oct 11, 2025
f6867a3
playerskull not displayname but name instead
Oct 11, 2025
7dfbea7
init
Oct 13, 2025
39fb11f
+
Oct 13, 2025
5985220
Merge branch 'dev' into feat/MobsModule/HappyGhastCustomFlyingSpeed
Oct 15, 2025
385697b
update
Oct 15, 2025
98e51ae
+
Oct 15, 2025
6d87eed
fix bootstrap
Oct 15, 2025
5489394
Merge branch 'dev' into feat/MobsModule/HappyGhastCustomFlyingSpeed
illyrius666 Oct 15, 2025
4ce423f
set bootstrapper
Oct 15, 2025
ab276b5
refactor
Oct 15, 2025
4d7de49
refactor
Oct 15, 2025
89b5d37
+
Oct 15, 2025
93bfb3c
NIMBUS & ZEPHYR now cannot be used together at the same time
Oct 15, 2025
174fdb4
Merge branch 'dev' into feat/MobsModule/HappyGhastCustomFlyingSpeed
Oct 23, 2025
472a0e8
bump
Oct 23, 2025
860bdee
registered the new enchantment into the TRADEABLE,NON_TREASURE & IN_E…
Oct 23, 2025
78b83b9
refactor
Oct 23, 2025
b1e19e7
refactor
Oct 23, 2025
206df2d
bloop
Oct 23, 2025
c962c27
making use of operators for get() functions
Oct 23, 2025
88f88cb
refactor
Oct 23, 2025
03892e4
refactor
Oct 23, 2025
0da3996
added a suppress tag
Oct 23, 2025
d7e1794
another refactor
Oct 23, 2025
35ff0e9
removed horse trading
Oct 23, 2025
2b2c6d4
added effects & attribute modifiers, left is to add requirements and …
Oct 23, 2025
9a0d56c
init eventhandler for nimbus conditions
Oct 23, 2025
f934c61
Merge branch 'refs/heads/dev' into feat/MobsModule/HappyGhastCustomFl…
Nov 2, 2025
82690a2
+
Nov 2, 2025
4368127
Merge branch 'dev' into feat/MobsModule/HappyGhastCustomFlyingSpeed
illyrius666 Nov 12, 2025
ed87608
Merge branch 'dev' into feat/MobsModule/HappyGhastCustomFlyingSpeed
illyrius666 Nov 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .idea/dictionaries/project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions .idea/modules/VanillaPlus.main.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions .idea/modules/VanillaPlus.test.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
49 changes: 49 additions & 0 deletions src/main/kotlin/org/xodium/vanillaplus/VanillaPlusBootstrap.kt
Original file line number Diff line number Diff line change
@@ -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)
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -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<Enchantment> = 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())
}
}
Original file line number Diff line number Diff line change
@@ -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<Enchantment> = 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)),
)
}
}
Original file line number Diff line number Diff line change
@@ -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<Enchantment> = 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)),
)
}
}
Original file line number Diff line number Diff line change
@@ -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<Enchantment> = 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)),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ interface DataInterface<K, T : Any> {
* @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]
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Enchantment>

/**
* 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)
}
12 changes: 9 additions & 3 deletions src/main/kotlin/org/xodium/vanillaplus/modules/EntityModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand All @@ -29,11 +30,16 @@ internal class EntityModule : ModuleInterface<EntityModule.Config> {
}

@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
}

/**
Expand Down
Loading