From dafc21214eaa0f94cd28af3f31c2ff6a1d2d32a9 Mon Sep 17 00:00:00 2001 From: rattatwinko Date: Fri, 2 May 2025 21:11:01 +0200 Subject: [PATCH] initial --- .gitignore | 113 ++++++++++ pom.xml | 87 ++++++++ src/main/kotlin/org/leaper/leaper/Leaper.kt | 220 ++++++++++++++++++++ src/main/resources/config.yml | 40 ++++ src/main/resources/plugin.yml | 17 ++ 5 files changed, 477 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/kotlin/org/leaper/leaper/Leaper.kt create mode 100644 src/main/resources/config.yml create mode 100644 src/main/resources/plugin.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4788b4b --- /dev/null +++ b/.gitignore @@ -0,0 +1,113 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +target/ + +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next + +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.flattened-pom.xml + +# Common working directory +run/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..c4bbc92 --- /dev/null +++ b/pom.xml @@ -0,0 +1,87 @@ + + + 4.0.0 + + org.leaper + leaper + 1.0-SNAPSHOT + jar + + leaper + + + 21 + 2.2.0-Beta2 + UTF-8 + + + + clean package + ${project.basedir}/src/main/kotlin + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + + ${java.version} + + + + org.apache.maven.plugins + maven-shade-plugin + 3.5.3 + + + package + + shade + + + + + + + + src/main/resources + true + + + + + + + papermc-repo + https://repo.papermc.io/repository/maven-public/ + + + sonatype + https://oss.sonatype.org/content/groups/public/ + + + + + + io.papermc.paper + paper-api + 1.21.5-R0.1-SNAPSHOT + provided + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + diff --git a/src/main/kotlin/org/leaper/leaper/Leaper.kt b/src/main/kotlin/org/leaper/leaper/Leaper.kt new file mode 100644 index 0000000..b4fee3b --- /dev/null +++ b/src/main/kotlin/org/leaper/leaper/Leaper.kt @@ -0,0 +1,220 @@ +package org.leaper.leaper + +import org.bukkit.ChatColor +import org.bukkit.Material +import org.bukkit.NamespacedKey +import org.bukkit.Particle +import org.bukkit.Sound +import org.bukkit.command.Command +import org.bukkit.command.CommandExecutor +import org.bukkit.command.CommandSender +import org.bukkit.entity.Player +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener +import org.bukkit.event.block.Action +import org.bukkit.event.player.PlayerInteractEvent +import org.bukkit.inventory.ItemFlag +import org.bukkit.inventory.ItemStack +import org.bukkit.persistence.PersistentDataType +import org.bukkit.plugin.java.JavaPlugin +import org.bukkit.potion.PotionEffect +import org.bukkit.potion.PotionEffectType +import java.util.UUID + +class Leaper : JavaPlugin(), Listener { + private val LEAPER_KEY = "leaper_item" + private lateinit var leaperKey: NamespacedKey + private val cooldowns = HashMap() + + // Configurable settings + private var cooldownTime = 5 * 1000 // Default: 5 seconds in milliseconds + private var leapDistance = 1.5 // Default: 1.5 blocks + private var leapHeight = 0.7 // Default: 0.7 blocks + private var jumpBoostDuration = 20 // Default: 20 ticks (1 second) + private var jumpBoostAmplifier = 1 // Default: level 2 jump boost + private var particleType = Particle.CLOUD // Default: cloud particles + private var particleCount = 25 // Default: 25 particles + private var soundEffect = Sound.ENTITY_RABBIT_JUMP // Default: rabbit jump sound + private var soundVolume = 1.0f // Default: 100% volume + private var soundPitch = 1.0f // Default: normal pitch + + override fun onEnable() { + // Save default config if it doesn't exist + saveDefaultConfig() + + // Load configuration + loadConfiguration() + + // Register events and commands + server.pluginManager.registerEvents(this, this) + getCommand("getleaper")?.setExecutor(LeaperCommand()) + getCommand("reloadleaper")?.setExecutor(ReloadCommand()) + + // Initialize NamespacedKey + leaperKey = NamespacedKey(this, LEAPER_KEY) + + logger.info("${ChatColor.GREEN}Leaper plugin has been enabled!") + } + + override fun onDisable() { + logger.info("${ChatColor.RED}Leaper plugin has been disabled!") + } + + private fun loadConfiguration() { + // Reload config from file + reloadConfig() + + // Load values from config + cooldownTime = config.getInt("settings.cooldown", 5) * 1000 + leapDistance = config.getDouble("settings.leap-distance", 1.5) + leapHeight = config.getDouble("settings.leap-height", 0.7) + jumpBoostDuration = config.getInt("settings.jump-boost-duration", 20) + jumpBoostAmplifier = config.getInt("settings.jump-boost-amplifier", 1) + + // Load particle settings + val particleTypeName = config.getString("effects.particle-type", "CLOUD") + try { + // Use Enum.values() instead of Enum.entries for backward compatibility + particleType = Particle.values().find { it.toString() == particleTypeName } ?: Particle.CLOUD + } catch (e: Exception) { + logger.warning("Invalid particle type in config: $particleTypeName. Using default: CLOUD") + particleType = Particle.CLOUD + } + particleCount = config.getInt("effects.particle-count", 25) + + // Load sound settings + val soundEffectName = config.getString("effects.sound", "ENTITY_RABBIT_JUMP") + try { + // Use Enum.values() instead of Enum.entries for backward compatibility + soundEffect = Sound.values().find { it.toString() == soundEffectName } ?: Sound.ENTITY_RABBIT_JUMP + } catch (e: Exception) { + logger.warning("Invalid sound effect in config: $soundEffectName. Using default: ENTITY_RABBIT_JUMP") + soundEffect = Sound.ENTITY_RABBIT_JUMP + } + soundVolume = config.getDouble("effects.sound-volume", 1.0).toFloat() + soundPitch = config.getDouble("effects.sound-pitch", 1.0).toFloat() + } + + inner class LeaperCommand : CommandExecutor { + override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array): Boolean { + if (sender !is Player) { + sender.sendMessage("${ChatColor.RED}This command can only be used by players!") + return true + } + + val player = sender + val leaperItem = createLeaperItem() + + // Check if inventory is full + if (player.inventory.firstEmpty() == -1) { + player.world.dropItemNaturally(player.location, leaperItem) + player.sendMessage("${ChatColor.YELLOW}Your inventory is full! The Leaper has been dropped at your feet.") + } else { + player.inventory.addItem(leaperItem) + player.sendMessage("${ChatColor.GREEN}You have received the Leaper!") + } + + return true + } + } + + inner class ReloadCommand : CommandExecutor { + override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array): Boolean { + // Reload configuration + loadConfiguration() + + sender.sendMessage("${ChatColor.GREEN}Leaper plugin configuration reloaded!") + return true + } + } + + private fun createLeaperItem(): ItemStack { + val leaper = ItemStack(Material.RABBIT_FOOT) + val meta = leaper.itemMeta + + meta?.setDisplayName("${ChatColor.AQUA}${ChatColor.BOLD}The Leaper") + meta?.lore = listOf( + "${ChatColor.GRAY}A magical foot that grants you the ability to leap!", + "${ChatColor.YELLOW}Right-click to jump forward", + "${ChatColor.RED}Cooldown: ${cooldownTime / 1000} seconds" + ) + + // Add item flags to hide enchantments/attributes + meta?.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_ENCHANTS) + + // Set persistent data to identify this item + meta?.persistentDataContainer?.set(leaperKey, PersistentDataType.BYTE, 1) + + leaper.itemMeta = meta + return leaper + } + + @EventHandler + fun onPlayerInteract(event: PlayerInteractEvent) { + val player = event.player + val item = event.item ?: return + + // Check if right-click air or block with the leaper item + if ((event.action == Action.RIGHT_CLICK_AIR || event.action == Action.RIGHT_CLICK_BLOCK) && + isLeaperItem(item)) { + + event.isCancelled = true + + // Check cooldown + val playerUUID = player.uniqueId + val currentTime = System.currentTimeMillis() + + if (cooldowns.containsKey(playerUUID)) { + val timeElapsed = currentTime - cooldowns[playerUUID]!! + + if (timeElapsed < cooldownTime) { + val remainingSeconds = (cooldownTime - timeElapsed) / 1000 + player.sendMessage("${ChatColor.RED}You must wait $remainingSeconds seconds before using The Leaper again!") + return + } + } + + // Apply leap effect + leap(player) + + // Set cooldown + cooldowns[playerUUID] = currentTime + } + } + + private fun isLeaperItem(item: ItemStack): Boolean { + val meta = item.itemMeta ?: return false + return meta.persistentDataContainer.has(leaperKey, PersistentDataType.BYTE) + } + + private fun leap(player: Player) { + // Calculate velocity based on config values + val direction = player.location.direction.multiply(leapDistance) + direction.y = leapHeight + + // Apply velocity to player + player.velocity = direction + + // Add jump boost effect if configured + if (jumpBoostDuration > 0 && jumpBoostAmplifier >= 0) { + player.addPotionEffect(PotionEffect( + PotionEffectType.JUMP_BOOST, + jumpBoostDuration, + jumpBoostAmplifier, + false, false, true + )) + } + + // Play sound effect + player.world.playSound(player.location, soundEffect, soundVolume, soundPitch) + + // Spawn particles + player.world.spawnParticle( + particleType, + player.location, + particleCount, + 0.5, 0.5, 0.5, // Spread in x, y, z directions + 0.1 // Particle speed + ) + } +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..74c62cb --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,40 @@ +# Leaper Plugin Configuration + +# General settings for the leaper item +settings: + # Cooldown time in seconds + cooldown: 5 + + # Distance of the leap in blocks + leap-distance: 1.5 + + # Height of the leap in blocks + leap-height: 0.7 + + # Duration of jump boost effect in ticks (20 ticks = 1 second) + # Set to 0 to disable + jump-boost-duration: 20 + + # Amplifier for jump boost effect (0 = level 1, 1 = level 2, etc.) + jump-boost-amplifier: 1 + +# Visual and sound effects +effects: + # Particle effect type + # Valid options: CLOUD, CRIT, FLAME, HEART, SMOKE, SPELL, etc. + # Full list: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Particle.html + particle-type: "CLOUD" + + # Number of particles to spawn + particle-count: 25 + + # Sound effect to play when leaping + # Valid options: ENTITY_RABBIT_JUMP, ENTITY_GENERIC_EXPLODE, ENTITY_FIREWORK_ROCKET_BLAST, etc. + # Full list: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Sound.html + sound: "ENTITY_RABBIT_JUMP" + + # Volume of the sound (0.0 to 1.0) + sound-volume: 1.0 + + # Pitch of the sound (0.5 to 2.0) + sound-pitch: 1.0 \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..84a5ef8 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,17 @@ +name: leaper +version: 1.0-SNAPSHOT +main: org.leaper.leaper.Leaper +api-version: 1.21 +description: A plugin that adds a special leaping item +author: YourName +commands: + getleaper: + description: Get the Leaper item + usage: /getleaper + permission: leaper.get + permission-message: You don't have permission to use this command. + +permissions: + leaper.get: + description: Allows players to get the Leaper item + default: true \ No newline at end of file