-
-
Notifications
You must be signed in to change notification settings - Fork 0
feat/Enchantment/NightVision #314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c4c324a
9b77051
d7f6e1a
5782eea
5962821
7b9bc08
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,41 @@ | ||||||||||||||||||||||||||||||||||||||
| package org.xodium.vanillaplus.enchantments | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| import io.papermc.paper.event.entity.EntityEquipmentChangedEvent | ||||||||||||||||||||||||||||||||||||||
| import io.papermc.paper.registry.data.EnchantmentRegistryEntry | ||||||||||||||||||||||||||||||||||||||
| import org.bukkit.entity.Player | ||||||||||||||||||||||||||||||||||||||
| import org.bukkit.inventory.EquipmentSlotGroup | ||||||||||||||||||||||||||||||||||||||
| import org.bukkit.potion.PotionEffect | ||||||||||||||||||||||||||||||||||||||
| import org.bukkit.potion.PotionEffectType | ||||||||||||||||||||||||||||||||||||||
| import org.xodium.vanillaplus.interfaces.EnchantmentInterface | ||||||||||||||||||||||||||||||||||||||
| import org.xodium.vanillaplus.utils.ExtUtils.mm | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| /** Represents an object handling night vision enchantment implementation within the system. */ | ||||||||||||||||||||||||||||||||||||||
| @Suppress("UnstableApiUsage") | ||||||||||||||||||||||||||||||||||||||
| internal object NightVisionEnchantment : EnchantmentInterface { | ||||||||||||||||||||||||||||||||||||||
| override fun builder(builder: EnchantmentRegistryEntry.Builder): EnchantmentRegistryEntry.Builder = | ||||||||||||||||||||||||||||||||||||||
| builder | ||||||||||||||||||||||||||||||||||||||
| .description(key.value().replaceFirstChar { it.uppercase() }.mm()) | ||||||||||||||||||||||||||||||||||||||
| .anvilCost(2) | ||||||||||||||||||||||||||||||||||||||
| .maxLevel(1) | ||||||||||||||||||||||||||||||||||||||
| .weight(2) | ||||||||||||||||||||||||||||||||||||||
| .minimumCost(EnchantmentRegistryEntry.EnchantmentCost.of(25, 0)) | ||||||||||||||||||||||||||||||||||||||
| .maximumCost(EnchantmentRegistryEntry.EnchantmentCost.of(75, 0)) | ||||||||||||||||||||||||||||||||||||||
| .activeSlots(EquipmentSlotGroup.ARMOR) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||
| * Handles the equipment change event to apply or remove night vision effect based on the helmet enchantment. | ||||||||||||||||||||||||||||||||||||||
| * @param event The EntityEquipmentChangedEvent triggered when an entity's equipment changes. | ||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||
| fun nightVision(event: EntityEquipmentChangedEvent) { | ||||||||||||||||||||||||||||||||||||||
| val player = event.entity as? Player ?: return | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
| val player = event.entity as? Player ?: return | |
| if (event.entity !is Player) return | |
| val player = event.entity as Player |
Copilot
AI
Nov 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The night vision effect is applied with duration -1 (infinite), but the removal logic only removes effects with duration -1. This creates a potential issue where if the player receives a night vision effect from another source (e.g., potion, beacon), it won't be removed when they unequip the helmet. Additionally, if the player has a legitimate night vision effect from another source, it will be removed when they unequip the helmet. Consider tracking the source of the night vision effect or using a different approach to manage the enchantment's effect.
| player.addPotionEffect(PotionEffect(PotionEffectType.NIGHT_VISION, -1, 0, true, false, true)) | |
| } else { | |
| player.activePotionEffects | |
| .filter { it.type == PotionEffectType.NIGHT_VISION } | |
| .forEach { if (it.duration == -1) player.removePotionEffect(PotionEffectType.NIGHT_VISION) } | |
| // Apply night vision with a unique combination of flags to identify the helmet's effect | |
| player.addPotionEffect(PotionEffect(PotionEffectType.NIGHT_VISION, -1, 0, true, false, true)) | |
| } else { | |
| // Remove only the night vision effect applied by the helmet (identified by flags) | |
| player.activePotionEffects | |
| .filter { | |
| it.type == PotionEffectType.NIGHT_VISION && | |
| it.duration == -1 && | |
| it.isAmbient && | |
| !it.hasParticles && | |
| it.hasIcon | |
| } | |
| .forEach { player.removePotionEffect(PotionEffectType.NIGHT_VISION) } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,17 +4,33 @@ 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 net.kyori.adventure.key.Key | ||||||||||||||||||||||||||
| import org.bukkit.enchantments.Enchantment | ||||||||||||||||||||||||||
| import org.xodium.vanillaplus.VanillaPlusBootstrap.Companion.INSTANCE | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| /** Represents a contract for enchantments within the system. */ | ||||||||||||||||||||||||||
| @Suppress("UnstableApiUsage") | ||||||||||||||||||||||||||
| internal interface EnchantmentInterface { | ||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||
| * The unique typed key that identifies this enchantment in the registry. | ||||||||||||||||||||||||||
| * The unique typed key identifies this enchantment in the registry. | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
| * The unique typed key identifies this enchantment in the registry. | |
| * The unique typed key that identifies this enchantment in the registry. |
Copilot
AI
Nov 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default enchantment key implementation uses this::class.simpleName which could be null. The current code calls .toString() on a nullable type chain, which could result in the string "null" being used as the enchantment key name if simpleName is null. Consider adding a null check or using requireNotNull() to fail fast with a clear error message.
| this::class | |
| .simpleName | |
| ?.removeSuffix("Enchantment") | |
| ?.split(Regex("(?=[A-Z])")) | |
| ?.filter { it.isNotEmpty() } | |
| ?.joinToString("_") { it.lowercase() } | |
| .toString(), | |
| requireNotNull(this::class.simpleName) { "Enchantment class must have a non-null simpleName for key generation." } | |
| .removeSuffix("Enchantment") | |
| .split(Regex("(?=[A-Z])")) | |
| .filter { it.isNotEmpty() } | |
| .joinToString("_") { it.lowercase() }, |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,6 +5,7 @@ import io.papermc.paper.command.brigadier.Commands | |||||||||||||
| import io.papermc.paper.datacomponent.DataComponentTypes | ||||||||||||||
| import io.papermc.paper.datacomponent.item.ItemLore | ||||||||||||||
| import io.papermc.paper.datacomponent.item.ResolvableProfile | ||||||||||||||
| import io.papermc.paper.event.entity.EntityEquipmentChangedEvent | ||||||||||||||
| import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder | ||||||||||||||
| import org.bukkit.Material | ||||||||||||||
| import org.bukkit.entity.Player | ||||||||||||||
|
|
@@ -24,6 +25,7 @@ import org.bukkit.permissions.Permission | |||||||||||||
| import org.bukkit.permissions.PermissionDefault | ||||||||||||||
| import org.xodium.vanillaplus.VanillaPlus.Companion.instance | ||||||||||||||
| import org.xodium.vanillaplus.data.CommandData | ||||||||||||||
| import org.xodium.vanillaplus.enchantments.NightVisionEnchantment | ||||||||||||||
| import org.xodium.vanillaplus.enchantments.PickupEnchantment | ||||||||||||||
| import org.xodium.vanillaplus.enchantments.ReplantEnchantment | ||||||||||||||
| import org.xodium.vanillaplus.interfaces.ModuleInterface | ||||||||||||||
|
|
@@ -168,6 +170,13 @@ internal class PlayerModule( | |||||||||||||
| PickupEnchantment.pickup(event) | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
|
||||||||||||||
| /** | |
| * Handles the event when a player's equipment changes, triggering the night vision enchantment logic. | |
| * @param event The EntityEquipmentChangedEvent triggered when a player's equipment is updated. | |
| */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The equipment change event doesn't verify that the changed slot is actually the helmet slot. The
EntityEquipmentChangedEventis triggered for any equipment change (helmet, chestplate, leggings, boots, main hand, off hand), so this handler will execute and reapply/remove the night vision effect even when changing boots or holding a different item. Consider checkingevent.slotto ensure it's a helmet-related slot before processing.