Today I was thinking of what to work on, and thought of this! I had an older version, that was pretty much broken. This version works 10x better. If you guys want to use the code, feel free too! Please just give me credit. Also if you want to use the code, put Leaves.spawnLeaves(); in your onEnable :D P.S. Sorry for the spaghetti code. Its an old project. I touched it up a bit, but mainly worked on fixing bugs.
Video Showcase (reuploaded for better quality):
Code:
package me.extendedhorizons.kitverse.cosmetics;
import me.extendedhorizons.kitverse.Main;
import me.extendedhorizons.kitverse.util.BlockUtil;
import net.minecraft.server.v1_8_R3.*;
import org.bukkit.*;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
@SuppressWarnings("unused")
public class Leaves {
static HashMap<ArmorStand, Double> stands = new HashMap<>();
public static void fixExistingleaves() {
new BukkitRunnable() {
@Override
public void run() {
for (ArmorStand stand : stands.keySet()) {
if (stand.getLocation().getBlock().getType().equals(Material.AIR) || stand.getLocation().getBlock().getType().equals(Material.WATER)) {
stand.setGravity(true);
}
if (stand.getLocation().getY() != stands.get(stand)) {
fancyFall(stand);
}
}
}
}.runTaskTimer(Main.getPlugin(), 1, 10);
}
public static void leaf(Location loc) {
World w = loc.getWorld();
ItemStack stack = new ItemStack(Material.LEAVES, 1);
Location centerLoc = BlockUtil.getCenterLoc(loc);
ArmorStand block = (ArmorStand) w.spawnEntity(centerLoc, EntityType.ARMOR_STAND);
block.setSmall(true);
block.setGravity(true);
block.setVisible(false);
if (!block.isOnGround()) {
fancyFall(block);
}
for (Player allPlayers : Bukkit.getServer().getOnlinePlayers()) {
CraftPlayer allP = (CraftPlayer) allPlayers;
PacketPlayOutEntityEquipment equip = new PacketPlayOutEntityEquipment(block.getEntityId(), 4, CraftItemStack.asNMSCopy(stack));
allP.getHandle().playerConnection.sendPacket(equip);
PlayerConnection connection = allP.getHandle().playerConnection;
}
}
//Main.getPlugin().getLogger().info("Spawned Leaf At: " + centerLoc);
public static void fancyFall(ArmorStand stand) {
World w = stand.getWorld();
new BukkitRunnable() {
public void run() {
double spin = (double) Math.round(Math.random() * 6);
spin = spin / 100;
if (!stand.isOnGround()) {
stand.setVelocity(new Vector(0, -0.06, 0));
stand.setHeadPose(stand.getHeadPose().add(0, -spin, 0));
} else {
stand.setVelocity(new Vector(0, 0, 0));
lower(stand, spin);
this.cancel();
}
}
}.runTaskTimer(Main.getPlugin(), 1, 1);
}
public static void lower(ArmorStand stand, double spin) {
Location loc = stand.getLocation();
new BukkitRunnable() {
int count = 0;
@Override
public void run() {
if (count <= 8) {
stand.teleport(loc.clone().add(0, -0.05, 0));
stand.setHeadPose(stand.getHeadPose().add(0, -spin, 0));
count++;
} else {
Location loc = stand.getLocation().clone().add(0, 1.75, 0);
Random random = new Random();
int randomInt1 = random.nextInt(1);
int randomInt2 = random.nextInt(1);
int lifeSpan = random.nextInt(25);
IBlockData iblockdata = net.minecraft.server.v1_8_R3.Block.getByCombinedId(18);
net.minecraft.server.v1_8_R3.Block block1 = iblockdata.getBlock();
PacketPlayOutWorldParticles packet = new PacketPlayOutWorldParticles(EnumParticle.BLOCK_DUST, false, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), randomInt1, 0, randomInt2, 0, 5, net.minecraft.server.v1_8_R3.Block.getCombinedId(iblockdata));
for (Player players : Bukkit.getOnlinePlayers()) {
PlayerConnection playerConnection = ((CraftPlayer)players).getHandle().playerConnection;
playerConnection.sendPacket(packet);
new BukkitRunnable() {
@Override
public void run() {
playerConnection.sendPacket(new PacketPlayOutEntityDestroy(stand.getEntityId()));
}
}.runTaskLater(Main.getPlugin(), 20 * lifeSpan);
}
stand.setGravity(false);
stands.put(stand, stand.getLocation().getY());
this.cancel();
}
}
}.runTaskTimer(Main.getPlugin(), 1, 1);
}
public static List<Chunk> getSurroundingChunks(Location loc, int radius) {
List<Chunk> chunks = new ArrayList<>();
for (int x = (loc.getChunk().getX() - radius); x <= (loc.getChunk().getX() + radius); x++) {
for (int z = (loc.getChunk().getZ() - radius); z <= (loc.getChunk().getZ() + radius); z++) {
chunks.add(loc.getWorld().getChunkAt(x, z));
}
}
return chunks;
}
public static void spawnLeaves() {
Random random = new Random();
World world = Bukkit.getServer().getWorld("world");
fixExistingleaves();
new BukkitRunnable() {
@Override
public void run() {
ArrayList<Block> blocks = new ArrayList<>();
blocks.clear();
blocks = getPossibleBlocks(world);
int playerAmount = Bukkit.getOnlinePlayers().toArray().length * 2;
if (blocks != null && blocks.size() > 0) {
for (int i = 0; i < playerAmount; i++) {
int index = random.nextInt(blocks.size());
Block block = blocks.get(index);
leaf(block.getLocation());
}
}
}
}.runTaskTimer(Main.getPlugin(), 1, 10 * 20);
}
public static ArrayList<Block> getPossibleBlocks(World world) {
ArrayList<Block> blocks = new ArrayList<>();
blocks.clear();
for (Player player : Bukkit.getOnlinePlayers()) {
player.getLocation().getChunk().load();
for (Chunk chunk : getSurroundingChunks(player.getLocation(), 1)) {
int bx = chunk.getX() << 4;
int bz = chunk.getZ() << 4;
for (int xx = bx; xx < bx + 32; xx++) {
for (int zz = bz; zz < bz + 32; zz++) {
for (int yy = 0; yy < 48; yy++) {
Block b = world.getBlockAt(xx, yy, zz);
Location loc1 = b.getLocation();
if (b.getType().equals(Material.LEAVES) && b.getLocation().clone().add(0, -1, 0).getBlock().getType().equals(Material.AIR) && isLowestLeafBlock(b)) {
if (!blocks.contains(b)) {
blocks.add(b);
}
}
}
}
}
}
}
return blocks;
}
public static boolean isLowestLeafBlock(Block block) {
Location location = block.getLocation();
for (int i = block.getLocation().getBlockY(); i > 0; i--) {
location.add(0, -1, 0);
if (location.getBlock().getType().equals(Material.LEAVES)) {
return false;
}
}
return true;
}
}
Video Showcase (reuploaded for better quality):
Last edited: