This commit is contained in:
rattatwinko
2025-05-02 21:11:01 +02:00
commit dafc21214e
5 changed files with 477 additions and 0 deletions

113
.gitignore vendored Normal file
View File

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

87
pom.xml Normal file
View File

@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.leaper</groupId>
<artifactId>leaper</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>leaper</name>
<properties>
<java.version>21</java.version>
<kotlin.version>2.2.0-Beta2</kotlin.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<defaultGoal>clean package</defaultGoal>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmTarget>${java.version}</jvmTarget>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>papermc-repo</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.21.5-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -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<UUID, Long>()
// 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<out String>): 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<out String>): 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
)
}
}

View File

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

View File

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