Initial commit: Folia compatibility and cleanup
This commit is contained in:
commit
ec4329fcc1
8 changed files with 271 additions and 0 deletions
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
target/
|
||||||
|
plans/
|
||||||
|
*.class
|
||||||
|
*.jar
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
.DS_Store
|
||||||
7
README.md
Normal file
7
README.md
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
# EzBoner
|
||||||
|
this is really fucking hard to explain,
|
||||||
|
when you use bonemeal, it affects all nearby crops (up to 32) using the proper amount of bonemeal, super duper fast and easy
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- Supports foila!
|
||||||
|
- **Connected Growth**: Look upwards
|
||||||
68
pom.xml
Normal file
68
pom.xml
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
<?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://www.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>boner</groupId>
|
||||||
|
<artifactId>EzBoner</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
|
||||||
|
<name>EzBoner</name>
|
||||||
|
<url>https://coldfiles.dev/</url>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>papermc</id>
|
||||||
|
<url>https://repo.papermc.io/repository/maven-public/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>dev.folia</groupId>
|
||||||
|
<artifactId>folia-api</artifactId>
|
||||||
|
<version>1.20.1-R0.1-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>${project.basedir}/src/main/resources</directory>
|
||||||
|
<includes>
|
||||||
|
<include>plugin.yml</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>run</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<target>
|
||||||
|
<copy file="${project.build.directory}/${project.build.finalName}.jar"
|
||||||
|
todir="/home/bunchy7s/programs/mcplugins/"/>
|
||||||
|
</target>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
26
src/main/java/boner/EzBoner.java
Normal file
26
src/main/java/boner/EzBoner.java
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
package boner;
|
||||||
|
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import boner.managers.PluginManager;
|
||||||
|
import boner.listeners.PlayerListener;
|
||||||
|
|
||||||
|
public class EzBoner extends JavaPlugin {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
|
||||||
|
// Initialize managers
|
||||||
|
PluginManager.getInstance().initialize();
|
||||||
|
|
||||||
|
// Register listeners
|
||||||
|
getServer().getPluginManager().registerEvents(new PlayerListener(), this);
|
||||||
|
|
||||||
|
getLogger().info("EzBoner has been enabled!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
getLogger().info("EzBoner has been disabled!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
74
src/main/java/boner/listeners/PlayerListener.java
Normal file
74
src/main/java/boner/listeners/PlayerListener.java
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
package boner.listeners;
|
||||||
|
|
||||||
|
import boner.EzBoner;
|
||||||
|
import boner.utils.Utils;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.data.Ageable;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PlayerListener implements Listener {
|
||||||
|
|
||||||
|
private final EzBoner plugin = JavaPlugin.getPlugin(EzBoner.class);
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||||
|
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
|
||||||
|
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
if (!player.isSneaking()) return;
|
||||||
|
|
||||||
|
ItemStack item = event.getItem();
|
||||||
|
if (item == null || item.getType() != Material.BONE_MEAL) return;
|
||||||
|
|
||||||
|
Block clickedBlock = event.getClickedBlock();
|
||||||
|
if (clickedBlock == null || !Utils.isBonemealable(clickedBlock)) return;
|
||||||
|
|
||||||
|
// Cancel the original event to handle it ourselves
|
||||||
|
event.setCancelled(true);
|
||||||
|
|
||||||
|
// Find connected crops (limit 32)
|
||||||
|
List<Block> targets = Utils.findConnectedCrops(clickedBlock, 32);
|
||||||
|
if (targets.isEmpty()) return;
|
||||||
|
|
||||||
|
// Folia-safe execution on the region of the clicked block
|
||||||
|
org.bukkit.Bukkit.getRegionScheduler().execute(plugin, clickedBlock.getLocation(), () -> {
|
||||||
|
int appliedCount = 0;
|
||||||
|
for (Block target : targets) {
|
||||||
|
if (Utils.isBonemealable(target)) {
|
||||||
|
// Apply bonemeal effect
|
||||||
|
if (target.getBlockData() instanceof Ageable ageable) {
|
||||||
|
ageable.setAge(ageable.getMaximumAge());
|
||||||
|
target.setBlockData(ageable);
|
||||||
|
} else {
|
||||||
|
// Fallback for saplings or other non-ageable but bonemealable blocks
|
||||||
|
target.applyBoneMeal(org.bukkit.block.BlockFace.UP);
|
||||||
|
}
|
||||||
|
|
||||||
|
appliedCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (appliedCount > 0) {
|
||||||
|
// Consume items from player
|
||||||
|
final int finalAppliedCount = appliedCount;
|
||||||
|
player.getScheduler().execute(plugin, () -> {
|
||||||
|
ItemStack handItem = player.getInventory().getItem(event.getHand());
|
||||||
|
if (handItem != null && handItem.getType() == Material.BONE_MEAL) {
|
||||||
|
handItem.setAmount(Math.max(0, handItem.getAmount() - finalAppliedCount));
|
||||||
|
}
|
||||||
|
}, null, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/main/java/boner/managers/PluginManager.java
Normal file
16
src/main/java/boner/managers/PluginManager.java
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
package boner.managers;
|
||||||
|
|
||||||
|
public class PluginManager {
|
||||||
|
private static PluginManager instance;
|
||||||
|
|
||||||
|
public static PluginManager getInstance() {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new PluginManager();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initialize() {
|
||||||
|
// Initialize your managers here
|
||||||
|
}
|
||||||
|
}
|
||||||
66
src/main/java/boner/utils/Utils.java
Normal file
66
src/main/java/boner/utils/Utils.java
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
package boner.utils;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.data.Ageable;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class Utils {
|
||||||
|
|
||||||
|
public static Component colorize(String msg) {
|
||||||
|
if (msg.contains("<") && msg.contains(">")) {
|
||||||
|
return MiniMessage.miniMessage().deserialize(msg);
|
||||||
|
}
|
||||||
|
return LegacyComponentSerializer.legacyAmpersand().deserialize(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String legacyColorize(String msg) {
|
||||||
|
return LegacyComponentSerializer.legacyAmpersand().serialize(
|
||||||
|
LegacyComponentSerializer.legacyAmpersand().deserialize(msg)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isBonemealable(Block block) {
|
||||||
|
BlockData data = block.getBlockData();
|
||||||
|
if (data instanceof Ageable ageable) {
|
||||||
|
return ageable.getAge() < ageable.getMaximumAge();
|
||||||
|
}
|
||||||
|
// Support for saplings which might not be Ageable in some versions but are bonemealable
|
||||||
|
return block.getType().name().contains("SAPLING");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Block> findConnectedCrops(Block start, int limit) {
|
||||||
|
List<Block> found = new ArrayList<>();
|
||||||
|
Queue<Block> queue = new LinkedList<>();
|
||||||
|
Set<Block> visited = new HashSet<>();
|
||||||
|
|
||||||
|
if (isBonemealable(start)) {
|
||||||
|
queue.add(start);
|
||||||
|
visited.add(start);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!queue.isEmpty() && found.size() < limit) {
|
||||||
|
Block current = queue.poll();
|
||||||
|
found.add(current);
|
||||||
|
|
||||||
|
for (int x = -1; x <= 1; x++) {
|
||||||
|
for (int z = -1; z <= 1; z++) {
|
||||||
|
if (x == 0 && z == 0) continue;
|
||||||
|
|
||||||
|
Block neighbor = current.getRelative(x, 0, z);
|
||||||
|
if (!visited.contains(neighbor) && isBonemealable(neighbor)) {
|
||||||
|
visited.add(neighbor);
|
||||||
|
queue.add(neighbor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/main/resources/plugin.yml
Normal file
6
src/main/resources/plugin.yml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
main: boner.EzBoner
|
||||||
|
version: 1.0
|
||||||
|
name: EzBoner
|
||||||
|
author: bunchy7s
|
||||||
|
api-version: 1.21
|
||||||
|
folia-supported: true
|
||||||
Loading…
Add table
Reference in a new issue