From b0235050f037ea7b56e25c82b8ce6a9936116ac8 Mon Sep 17 00:00:00 2001 From: Xelara Networks Date: Thu, 11 Jun 2026 20:49:27 -0400 Subject: [PATCH] added --- README.md | 0 pom.xml | 47 ++++ .../com/bitnix/dirthead/DirtHeadPlugin.java | 221 ++++++++++++++++++ src/main/resources/config.yml | 37 +++ src/main/resources/plugin.yml | 18 ++ target/DirtHead-1.0-SNAPSHOT.jar | Bin 0 -> 9014 bytes .../com/bitnix/dirthead/DirtHeadPlugin.class | Bin 0 -> 12794 bytes target/classes/config.yml | 37 +++ target/classes/plugin.yml | 18 ++ target/maven-archiver/pom.properties | 5 + .../compile/default-compile/createdFiles.lst | 1 + .../compile/default-compile/inputFiles.lst | 1 + 12 files changed, 385 insertions(+) create mode 100644 README.md create mode 100644 pom.xml create mode 100644 src/main/java/com/bitnix/dirthead/DirtHeadPlugin.java create mode 100644 src/main/resources/config.yml create mode 100644 src/main/resources/plugin.yml create mode 100644 target/DirtHead-1.0-SNAPSHOT.jar create mode 100644 target/classes/com/bitnix/dirthead/DirtHeadPlugin.class create mode 100644 target/classes/config.yml create mode 100644 target/classes/plugin.yml create mode 100644 target/maven-archiver/pom.properties create mode 100644 target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst create mode 100644 target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..8028c34 --- /dev/null +++ b/pom.xml @@ -0,0 +1,47 @@ + + 4.0.0 + + com.bitnix + DirtHead + 1.0-SNAPSHOT + jar + + DirtHead + Drops glowing player heads on PvP death with configurable particles. + + + UTF-8 + 21 + + + + + papermc-repo + https://repo.papermc.io/repository/maven-public/ + + + + + + io.papermc.paper + paper-api + 1.21.1-R0.1-SNAPSHOT + provided + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + 21 + + + + + diff --git a/src/main/java/com/bitnix/dirthead/DirtHeadPlugin.java b/src/main/java/com/bitnix/dirthead/DirtHeadPlugin.java new file mode 100644 index 0000000..362a40f --- /dev/null +++ b/src/main/java/com/bitnix/dirthead/DirtHeadPlugin.java @@ -0,0 +1,221 @@ +package com.bitnix.dirthead; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitTask; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; + +public class DirtHeadPlugin extends JavaPlugin implements Listener { + + private final Map particleTasks = new HashMap<>(); + private final LegacyComponentSerializer legacy = LegacyComponentSerializer.legacyAmpersand(); + + @Override + public void onEnable() { + saveDefaultConfig(); + getServer().getPluginManager().registerEvents(this, this); + Objects.requireNonNull(getCommand("dirthead")).setExecutor((sender, command, label, args) -> { + if (!sender.hasPermission("dirthead.admin")) { + sender.sendMessage(color(getConfig().getString("messages.prefix", "&8[&6DirtHead&8] ") + + getConfig().getString("messages.no-permission", "&cYou do not have permission."))); + return true; + } + + if (args.length == 1 && args[0].equalsIgnoreCase("reload")) { + reloadConfig(); + sender.sendMessage(color(getConfig().getString("messages.prefix", "&8[&6DirtHead&8] ") + + getConfig().getString("messages.reload", "&aConfig reloaded."))); + return true; + } + + sender.sendMessage(color(getConfig().getString("messages.prefix", "&8[&6DirtHead&8] ") + + getConfig().getString("messages.usage", "&eUse: /dirthead reload"))); + return true; + }); + } + + @Override + public void onDisable() { + for (BukkitTask task : particleTasks.values()) { + if (task != null) { + task.cancel(); + } + } + particleTasks.clear(); + } + + @EventHandler + public void onPlayerDeath(PlayerDeathEvent event) { + FileConfiguration config = getConfig(); + + if (!config.getBoolean("enabled", true)) { + return; + } + + if (!config.getBoolean("head.drop-on-pvp-death", true)) { + return; + } + + Player victim = event.getPlayer(); + Player killer = victim.getKiller(); + + if (killer == null) { + return; + } + + if (victim.hasPermission("dirthead.bypass")) { + return; + } + + if (config.getBoolean("head.op-bypass", false) && victim.isOp()) { + return; + } + + ItemStack head = createPlayerHead(victim, killer); + if (head == null) { + return; + } + + Location dropLocation = victim.getLocation().clone(); + Item dropped = victim.getWorld().dropItemNaturally(dropLocation, head); + + if (config.getBoolean("head.glowing.enabled", true)) { + dropped.setGlowing(true); + } + + dropped.setInvulnerable(config.getBoolean("head.invulnerable", true)); + dropped.setGravity(config.getBoolean("head.gravity", false)); + dropped.setPickupDelay(Math.max(0, config.getInt("head.pickup-delay-ticks", 40))); + + int despawnSeconds = Math.max(1, config.getInt("head.despawn-after-seconds", 120)); + getServer().getScheduler().runTaskLater(this, () -> { + if (dropped.isValid() && !dropped.isDead()) { + cancelParticleTask(dropped.getUniqueId()); + dropped.remove(); + } + }, despawnSeconds * 20L); + + startParticleTask(dropped); + + if (!config.getBoolean("head.keep-vanilla-drops", true)) { + event.getDrops().removeIf(item -> item.getType() == Material.PLAYER_HEAD); + } + } + + private ItemStack createPlayerHead(Player victim, Player killer) { + ItemStack item = new ItemStack(Material.PLAYER_HEAD); + ItemMeta rawMeta = item.getItemMeta(); + if (!(rawMeta instanceof SkullMeta meta)) { + return null; + } + + meta.setOwningPlayer(victim); + + String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + String displayName = getConfig().getString("head.name", "&6&l%player%'s Head") + .replace("%player%", victim.getName()) + .replace("%killer%", killer.getName()) + .replace("%time%", time); + + meta.displayName(color(displayName)); + + List loreLines = getConfig().getStringList("head.lore"); + if (!loreLines.isEmpty()) { + List lore = new ArrayList<>(); + for (String line : loreLines) { + lore.add(color(line + .replace("%player%", victim.getName()) + .replace("%killer%", killer.getName()) + .replace("%time%", time))); + } + meta.lore(lore); + } + + item.setItemMeta(meta); + return item; + } + + private void startParticleTask(Item dropped) { + FileConfiguration config = getConfig(); + + if (!config.getBoolean("particles.enabled", true)) { + return; + } + + Particle particle; + try { + particle = Particle.valueOf(config.getString("particles.particle", "DUST").toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException ex) { + getLogger().warning("Invalid particle in config. Falling back to DUST."); + particle = Particle.DUST; + } + + int interval = Math.max(1, config.getInt("particles.interval-ticks", 10)); + int count = Math.max(1, config.getInt("particles.count", 8)); + double offsetX = config.getDouble("particles.offset-x", 0.18); + double offsetY = config.getDouble("particles.offset-y", 0.25); + double offsetZ = config.getDouble("particles.offset-z", 0.18); + double extra = config.getDouble("particles.extra", 0.0); + + Particle finalParticle = particle; + + BukkitTask task = getServer().getScheduler().runTaskTimer(this, () -> { + if (!dropped.isValid() || dropped.isDead()) { + cancelParticleTask(dropped.getUniqueId()); + return; + } + + Location loc = dropped.getLocation().clone().add(0.0, 0.2, 0.0); + + if (finalParticle == Particle.DUST) { + int red = clampColor(getConfig().getInt("particles.color.red", 255)); + int green = clampColor(getConfig().getInt("particles.color.green", 215)); + int blue = clampColor(getConfig().getInt("particles.color.blue", 0)); + float size = (float) getConfig().getDouble("particles.color.size", 1.2); + + Particle.DustOptions dustOptions = new Particle.DustOptions( + Color.fromRGB(red, green, blue), + Math.max(0.1f, size) + ); + + dropped.getWorld().spawnParticle(finalParticle, loc, count, offsetX, offsetY, offsetZ, extra, dustOptions); + } else { + dropped.getWorld().spawnParticle(finalParticle, loc, count, offsetX, offsetY, offsetZ, extra); + } + }, 0L, interval); + + particleTasks.put(dropped.getUniqueId(), task); + } + + private void cancelParticleTask(UUID uuid) { + BukkitTask task = particleTasks.remove(uuid); + if (task != null) { + task.cancel(); + } + } + + private int clampColor(int value) { + return Math.max(0, Math.min(255, value)); + } + + private Component color(String text) { + return legacy.deserialize(text == null ? "" : text); + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..d8d0231 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,37 @@ +enabled: true + +head: + drop-on-pvp-death: true + keep-vanilla-drops: true + op-bypass: false + name: "&6&l%player%'s Head" + lore: + - "&7Killed by: &c%killer%" + - "&7Time: &e%time%" + glowing: + enabled: true + invulnerable: true + gravity: false + pickup-delay-ticks: 40 + despawn-after-seconds: 120 + +particles: + enabled: true + particle: "DUST" + count: 8 + offset-x: 0.18 + offset-y: 0.25 + offset-z: 0.18 + extra: 0.0 + interval-ticks: 10 + color: + red: 255 + green: 215 + blue: 0 + size: 1.2 + +messages: + prefix: "&8[&6DirtHead&8] " + reload: "&aConfig reloaded." + no-permission: "&cYou do not have permission." + usage: "&eUse: /dirthead reload" diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..c97409c --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,18 @@ +name: DirtHead +version: 1.0-SNAPSHOT +main: com.bitnix.dirthead.DirtHeadPlugin +api-version: '1.21' +author: bitnix +description: Drops glowing player heads on PvP death with configurable particles. +commands: + dirthead: + description: Reload DirtHead config + usage: /dirthead reload + permission: dirthead.admin +permissions: + dirthead.admin: + description: Allows reloading the DirtHead config + default: op + dirthead.bypass: + description: Prevents your head from dropping on PvP death + default: false diff --git a/target/DirtHead-1.0-SNAPSHOT.jar b/target/DirtHead-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..527f0f55b2e103be27f99455dbd6ede03e8cb923 GIT binary patch literal 9014 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 Mhk+@i`uXku0i+YHasU7T literal 0 HcmV?d00001 diff --git a/target/classes/com/bitnix/dirthead/DirtHeadPlugin.class b/target/classes/com/bitnix/dirthead/DirtHeadPlugin.class new file mode 100644 index 0000000000000000000000000000000000000000..b9943906f87757107ee033d186ceb02ec441209c GIT binary patch literal 12794 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