From 23bb8559f2fab103cc9111d2222f8a2f086c14bb Mon Sep 17 00:00:00 2001 From: Kariya Date: Thu, 11 Dec 2025 14:48:55 +0000 Subject: [PATCH] feat: Add double jump component --- .../kotlin/net/hareworks/hcu/items/App.kt | 6 +- .../items/api/component/CustomComponent.kt | 1 + .../content/components/DoubleJumpComponent.kt | 72 +++++++++++++++++++ .../hcu/items/listeners/EventListener.kt | 11 +++ 4 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 src/main/kotlin/net/hareworks/hcu/items/content/components/DoubleJumpComponent.kt diff --git a/src/main/kotlin/net/hareworks/hcu/items/App.kt b/src/main/kotlin/net/hareworks/hcu/items/App.kt index 15fc46d..aaa433d 100644 --- a/src/main/kotlin/net/hareworks/hcu/items/App.kt +++ b/src/main/kotlin/net/hareworks/hcu/items/App.kt @@ -9,6 +9,7 @@ import net.hareworks.hcu.items.registry.ComponentRegistry import net.hareworks.hcu.items.content.items.TestItem import net.hareworks.hcu.items.content.items.GrapplingItem import net.hareworks.hcu.items.content.components.GliderComponent +import net.hareworks.hcu.items.content.components.DoubleJumpComponent import org.bukkit.permissions.PermissionDefault import org.bukkit.plugin.java.JavaPlugin @@ -36,7 +37,8 @@ public class App : JavaPlugin() { ItemRegistry.register(GrapplingItem()) // Register Components - val gliderComponent = GliderComponent(this) - ComponentRegistry.register(gliderComponent) + ComponentRegistry.register(GliderComponent(this)) + ComponentRegistry.register(DoubleJumpComponent(this)) + } } diff --git a/src/main/kotlin/net/hareworks/hcu/items/api/component/CustomComponent.kt b/src/main/kotlin/net/hareworks/hcu/items/api/component/CustomComponent.kt index 4f1c470..2849f07 100644 --- a/src/main/kotlin/net/hareworks/hcu/items/api/component/CustomComponent.kt +++ b/src/main/kotlin/net/hareworks/hcu/items/api/component/CustomComponent.kt @@ -18,4 +18,5 @@ interface CustomComponent { fun onEntityDamage(event: org.bukkit.event.entity.EntityDamageEvent) {} fun onPlayerMove(event: org.bukkit.event.player.PlayerMoveEvent) {} fun onToggleSneak(player: org.bukkit.entity.Player, item: org.bukkit.inventory.ItemStack, event: org.bukkit.event.player.PlayerToggleSneakEvent) {} + fun onToggleGlide(player: org.bukkit.entity.Player, item: org.bukkit.inventory.ItemStack, event: org.bukkit.event.entity.EntityToggleGlideEvent) {} } diff --git a/src/main/kotlin/net/hareworks/hcu/items/content/components/DoubleJumpComponent.kt b/src/main/kotlin/net/hareworks/hcu/items/content/components/DoubleJumpComponent.kt new file mode 100644 index 0000000..75e2589 --- /dev/null +++ b/src/main/kotlin/net/hareworks/hcu/items/content/components/DoubleJumpComponent.kt @@ -0,0 +1,72 @@ +package net.hareworks.hcu.items.content.components + +import net.hareworks.hcu.items.App +import net.hareworks.hcu.items.api.Tier +import net.hareworks.hcu.items.api.component.AbstractComponent +import net.hareworks.hcu.items.api.component.EquippableComponent +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.NamedTextColor +import org.bukkit.GameMode +import org.bukkit.Material +import org.bukkit.Particle +import org.bukkit.Sound +import org.bukkit.entity.Player +import org.bukkit.event.entity.EntityToggleGlideEvent +import org.bukkit.inventory.ItemStack +import org.bukkit.util.Vector + +class DoubleJumpComponent(private val plugin: App) : AbstractComponent(plugin, "double_jump_component"), EquippableComponent { + + override val displayName: String = "Double Jump" + override val maxTier: Int = 3 + + override fun apply(item: ItemStack, tier: Tier?) { + if (isBoots(item.type)) { + super.apply(item, tier) + } + } + + private fun isBoots(material: Material): Boolean { + // Only apply to boots + return material.name.endsWith("_BOOTS") + } + + override fun onTick(player: Player, item: ItemStack) { + // No custom tick login currently + } + + override fun onToggleGlide(player: Player, item: ItemStack, event: EntityToggleGlideEvent) { + if (player.gameMode == GameMode.CREATIVE || player.gameMode == GameMode.SPECTATOR) return + + // When user initiates gliding (pressing Jump in air with Elytra/Glider capability) + // event.isGliding will be true. + if (event.isGliding) { + // Cancel the glide start + event.isCancelled = true + + // Execute Double Jump + handleDoubleJump(player, item) + } + } + + private fun handleDoubleJump(player: Player, item: ItemStack) { + val tier = getTier(item) ?: Tier.ONE + + // Physics Calculation + // Vector: Up + Forward direction + val direction = player.location.direction.clone().setY(0).normalize() + val currentVelocity = player.velocity + + // Base power + Tier bonus + val verticalPower = 0.5 + (tier.level * 0.15) + val forwardPower = 0.3 + (tier.level * 0.1) + + player.velocity = currentVelocity.add(direction.multiply(forwardPower)).setY(verticalPower) + + // Effects + player.world.spawnParticle(Particle.CLOUD, player.location, 10, 0.5, 0.1, 0.5, 0.05) + player.playSound(player.location, Sound.ENTITY_BAT_TAKEOFF, 1.0f, 1.2f) + + player.sendActionBar(Component.text("Double Jump!", NamedTextColor.GREEN)) + } +} diff --git a/src/main/kotlin/net/hareworks/hcu/items/listeners/EventListener.kt b/src/main/kotlin/net/hareworks/hcu/items/listeners/EventListener.kt index 497a580..10d645f 100644 --- a/src/main/kotlin/net/hareworks/hcu/items/listeners/EventListener.kt +++ b/src/main/kotlin/net/hareworks/hcu/items/listeners/EventListener.kt @@ -98,6 +98,17 @@ class EventListener(private val plugin: Plugin) : Listener { } } + @EventHandler + fun onToggleGlide(event: org.bukkit.event.entity.EntityToggleGlideEvent) { + val entity = event.entity + if (entity is Player) { + val items = getEquipmentItems(entity) + for (item in items) { + dispatchToComponents(item) { it.onToggleGlide(entity, item, event) } + } + } + } + private fun tickComponents() { for (player in plugin.server.onlinePlayers) { val items = getEquipmentItems(player)