update 5.29

master
sky 2020-05-17 21:48:41 +08:00
parent 64f7dd2817
commit c674361e12
7 changed files with 782 additions and 335 deletions

View File

@ -20,9 +20,11 @@ import io.izzel.taboolib.module.tellraw.TellrawJson;
import io.izzel.taboolib.util.Files;
import io.izzel.taboolib.util.book.BookFormatter;
import io.izzel.taboolib.util.item.Items;
import io.izzel.taboolib.util.lite.Effects;
import io.izzel.taboolib.util.lite.Signs;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
@ -31,10 +33,13 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.server.ServerCommandEvent;
import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.util.NumberConversions;
import org.bukkit.util.Vector;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
/**
@ -51,7 +56,7 @@ public class ListenerCommand implements Listener {
abstract public String[] name();
abstract public void run(Player player);
abstract public void run(Player player, String[] args);
}
List<Module> testUtil = Lists.newArrayList(
@ -62,7 +67,7 @@ public class ListenerCommand implements Listener {
}
@Override
public void run(Player player) {
public void run(Player player, String[] args) {
TellrawJson.create()
.append("§8[§fTabooLib§8] §7TellrawJson: §f[")
.append(Items.getName(player.getItemInHand())).hoverItem(player.getItemInHand())
@ -77,7 +82,7 @@ public class ListenerCommand implements Listener {
}
@Override
public void run(Player player) {
public void run(Player player, String[] args) {
Signs.fakeSign(player, lines -> player.sendMessage("§8[§fTabooLib§8] §7FakeSign: §f" + Arrays.toString(lines)));
}
},
@ -88,7 +93,7 @@ public class ListenerCommand implements Listener {
}
@Override
public void run(Player player) {
public void run(Player player, String[] args) {
player.sendMessage("§8[§fTabooLib§8] §7Hologram.");
Location location = player.getEyeLocation().add(player.getLocation().getDirection());
Hologram hologram = THologram.create(location, "TabooLib", player)
@ -119,7 +124,7 @@ public class ListenerCommand implements Listener {
}
@Override
public void run(Player player) {
public void run(Player player, String[] args) {
BookFormatter.writtenBook()
.generation(BookMeta.Generation.COPY_OF_COPY)
.addPage(TellrawJson.create()
@ -135,7 +140,7 @@ public class ListenerCommand implements Listener {
}
@Override
public void run(Player player) {
public void run(Player player, String[] args) {
player.sendMessage("§8[§fTabooLib§8] §7Lighting. §a(+)");
TLight.create(player.getLocation().getBlock(), Type.BLOCK, 15);
TabooLib.getPlugin().runTask(() -> {
@ -155,7 +160,7 @@ public class ListenerCommand implements Listener {
}
@Override
public void run(Player player) {
public void run(Player player, String[] args) {
player.sendMessage("§8[§fTabooLib§8] §7SimpleAI.");
Skeleton skeleton = player.getWorld().spawn(player.getLocation(), Skeleton.class, c -> {
c.setCustomName("Fearless Skeleton");
@ -179,7 +184,7 @@ public class ListenerCommand implements Listener {
}
@Override
public void run(Player player) {
public void run(Player player, String[] args) {
TellrawJson.create().append("§8[§fTabooLib§8] §7LocalPlayer: ").append("§c[...]").hoverText(LocalPlayer.get(player).saveToString()).send(player);
long time = System.currentTimeMillis();
FileConfiguration conf = LocalPlayer.get0(player);
@ -188,6 +193,135 @@ public class ListenerCommand implements Listener {
LocalPlayer.set0(player, conf);
player.sendMessage("§8[§fTabooLib§8] §7set: " + (System.currentTimeMillis() - time) + "ms");
}
},
new Module() {
@Override
public String[] name() {
return new String[] {"effects", "effect"};
}
@Override
public void run(Player player, String[] args) {
if (args.length < 2) {
player.sendMessage("§8[§fTabooLib§8] §7Effects:");
player.sendMessage("§8[§fTabooLib§8] §7-§f LINE-[interval]");
player.sendMessage("§8[§fTabooLib§8] §7-§f POLYGON-[radius]-[interval]");
player.sendMessage("§8[§fTabooLib§8] §7-§f CIRCLE-[radius]-[rate]");
player.sendMessage("§8[§fTabooLib§8] §7-§f CONE-[height]-[radius]-[rate]-[circle rate]");
player.sendMessage("§8[§fTabooLib§8] §7-§f ATOM-[orbits]-[radius]-[rate]");
player.sendMessage("§8[§fTabooLib§8] §7-§f ELLIPSE-[radius]-[other radius]-[rate]");
player.sendMessage("§8[§fTabooLib§8] §7-§f INFINITY-[radius]-[rate]");
player.sendMessage("§8[§fTabooLib§8] §7-§f CRESCENT-[radius]-[rate]");
player.sendMessage("§8[§fTabooLib§8] §7-§f WARE_FUNCTION-[extend]-[height range]");
player.sendMessage("§8[§fTabooLib§8] §7-§f CYLINDER-[height]-[radius]-[rate]-[interval]");
player.sendMessage("§8[§fTabooLib§8] §7-§f SPHERE-[radius]-[rate]");
player.sendMessage("§8[§fTabooLib§8] §7-§f SPHERE_SPIKE-[radius]-[rate]-[chance]-[min]-[max]-[interval]");
player.sendMessage("§8[§fTabooLib§8] §7-§f RING-[rate]-[tube rate]-[radius]-[tube radius]");
TellrawJson.create().append("§8[§fTabooLib§8] §7-§f LIGHTING-").append("§c[...]").hoverText("[rate]-[direction]-[entries]-[branches]-[radius]-[offset]-[offset rate]-[length]-[length rate]-[branch]-[branch rate]").send(player);
player.sendMessage("§8[§fTabooLib§8] §7-§f DNA-[radius]-[rate]-[extension]-[height]-[hydrogen bond dist]");
player.sendMessage("§8[§fTabooLib§8] §7-§f RECTANGLE-[rate]");
player.sendMessage("§8[§fTabooLib§8] §7-§f CAGE-[rate]-[bar rate]");
player.sendMessage("§8[§fTabooLib§8] §7-§f CUBE-[rate]");
player.sendMessage("§8[§fTabooLib§8] §7-§f CUBE_FILLED-[rate]");
player.sendMessage("§8[§fTabooLib§8] §7-§f CUBE_STRUCTURED-[rate]");
player.sendMessage("§8[§fTabooLib§8] §7-§f HYPERCUBE-[rate]-[size rate]-[cubes]");
return;
}
List<String> a = Lists.newArrayList(args[1].toUpperCase().split("-"));
Location locA = player.getEyeLocation();
Location locB = player.getEyeLocation().add(player.getLocation().getDirection().multiply(10)).add(Vector.getRandom().multiply(5));
Consumer<Location> action1 = loc -> Effects.create(Particle.FLAME, loc).count(1).player(player).play();
Consumer<Location> action2 = loc -> Effects.create(Particle.VILLAGER_HAPPY, loc).count(1).player(player).play();
switch (a.get(0)) {
case "LINE": {
Effects.buildLine(locA, locB, action1, orDob(a, 1, 0.1));
break;
}
case "POLYGON": {
Effects.buildPolygon(locA, orDob(a, 1, 10D), orDob(a, 2, 10D), action1);
break;
}
case "CIRCLE": {
Effects.buildCircle(locA, orDob(a, 1, 10D), orDob(a, 2, 10D), action1);
break;
}
case "CONE": {
Effects.buildCone(locA, orDob(a, 1, 10D), orDob(a, 2, 10D), orDob(a, 3, 10D), orDob(a, 4, 10D), action1);
break;
}
case "ATOM": {
Effects.buildAtom(locA, orInt(a, 1, 10), orDob(a, 2, 10D), orDob(a, 3, 10D), action1, action2);
break;
}
case "ELLIPSE": {
Effects.buildEllipse(locA, orDob(a, 1, 10D), orDob(a, 2, 10D), orDob(a, 3, 10D), action1);
break;
}
case "INFINITY": {
Effects.buildInfinity(locA, orDob(a, 1, 10D), orDob(a, 2, 10D), action1);
break;
}
case "CRESCENT": {
Effects.buildCrescent(locA, orDob(a, 1, 10D), orDob(a, 2, 10D), action1);
break;
}
case "WARE_FUNCTION": {
Effects.buildWaveFunction(locA, orDob(a, 1, 10D), orDob(a, 2, 10D), orDob(a, 3, 10D), orDob(a, 4, 10D), action1);
break;
}
case "CYLINDER": {
Effects.buildCylinder(locA, orDob(a, 1, 10D), orDob(a, 2, 10D), orDob(a, 3, 10D), orDob(a, 4, 10D), action1);
break;
}
case "SPHERE": {
Effects.buildSphere(locA, orDob(a, 1, 10D), orDob(a, 2, 10D), action1);
break;
}
case "SPHERE_SPIKE": {
Effects.buildSphereSpike(locA, orDob(a, 1, 10D), orDob(a, 2, 10D), orInt(a, 3, 10), orDob(a, 4, 10D), orDob(a, 5, 10D), orDob(a, 6, 10D), action1);
break;
}
case "RING": {
Effects.buildRing(locA, orDob(a, 1, 10D), orDob(a, 2, 10D), orDob(a, 3, 10D), orDob(a, 4, 10D), action1);
break;
}
case "LIGHTING": {
Effects.buildLightning(locA, locA.getDirection(), orInt(a, 1, 10), orInt(a, 2, 10), orDob(a, 3, 10), orDob(a, 4, 10D), orDob(a, 5, 10D), orDob(a, 6, 10D), orDob(a, 7, 10D), orDob(a, 8, 10D), orDob(a, 9, 10D), action1);
break;
}
case "DNA": {
Effects.buildDNA(locA, orDob(a, 1, 10D), orDob(a, 2, 10D), orDob(a, 3, 10D), orInt(a, 4, 10), orInt(a, 5, 10), action1, action2);
break;
}
case "RECTANGLE": {
Effects.buildRectangle(locA, locB, orDob(a, 1, 10D), action1);
break;
}
case "CAGE": {
Effects.buildCage(locA, locB, orDob(a, 1, 10D), orDob(a, 2, 10D), action1);
break;
}
case "CUBE": {
Effects.buildCube(locA, locB, orDob(a, 1, 10D), action1);
break;
}
case "CUBE_FILLED": {
Effects.buildCubeFilled(locA, locB, orDob(a, 1, 10D), action1);
break;
}
case "CUBE_STRUCTURED": {
Effects.buildCubeStructured(locA, locB, orDob(a, 1, 10D), action1);
break;
}
case "HYPERCUBE": {
Effects.buildHypercube(locA, locB, orDob(a, 1, 10D), orDob(a, 2, 10D), orInt(a, 3, 10), action1);
break;
}
default:
player.sendMessage("§8[§fTabooLib§8] §7No Effect.");
break;
}
}
});
@ -213,11 +347,12 @@ public class ListenerCommand implements Listener {
for (Module module : testUtil) {
for (String name : module.name()) {
if (name.equalsIgnoreCase(args[0])) {
module.run((Player) sender);
module.run((Player) sender, args);
return;
}
}
}
sender.sendMessage("§8[§fTabooLib§8] §7Test: §f" + testUtil.stream().map(i -> i.name()[0]).collect(Collectors.joining(", ")));
}
}).build();
}
@ -251,4 +386,12 @@ public class ListenerCommand implements Listener {
Bukkit.shutdown();
}
}
private static int orInt(List<String> list, int index, int def) {
return list.size() > index ? NumberConversions.toInt(list.get(index)) : def;
}
private static double orDob(List<String> list, int index, double def) {
return list.size() > index ? NumberConversions.toDouble(list.get(index)) : def;
}
}

View File

@ -65,6 +65,7 @@ import java.util.function.Consumer;
public class NMSImpl extends NMS {
private Field entityTypesField;
private final boolean is11300 = Version.isAfter(Version.v1_13);
private final boolean is11400 = Version.isAfter(Version.v1_14);
private final boolean is11500 = Version.isAfter(Version.v1_15);
@ -116,7 +117,11 @@ public class NMSImpl extends NMS {
@Override
public Object toPacketPlayOutWorldParticles(Particle var1, boolean var2, float var3, float var4, float var5, float var6, float var7, float var8, float var9, int var10, Object var11) {
return new net.minecraft.server.v1_12_R1.PacketPlayOutWorldParticles(CraftParticle.toNMS(var1), var2, var3, var4, var5, var6, var7, var8, var9, var10, CraftParticle.toData(var1, var11));
if (is11300) {
return new net.minecraft.server.v1_13_R2.PacketPlayOutWorldParticles(org.bukkit.craftbukkit.v1_13_R2.CraftParticle.toNMS(var1, var11), var2, var3, var4, var5, var6, var7, var8, var9, var10);
} else {
return new net.minecraft.server.v1_12_R1.PacketPlayOutWorldParticles(CraftParticle.toNMS(var1), var2, var3, var4, var5, var6, var7, var8, var9, var10, CraftParticle.toData(var1, var11));
}
}
@Override

View File

@ -1,5 +1,6 @@
package io.izzel.taboolib.util.item;
import com.google.common.base.Enums;
import com.google.common.collect.ImmutableMap;
import com.google.gson.*;
import io.izzel.taboolib.Version;
@ -75,7 +76,7 @@ public class Items {
public static Material asMaterial(String args) {
try {
Material material = Material.getMaterial(args.toUpperCase());
return material != null ? material : Material.getMaterial(Integer.parseInt(args));
return material != null ? material : Material.getMaterial(NumberConversions.toInt(args));
} catch (Exception e) {
return Material.STONE;
}
@ -84,24 +85,16 @@ public class Items {
public static Color asColor(String color) {
try {
String[] v = color.split("-");
return Color.fromBGR(Integer.parseInt(v[0]), Integer.parseInt(v[1]), Integer.parseInt(v[2]));
return Color.fromRGB(NumberConversions.toInt(v[0]), NumberConversions.toInt(v[1]), NumberConversions.toInt(v[2]));
} catch (Exception e) {
return Color.fromBGR(0, 0, 0);
}
}
public static ItemFlag asItemFlag(String flag) {
try {
return ItemFlag.valueOf(flag);
} catch (Exception e) {
return null;
return Color.fromRGB(0, 0, 0);
}
}
public static Enchantment asEnchantment(String enchant) {
try {
Enchantment enchantment = Enchantment.getByName(enchant);
return enchantment != null ? enchantment : Enchantment.getById(Integer.parseInt(enchant));
return enchantment != null ? enchantment : Enchantment.getById(NumberConversions.toInt(enchant));
} catch (Exception e) {
return null;
}
@ -110,12 +103,16 @@ public class Items {
public static PotionEffectType asPotionEffectType(String potion) {
try {
PotionEffectType type = PotionEffectType.getByName(potion);
return type != null ? type : PotionEffectType.getById(Integer.parseInt(potion));
return type != null ? type : PotionEffectType.getById(NumberConversions.toInt(potion));
} catch (Exception e) {
return null;
}
}
public static ItemFlag asItemFlag(String flag) {
return Enums.getIfPresent(ItemFlag.class, flag).orNull();
}
public static String asAttribute(String name) {
return Attribute.parse(name).getMinecraftKey();
}

View File

@ -1,29 +1,34 @@
package io.izzel.taboolib.util.lite;
import com.google.common.base.Enums;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import io.izzel.taboolib.TabooLib;
import io.izzel.taboolib.util.ArrayUtil;
import io.izzel.taboolib.util.Reflection;
import io.izzel.taboolib.util.TMap;
import io.izzel.taboolib.util.item.Items;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
import org.bukkit.util.NumberConversions;
import org.bukkit.util.Vector;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.Consumer;
/**
* @Author sky
* @Since 2019-10-06 1:02
* <p>
*
* CryptoMorin XSeries
*/
public class Effects {
@ -36,10 +41,26 @@ public class Effects {
private List<Player> player = Lists.newArrayList();
private Object data;
public static Particle parseParticle(String in) {
return Enums.getIfPresent(Particle.class, in).or(Particle.FLAME);
}
public static Effects create(Particle particle, Location center) {
return new Effects(particle, center);
}
public static Effects create(Particle particle, Location center, double offsetX, double offsetY, double offsetZ) {
return new Effects(particle, center).offset(new double[] {offsetX, offsetY, offsetZ});
}
public static Effects create(Particle particle, Location center, double offsetX, double offsetY, double offsetZ, double speed) {
return new Effects(particle, center).offset(new double[] {offsetX, offsetY, offsetZ}).speed(speed);
}
public static Effects create(Particle particle, Location center, double offsetX, double offsetY, double offsetZ, double speed, int count) {
return new Effects(particle, center).offset(new double[] {offsetX, offsetY, offsetZ}).speed(speed).count(count);
}
public static Effects parse(String in) {
TMap map = TMap.parse(in);
Effects effects = Effects.create(parseParticle(map.getName()), null);
@ -80,14 +101,6 @@ public class Effects {
return effects;
}
public static Particle parseParticle(String in) {
try {
return Particle.valueOf(in.toUpperCase());
} catch (Throwable ignored) {
}
return Particle.FLAME;
}
public static void buildLine(Location locA, Location locB, Consumer<Location> action) {
buildLine(locA, locB, action, 0.25);
}
@ -101,15 +114,367 @@ public class Effects {
}
}
public static void buildPolygon(Location center, double range, double interval, Consumer<Location> action) {
public static void buildPolygon(Location center, double radius, double interval, Consumer<Location> action) {
for (double i = 0; i < 360; i += interval) {
double radians = Math.toRadians(i);
double cos = Math.cos(radians) * range;
double sin = Math.sin(radians) * range;
double cos = Math.cos(radians) * radius;
double sin = Math.sin(radians) * radius;
action.accept(center.clone().add(cos, 0, sin));
}
}
public static void buildCircle(Location center, double radius, double rate, Consumer<Location> action) {
double pii = Math.PI * 2;
double rateDiv = Math.PI / rate;
for (double theta = 0; theta <= pii; theta += rateDiv) {
double x = radius * Math.cos(theta);
double z = radius * Math.sin(theta);
action.accept(center.clone().add(x, 0, z));
}
}
public static void buildCone(Location center, double height, double radius, double rate, double circleRate, Consumer<Location> action) {
double radiusDiv = radius / (height / rate);
for (double i = 0; i < height; i += rate) {
radius -= radiusDiv;
buildCircle(center.clone().add(0, i, 0), Math.max(radius, 0), circleRate - i, action);
}
}
public static void buildAtom(Location center, int orbits, double radius, double rate, Consumer<Location> orbit, Consumer<Location> nucleus) {
double dist = Math.PI / orbits;
for (double angle = 0; orbits > 0; angle += dist) {
buildCircle(center, radius, rate, orbit);
orbits--;
}
buildSphere(center, radius / 3, rate / 2, nucleus);
}
public static void buildEllipse(Location center, double radius, double otherRadius, double rate, Consumer<Location> action) {
double pii = Math.PI * 2;
double rateDiv = Math.PI / rate;
for (double theta = 0; theta <= pii; theta += rateDiv) {
double x = radius * Math.cos(theta);
double y = otherRadius * Math.sin(theta);
action.accept(center.clone().add(x, y, 0));
}
}
public static void buildInfinity(Location center, double radius, double rate, Consumer<Location> action) {
double pii = Math.PI * 2;
double rateDiv = Math.PI / rate;
for (double i = 0; i < pii; i += rateDiv) {
double x = Math.sin(i);
double smooth = Math.pow(x, 2) + 1;
double curve = radius * Math.cos(i);
double z = curve / smooth;
double y = (curve * x) / smooth;
buildCircle(center.clone().add(x, y, z), 1, rate, action);
}
}
public static void buildCrescent(Location center, double radius, double rate, Consumer<Location> action) {
double rateDiv = Math.PI / rate;
for (double theta = Math.toRadians(45); theta <= Math.toRadians(325); theta += rateDiv) {
double x = Math.cos(theta);
double z = Math.sin(theta);
action.accept(center.clone().add(radius * x, 0, radius * z));
double smallerRadius = radius / 1.3;
action.accept(center.clone().add(smallerRadius * x + 0.8, 0, smallerRadius * z));
}
}
public static void buildWaveFunction(Location center, double extend, double heightRange, double size, double rate, Consumer<Location> action) {
double pii = Math.PI * 2;
double height = heightRange / 2;
boolean increase = true;
double increaseRandomizer = Numbers.getRandomDouble(heightRange / 2, heightRange);
double rateDiv = Math.PI / rate;
size *= pii;
for (double x = 0; x <= size; x += rateDiv) {
double xx = extend * x;
double y1 = Math.sin(x);
if (y1 == 1) {
increase = !increase;
if (increase) {
increaseRandomizer = Numbers.getRandomDouble(heightRange / 2, heightRange);
} else {
increaseRandomizer = Numbers.getRandomDouble(-heightRange, -heightRange / 2);
}
}
height += increaseRandomizer;
for (double z = 0; z <= size; z += rateDiv) {
double y2 = Math.cos(z);
double yy = height * y1 * y2;
double zz = extend * z;
action.accept(center.clone().add(xx, yy, zz));
}
}
}
public static void buildCylinder(Location center, double height, double radius, double rate, double interval, Consumer<Location> action) {
double rateDiv = Math.PI / rate;
for (double theta = 0; theta <= Math.PI; theta += rateDiv) {
double x = radius * Math.cos(theta);
double z = radius * Math.sin(theta);
action.accept(center.clone().add(x, 0, z));
action.accept(center.clone().add(-x, 0, -z));
action.accept(center.clone().add(x, height, z));
action.accept(center.clone().add(-x, height, -z));
Location point1 = center.clone().add(x, 0, z);
Location point2 = center.clone().add(-x, 0, -z);
buildLine(point1, point2, action, interval);
Location point21 = center.clone().add(x, height, z);
Location point22 = center.clone().add(-x, height, -z);
buildLine(point21, point22, action, interval);
buildLine(point1, point21, action, interval);
buildLine(point2, point22, action, interval);
}
}
public static void buildSphere(Location center, double radius, double rate, Consumer<Location> action) {
double pii = Math.PI * 2;
double rateDiv = Math.PI / rate;
for (double phi = 0; phi <= Math.PI; phi += rateDiv) {
double y1 = radius * Math.cos(phi);
double y2 = radius * Math.sin(phi);
for (double theta = 0; theta <= pii; theta += rateDiv) {
double x = Math.cos(theta) * y2;
double z = Math.sin(theta) * y2;
action.accept(center.clone().add(x, y1, z));
}
}
}
public static void buildSphereSpike(Location center, double radius, double rate, int chance, double minRandomDistance, double maxRandomDistance, double interval, Consumer<Location> action) {
double pii = Math.PI * 2;
double rateDiv = Math.PI / rate;
for (double phi = 0; phi <= Math.PI; phi += rateDiv) {
double y = radius * Math.cos(phi);
double sinPhi = radius * Math.sin(phi);
for (double theta = 0; theta <= pii; theta += rateDiv) {
double x = Math.cos(theta) * sinPhi;
double z = Math.sin(theta) * sinPhi;
if (chance == 0 || Numbers.getRandomInteger(0, chance) == 1) {
Location start = center.clone().add(x, y, z);
Vector endV = start.clone().subtract(center).toVector().multiply(Numbers.getRandomDouble(minRandomDistance, maxRandomDistance));
Location end = start.clone().add(endV);
buildLine(start, end, action, interval);
}
}
}
}
public static void buildRing(Location center, double rate, double tubeRate, double radius, double tubeRadius, Consumer<Location> action) {
double pii = Math.PI * 2;
double rateDiv = Math.PI / rate;
double tubeDiv = Math.PI / tubeRadius;
for (double theta = 0; theta <= pii; theta += rateDiv) {
double cos = Math.cos(theta);
double sin = Math.sin(theta);
for (double phi = 0; phi <= pii; phi += tubeDiv) {
double finalRadius = radius + (tubeRadius * Math.cos(phi));
double x = finalRadius * cos;
double y = finalRadius * sin;
double z = tubeRadius * Math.sin(phi);
action.accept(center.clone().add(x, y, z));
}
}
}
public static void buildLightning(Location start, Vector direction, int entries, int branches, double radius, double offset, double offsetRate, double length, double lengthRate, double branch, double branchRate, Consumer<Location> action) {
ThreadLocalRandom random = ThreadLocalRandom.current();
if (entries <= 0) {
return;
}
boolean inRange = true;
while (random.nextDouble() < branch || inRange) {
Vector randomizer = new Vector(random.nextDouble(-radius, radius), random.nextDouble(-radius, radius), random.nextDouble(-radius, radius)).normalize().multiply((random.nextDouble(-radius, radius)) * offset);
Vector endVector = start.clone().toVector().add(direction.clone().multiply(length)).add(randomizer);
Location end = endVector.toLocation(start.getWorld());
if (end.distance(start) <= length) {
inRange = true;
continue;
} else {
inRange = false;
}
int rate = (int) (start.distance(end) / 0.1); // distance * (distance / 10)
Vector rateDir = endVector.clone().subtract(start.toVector()).normalize().multiply(0.1);
for (int i = 0; i < rate; i++) {
Location loc = start.clone().add(rateDir.clone().multiply(i));
action.accept(loc);
}
buildLightning(end.clone(), direction, entries - 1, branches - 1, radius, offset * offsetRate, offsetRate, length * lengthRate, lengthRate, branch * branchRate, branchRate, action);
if (branches <= 0) {
break;
}
}
}
public static void buildDNA(Location start, double radius, double rate, double extension, int height, int hydrogenBondDist, Consumer<Location> action1, Consumer<Location> action2) {
int nucleotideDist = 0;
for (double y = 0; y <= height; y += rate) {
nucleotideDist++;
double x = radius * Math.cos(extension * y);
double z = radius * Math.sin(extension * y);
Location nucleotide1 = start.clone().add(x, y, z);
action1.accept(start.clone().add(x, y, z));
Location nucleotide2 = start.clone().subtract(x, -y, z);
action1.accept(start.clone().add(-x, y, -z));
if (nucleotideDist >= hydrogenBondDist) {
nucleotideDist = 0;
buildLine(nucleotide1, nucleotide2, action2, rate * 2);
}
}
}
public static void buildRectangle(Location start, Location end, double rate, Consumer<Location> action) {
double maxX = Math.max(start.getX(), end.getX());
double minX = Math.min(start.getX(), end.getX());
double maxY = Math.max(start.getY(), end.getY());
double minY = Math.min(start.getY(), end.getY());
for (double x = minX; x <= maxX; x += rate) {
for (double y = minY; y <= maxY; y += rate) {
action.accept(start.clone().add(x - minX, y - minY, 0));
}
}
}
public static void buildCage(Location start, Location end, double rate, double barRate, Consumer<Location> action) {
double maxX = Math.max(start.getX(), end.getX());
double minX = Math.min(start.getX(), end.getX());
double maxZ = Math.max(start.getZ(), end.getZ());
double minZ = Math.min(start.getZ(), end.getZ());
double barChance = 0;
for (double x = minX; x <= maxX; x += rate) {
for (double z = minZ; z <= maxZ; z += rate) {
Location barStart = start.clone().add(x - minX, 0, z - minZ);
Location barEnd = start.clone().add(x - minX, 3, z - minZ);
if ((x == minX || x + rate > maxX) || (z == minZ || z + rate > maxZ)) {
barChance++;
if (barChance >= barRate) {
barChance = 0;
buildLine(barStart, barEnd, action, rate);
}
}
}
}
}
public static void buildCube(Location start, Location end, double rate, Consumer<Location> action) {
double maxX = Math.max(start.getX(), end.getX());
double minX = Math.min(start.getX(), end.getX());
double maxY = Math.max(start.getY(), end.getY());
double minY = Math.min(start.getY(), end.getY());
double maxZ = Math.max(start.getZ(), end.getZ());
double minZ = Math.min(start.getZ(), end.getZ());
for (double x = minX; x <= maxX; x += rate) {
for (double y = minY; y <= maxY; y += rate) {
for (double z = minZ; z <= maxZ; z += rate) {
if ((y == minY || y + rate > maxY) || (x == minX || x + rate > maxX) || (z == minZ || z + rate > maxZ)) {
action.accept(start.clone().add(x - minX, y - minY, z - minZ));
}
}
}
}
}
public static void buildCubeFilled(Location start, Location end, double rate, Consumer<Location> action) {
double maxX = Math.max(start.getX(), end.getX());
double minX = Math.min(start.getX(), end.getX());
double maxY = Math.max(start.getY(), end.getY());
double minY = Math.min(start.getY(), end.getY());
double maxZ = Math.max(start.getZ(), end.getZ());
double minZ = Math.min(start.getZ(), end.getZ());
for (double x = minX; x <= maxX; x += rate) {
for (double y = minY; y <= maxY; y += rate) {
for (double z = minZ; z <= maxZ; z += rate) {
action.accept(start.clone().add(x - minX, y - minY, z - minZ));
}
}
}
}
public static void buildCubeStructured(Location start, Location end, double rate, Consumer<Location> action) {
double maxX = Math.max(start.getX(), end.getX());
double minX = Math.min(start.getX(), end.getX());
double maxY = Math.max(start.getY(), end.getY());
double minY = Math.min(start.getY(), end.getY());
double maxZ = Math.max(start.getZ(), end.getZ());
double minZ = Math.min(start.getZ(), end.getZ());
for (double x = minX; x <= maxX; x += rate) {
for (double y = minY; y <= maxY; y += rate) {
for (double z = minZ; z <= maxZ; z += rate) {
int components = 0;
if (x == minX || x + rate > maxX) {
components++;
}
if (y == minY || y + rate > maxY) {
components++;
}
if (z == minZ || z + rate > maxZ) {
components++;
}
if (components >= 2) {
action.accept(start.clone().add(x - minX, y - minY, z - minZ));
}
}
}
}
}
public static void buildHypercube(Location startOrigin, Location endOrigin, double rate, double sizeRate, int cubes, Consumer<Location> action) {
List<Location> previousPoints = null;
for (int i = 0; i < cubes + 1; i++) {
List<Location> points = new ArrayList<>();
Location start = startOrigin.clone().subtract(i * sizeRate, i * sizeRate, i * sizeRate);
Location end = endOrigin.clone().add(i * sizeRate, i * sizeRate, i * sizeRate);
double maxX = Math.max(start.getX(), end.getX());
double minX = Math.min(start.getX(), end.getX());
double maxY = Math.max(start.getY(), end.getY());
double minY = Math.min(start.getY(), end.getY());
double maxZ = Math.max(start.getZ(), end.getZ());
double minZ = Math.min(start.getZ(), end.getZ());
points.add(new Location(start.getWorld(), maxX, maxY, maxZ));
points.add(new Location(start.getWorld(), minX, minY, minZ));
points.add(new Location(start.getWorld(), maxX, minY, maxZ));
points.add(new Location(start.getWorld(), minX, maxY, minZ));
points.add(new Location(start.getWorld(), minX, minY, maxZ));
points.add(new Location(start.getWorld(), maxX, minY, minZ));
points.add(new Location(start.getWorld(), maxX, maxY, minZ));
points.add(new Location(start.getWorld(), minX, maxY, maxZ));
if (previousPoints != null) {
for (int p = 0; p < 8; p++) {
Location current = points.get(p);
Location previous = previousPoints.get(p);
buildLine(previous, current, action, rate);
}
}
previousPoints = points;
for (double x = minX; x <= maxX; x += rate) {
for (double y = minY; y <= maxY; y += rate) {
for (double z = minZ; z <= maxZ; z += rate) {
int components = 0;
if (x == minX || x + rate > maxX) {
components++;
}
if (y == minY || y + rate > maxY) {
components++;
}
if (z == minZ || z + rate > maxZ) {
components++;
}
if (components >= 2) {
action.accept(start.clone().add(x - minX, y - minY, z - minZ));
}
}
}
}
}
}
Effects() {
}
@ -130,6 +495,10 @@ public class Effects {
}
}
public void playAsync() {
Bukkit.getScheduler().runTaskAsynchronously(TabooLib.getPlugin(), this::play);
}
public Effects particle(Particle particle) {
this.particle = particle;
return this;
@ -180,11 +549,21 @@ public class Effects {
return this;
}
public Effects data(BlockData data) {
this.data = data;
return this;
}
public Effects data(ColorData data) {
this.data = data;
return this;
}
public Effects data0(Object data) {
this.data = data;
return this;
}
public static class ColorData {
private final Color color;

View File

@ -1,4 +1,4 @@
package io.izzel.taboolib.util.lite;/*
/*
* The MIT License (MIT)
*
* Copyright (c) 2018 Hex_27
@ -20,6 +20,7 @@ package io.izzel.taboolib.util.lite;/*
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package io.izzel.taboolib.util.lite;
import com.google.common.base.Enums;
import com.google.common.cache.Cache;
@ -27,9 +28,8 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.text.WordUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
@ -39,33 +39,30 @@ import javax.annotation.Nullable;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/*
* References
*
* * * GitHub: https://github.com/CryptoMorin/XSeries/blob/master/Materials.java
* * XSeries: https://www.spigotmc.org/threads/378136/
* Pre-flattening: https://minecraft.gamepedia.com/Java_Edition_data_values/Pre-flattening
* Materials: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html
* Materials (1.8): https://helpch.at/docs/1.8/org/bukkit/Material.html
* Material IDs: https://minecraft-ids.grahamedgecombe.com/
* Material Source Code: https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/browse/src/main/java/org/bukkit/Material.java
* Materials v1: https://www.spigotmc.org/threads/329630/
*/
/**
* <b>Materials</b> - Data Values/Pre-flattening<br>
* Supports 1.8-1.15<br>
* 1.13 and above as priority.
* <p>
* This class is mainly designed to support ItemStacks.
* If you want to use it on blocks you'll have to
* use <a href="https://github.com/CryptoMorin/XSeries/blob/master/XBlock.java">XBlock</a>
* <p>
* Pre-flattening: https://minecraft.gamepedia.com/Java_Edition_data_values/Pre-flattening
* Materials: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html
* Materials (1.12): https://helpch.at/docs/1.12.2/index.html?org/bukkit/Material.html
* Material IDs: https://minecraft-ids.grahamedgecombe.com/
* Material Source Code: https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/browse/src/main/java/org/bukkit/Material.java
* Materials v1: https://www.spigotmc.org/threads/329630/
*
* @author Crypto Morin
* @version 3.2.0
* @version 4.0.0
* @see Material
* @see ItemStack
*/
public enum Materials {
ACACIA_BOAT("BOAT_ACACIA"),
ACACIA_BUTTON("WOOD_BUTTON"),
ACACIA_DOOR("ACACIA_DOOR_ITEM"),
@ -103,15 +100,19 @@ public enum Materials {
ATTACHED_PUMPKIN_STEM(7, "PUMPKIN_STEM"),
AZURE_BLUET(3, "RED_ROSE"),
BAKED_POTATO,
BAMBOO("1.14", "SUGAR_CANE"),
BAMBOO("1.14", "SUGAR_CANE", ""),
BAMBOO_SAPLING("1.14"),
BARREL("1.14", "CHEST"),
BARREL("1.14", "CHEST", ""),
BARRIER,
BAT_SPAWN_EGG(65, "MONSTER_EGG"),
BEACON,
BEDROCK,
BEEF("RAW_BEEF"),
BEEHIVE("1.15"),
/**
* Beetroot is a known material in pre-1.13
* Use XBlock when comparing block types.
*/
BEETROOT("BEETROOT_BLOCK"),
BEETROOTS("BEETROOT"),
BEETROOT_SEEDS,
@ -148,7 +149,7 @@ public enum Materials {
BLACK_TERRACOTTA(15, "HARD_CLAY", "STAINED_CLAY"),
BLACK_WALL_BANNER("WALL_BANNER"),
BLACK_WOOL(15, "WOOL"),
BLAST_FURNACE("1.14", "FURNACE"),
BLAST_FURNACE("1.14", "FURNACE", ""),
BLAZE_POWDER,
BLAZE_ROD,
BLAZE_SPAWN_EGG(61, "MONSTER_EGG"),
@ -159,7 +160,7 @@ public enum Materials {
BLUE_CONCRETE_POWDER(11, "CONCRETE_POWDER"),
BLUE_DYE(4, "INK_SACK", "LAPIS_LAZULI"),
BLUE_GLAZED_TERRACOTTA(11, "1.12", "HARD_CLAY", "STAINED_CLAY", "BLUE_TERRACOTTA"),
BLUE_ICE("1.13", "PACKED_ICE"),
BLUE_ICE("1.13", "PACKED_ICE", ""),
BLUE_ORCHID(1, "RED_ROSE"),
BLUE_SHULKER_BOX,
BLUE_STAINED_GLASS(11, "STAINED_GLASS"),
@ -212,8 +213,8 @@ public enum Materials {
CARROT("CARROT_ITEM"),
CARROTS("CARROT"),
CARROT_ON_A_STICK("CARROT_STICK"),
CARTOGRAPHY_TABLE("1.14", "CRAFTING_TABLE"),
CARVED_PUMPKIN(1, "1.13", "PUMPKIN"),
CARTOGRAPHY_TABLE("1.14", "CRAFTING_TABLE", ""),
CARVED_PUMPKIN(1, "1.13", "PUMPKIN", ""),
CAT_SPAWN_EGG,
CAULDRON("CAULDRON_ITEM"),
/**
@ -238,9 +239,9 @@ public enum Materials {
CHISELED_RED_SANDSTONE(1, "RED_SANDSTONE"),
CHISELED_SANDSTONE(1, "SANDSTONE"),
CHISELED_STONE_BRICKS(3, "SMOOTH_BRICK"),
CHORUS_FLOWER,
CHORUS_FRUIT,
CHORUS_PLANT,
CHORUS_FLOWER("1.9"),
CHORUS_FRUIT("1.9"),
CHORUS_PLANT("1.9"),
CLAY,
CLAY_BALL,
CLOCK("WATCH"),
@ -256,13 +257,13 @@ public enum Materials {
COCOA("1.15"),
COCOA_BEANS(3, "INK_SACK", "COCOA"),
COD("RAW_FISH"),
COD_BUCKET("1.13", "BUCKET", "WATER_BUCKET"),
COD_SPAWN_EGG("1.13", "MONSTER_EGG"),
COD_BUCKET("1.13", "BUCKET", "WATER_BUCKET", ""),
COD_SPAWN_EGG("1.13", "MONSTER_EGG", ""),
COMMAND_BLOCK("COMMAND"),
COMMAND_BLOCK_MINECART("COMMAND_MINECART"),
COMPARATOR("REDSTONE_COMPARATOR", "REDSTONE_COMPARATOR_ON", "REDSTONE_COMPARATOR_OFF"),
COMPASS,
COMPOSTER("1.14", "CAULDRON"),
COMPOSTER("1.14", "CAULDRON", ""),
CONDUIT("1.13", "BEACON"),
COOKED_BEEF,
COOKED_CHICKEN,
@ -272,7 +273,7 @@ public enum Materials {
COOKED_RABBIT,
COOKED_SALMON(1, "COOKED_FISH"),
COOKIE,
CORNFLOWER(4, "1.14", "BLUE_DYE"),
CORNFLOWER(4, "1.14", "BLUE_DYE", ""),
COW_SPAWN_EGG(92, "MONSTER_EGG"),
CRACKED_STONE_BRICKS(2, "SMOOTH_BRICK"),
CRAFTING_TABLE("WORKBENCH"),
@ -341,7 +342,7 @@ public enum Materials {
DEAD_TUBE_CORAL_BLOCK("1.13"),
DEAD_TUBE_CORAL_FAN("1.13"),
DEAD_TUBE_CORAL_WALL_FAN("1.13"),
DEBUG_STICK("1.13", "STICK"),
DEBUG_STICK("1.13", "STICK", ""),
DETECTOR_RAIL,
DIAMOND,
DIAMOND_AXE,
@ -362,16 +363,16 @@ public enum Materials {
DIORITE_WALL,
DIRT,
DISPENSER,
DOLPHIN_SPAWN_EGG("1.13", "MONSTER_EGG"),
DOLPHIN_SPAWN_EGG("1.13", "MONSTER_EGG", ""),
DONKEY_SPAWN_EGG(32, "MONSTER_EGG"),
DRAGON_BREATH("DRAGONS_BREATH"),
DRAGON_EGG,
DRAGON_HEAD(5, "SKULL", "SKULL_ITEM"),
DRAGON_HEAD(5, "1.9", "SKULL", "SKULL_ITEM"),
DRAGON_WALL_HEAD(5, "SKULL", "SKULL_ITEM"),
DRIED_KELP("1.13"),
DRIED_KELP_BLOCK("1.13"),
DROPPER,
DROWNED_SPAWN_EGG("1.13", "MONSTER_EGG"),
DROWNED_SPAWN_EGG("1.13", "MONSTER_EGG", ""),
EGG,
ELDER_GUARDIAN_SPAWN_EGG(4, "MONSTER_EGG"),
ELYTRA,
@ -387,10 +388,10 @@ public enum Materials {
ENDER_EYE("EYE_OF_ENDER"),
ENDER_PEARL,
END_CRYSTAL,
END_GATEWAY,
END_GATEWAY("1.9"),
END_PORTAL("ENDER_PORTAL"),
END_PORTAL_FRAME("ENDER_PORTAL_FRAME"),
END_ROD,
END_ROD("1.9", "BLAZE_ROD", ""),
END_STONE("ENDER_STONE"),
END_STONE_BRICKS("END_BRICKS"),
END_STONE_BRICK_SLAB(4, "STEP"),
@ -412,13 +413,16 @@ public enum Materials {
FIRE_CORAL_FAN("1.13"),
FIRE_CORAL_WALL_FAN,
FISHING_ROD,
FLETCHING_TABLE("1.14", "CRAFTING_TABLE"),
FLETCHING_TABLE("1.14", "CRAFTING_TABLE", ""),
FLINT,
FLINT_AND_STEEL,
FLOWER_BANNER_PATTERN,
FLOWER_POT("FLOWER_POT_ITEM"), // TODO Fix exceptional material
FLOWER_POT("FLOWER_POT_ITEM"),
FOX_SPAWN_EGG("1.14"),
FROSTED_ICE,
/**
* This special material cannot be obtained as an item.
*/
FROSTED_ICE("1.9", "PACKED_ICE", ""),
FURNACE("BURNING_FURNACE"),
FURNACE_MINECART("POWERED_MINECART"),
GHAST_SPAWN_EGG(56, "MONSTER_EGG"),
@ -480,7 +484,7 @@ public enum Materials {
GREEN_TERRACOTTA(13, "HARD_CLAY", "STAINED_CLAY"),
GREEN_WALL_BANNER(2, "WALL_BANNER"),
GREEN_WOOL(13, "WOOL"),
GRINDSTONE("1.14", "ANVIL"),
GRINDSTONE("1.14", "ANVIL", ""),
GUARDIAN_SPAWN_EGG(68, "MONSTER_EGG"),
GUNPOWDER("SULPHUR"),
HAY_BLOCK,
@ -488,8 +492,8 @@ public enum Materials {
HEAVY_WEIGHTED_PRESSURE_PLATE("IRON_PLATE"),
HONEYCOMB("1.15"),
HONEYCOMB_BLOCK("1.15"),
HONEY_BLOCK("1.15", "SLIME_BLOCK"),
HONEY_BOTTLE("1.15", "GLASS_BOTTLE"),
HONEY_BLOCK("1.15", "SLIME_BLOCK", ""),
HONEY_BOTTLE("1.15", "GLASS_BOTTLE", ""),
HOPPER,
HOPPER_MINECART,
HORN_CORAL("1.13"),
@ -525,7 +529,7 @@ public enum Materials {
IRON_TRAPDOOR,
ITEM_FRAME,
JACK_O_LANTERN,
JIGSAW("1.14", "COMMAND_BLOCK", "STRUCTURE_BLOCK"),
JIGSAW("1.14", "COMMAND_BLOCK", "STRUCTURE_BLOCK", ""),
JUKEBOX,
JUNGLE_BOAT("BOAT_JUNGLE"),
JUNGLE_BUTTON("WOOD_BUTTON"),
@ -547,7 +551,7 @@ public enum Materials {
KELP_PLANT("1.13"),
KNOWLEDGE_BOOK("1.12", "BOOK"),
LADDER,
LANTERN("1.14", "SEA_LANTERN"),
LANTERN("1.14", "SEA_LANTERN", ""),
LAPIS_BLOCK,
LAPIS_LAZULI(4, "INK_SACK"),
LAPIS_ORE,
@ -559,9 +563,9 @@ public enum Materials {
LEATHER_BOOTS,
LEATHER_CHESTPLATE,
LEATHER_HELMET,
LEATHER_HORSE_ARMOR("1.14", "IRON_HORSE_ARMOR"),
LEATHER_HORSE_ARMOR("1.14", "IRON_HORSE_ARMOR", ""),
LEATHER_LEGGINGS,
LECTERN("1.14", "BOOKSHELF"),
LECTERN("1.14", "BOOKSHELF", ""),
LEVER,
LIGHT_BLUE_BANNER(3, "BANNER", "STANDING_BANNER"),
LIGHT_BLUE_BED(3, "BED", "BED_BLOCK"),
@ -582,7 +586,11 @@ public enum Materials {
LIGHT_GRAY_CONCRETE(8, "CONCRETE"),
LIGHT_GRAY_CONCRETE_POWDER(8, "CONCRETE_POWDER"),
LIGHT_GRAY_DYE(7, "INK_SACK"),
LIGHT_GRAY_GLAZED_TERRACOTTA(8, "1.12", "HARD_CLAY", "STAINED_CLAY", "LIGHT_GRAY_TERRACOTTA", "SILVER_GLAZED_TERRACOTTA/1.13"),
/**
* Renamed to SILVER_GLAZED_TERRACOTTA in 1.13
* Renamed to LIGHT_GRAY_GLAZED_TERRACOTTA in 1.14
*/
LIGHT_GRAY_GLAZED_TERRACOTTA(8, "1.12", "HARD_CLAY", "STAINED_CLAY", "LIGHT_GRAY_TERRACOTTA", "SILVER_GLAZED_TERRACOTTA"),
LIGHT_GRAY_SHULKER_BOX("SILVER_SHULKER_BOX"),
LIGHT_GRAY_STAINED_GLASS(8, "STAINED_GLASS"),
LIGHT_GRAY_STAINED_GLASS_PANE(8, "THIN_GLASS", "STAINED_GLASS_PANE"),
@ -591,7 +599,7 @@ public enum Materials {
LIGHT_GRAY_WOOL(8, "WOOL"),
LIGHT_WEIGHTED_PRESSURE_PLATE("GOLD_PLATE"),
LILAC(1, "DOUBLE_PLANT"),
LILY_OF_THE_VALLEY(15, "1.14", "WHITE_DYE"),
LILY_OF_THE_VALLEY(15, "1.14", "WHITE_DYE", ""),
LILY_PAD("WATER_LILY"),
LIME_BANNER(10, "BANNER", "STANDING_BANNER"),
LIME_BED(5, "BED", "BED_BLOCK"),
@ -622,7 +630,7 @@ public enum Materials {
MAGENTA_TERRACOTTA(2, "HARD_CLAY", "STAINED_CLAY"),
MAGENTA_WALL_BANNER(13, "WALL_BANNER"),
MAGENTA_WOOL(2, "WOOL"),
MAGMA_BLOCK("MAGMA"),
MAGMA_BLOCK("1.10", "MAGMA"),
MAGMA_CREAM,
MAGMA_CUBE_SPAWN_EGG(62, "MONSTER_EGG"),
MAP("EMPTY_MAP"),
@ -672,8 +680,13 @@ public enum Materials {
NETHER_PORTAL("PORTAL"),
NETHER_QUARTZ_ORE("QUARTZ_ORE"),
NETHER_STAR,
NETHER_WART("NETHER_STALK"),
NETHER_WART_BLOCK("NETHER_WARTS"),
/**
* Just like mentioned in https://minecraft.gamepedia.com/Nether_Wart
* Nether wart is also known as nether stalk in the code.
* NETHER_STALK is the planted state of nether warts.
*/
NETHER_WART("NETHER_WARTS", "NETHER_STALK"),
NETHER_WART_BLOCK,
NOTE_BLOCK,
OAK_BOAT("BOAT"),
OAK_BUTTON("WOOD_BUTTON"),
@ -717,7 +730,7 @@ public enum Materials {
PEONY(5, "DOUBLE_PLANT"),
PETRIFIED_OAK_SLAB("WOOD_STEP"),
PHANTOM_MEMBRANE("1.13"),
PHANTOM_SPAWN_EGG("1.13", "MONSTER_EGG"),
PHANTOM_SPAWN_EGG("1.13", "MONSTER_EGG", ""),
PIG_SPAWN_EGG(90, "MONSTER_EGG"),
PILLAGER_SPAWN_EGG("1.14"),
PINK_BANNER(9, "BANNER", "STANDING_BANNER"),
@ -792,8 +805,8 @@ public enum Materials {
PRISMARINE_STAIRS("1.13"),
PRISMARINE_WALL,
PUFFERFISH(3, "RAW_FISH"),
PUFFERFISH_BUCKET("1.13", "BUCKET", "WATER_BUCKET"),
PUFFERFISH_SPAWN_EGG("1.13", "MONSTER_EGG"),
PUFFERFISH_BUCKET("1.13", "BUCKET", "WATER_BUCKET", ""),
PUFFERFISH_SPAWN_EGG("1.13", "MONSTER_EGG", ""),
PUMPKIN,
PUMPKIN_PIE,
PUMPKIN_SEEDS,
@ -865,16 +878,16 @@ public enum Materials {
ROTTEN_FLESH,
SADDLE,
SALMON(1, "RAW_FISH"),
SALMON_BUCKET("1.13", "BUCKET", "WATER_BUCKET"),
SALMON_SPAWN_EGG("1.13", "MONSTER_EGG"),
SALMON_BUCKET("1.13", "BUCKET", "WATER_BUCKET", ""),
SALMON_SPAWN_EGG("1.13", "MONSTER_EGG", ""),
SAND,
SANDSTONE,
SANDSTONE_SLAB(1, "STEP", "STONE_SLAB", "DOUBLE_STEP"),
SANDSTONE_STAIRS,
SANDSTONE_WALL,
SCAFFOLDING("1.14", "SLIME_BLOCK"),
SCAFFOLDING("1.14", "SLIME_BLOCK", ""),
SCUTE("1.13"),
SEAGRASS("1.13", "GRASS"),
SEAGRASS("1.13", "GRASS", ""),
SEA_LANTERN,
SEA_PICKLE("1.13"),
SHEARS,
@ -893,8 +906,8 @@ public enum Materials {
SLIME_BLOCK,
SLIME_SPAWN_EGG(55, "MONSTER_EGG"),
SMITHING_TABLE,
SMOKER("1.14", "FURNACE"),
SMOOTH_QUARTZ("1.13"),
SMOKER("1.14", "FURNACE", ""),
SMOOTH_QUARTZ("1.13", "QUARTZ", ""),
SMOOTH_QUARTZ_SLAB(7, "STEP"),
SMOOTH_QUARTZ_STAIRS,
SMOOTH_RED_SANDSTONE(2, "RED_SANDSTONE"),
@ -910,7 +923,7 @@ public enum Materials {
SNOW_BLOCK,
SOUL_SAND,
SPAWNER("MOB_SPAWNER"),
SPECTRAL_ARROW("1.9", "ARROW"),
SPECTRAL_ARROW("1.9", "ARROW", ""),
SPIDER_EYE,
SPIDER_SPAWN_EGG(52, "MONSTER_EGG"),
SPLASH_POTION,
@ -966,24 +979,28 @@ public enum Materials {
STRUCTURE_BLOCK,
/**
* Originally developers used barrier blocks for its purpose.
* 1.10 will be parsed as 1.9 version.
* So technically this isn't really considered as a suggested material.
*/
STRUCTURE_VOID("1.10", "BARRIER"),
STRUCTURE_VOID("1.10", "", "BARRIER"),
SUGAR,
/**
* Sugar Cane is a known material in pre-1.13
* Use XBlock when comparing block types.
*/
SUGAR_CANE("SUGAR_CANE_BLOCK"),
SUNFLOWER("DOUBLE_PLANT"),
SUSPICIOUS_STEW("1.14", "MUSHROOM_STEW"),
SUSPICIOUS_STEW("1.14", "MUSHROOM_STEW", ""),
SWEET_BERRIES("1.14"),
SWEET_BERRY_BUSH("1.14", "GRASS"),
SWEET_BERRY_BUSH("1.14", "GRASS", ""),
TALL_GRASS(2, "DOUBLE_PLANT"),
TALL_SEAGRASS(2, "1.13", "TALL_GRASS"),
TALL_SEAGRASS(2, "1.13", "TALL_GRASS", ""),
TERRACOTTA("HARD_CLAY"),
TIPPED_ARROW("1.9", "ARROW"),
TIPPED_ARROW("1.9", "ARROW", ""),
TNT,
TNT_MINECART("EXPLOSIVE_MINECART"),
TORCH,
TOTEM_OF_UNDYING("TOTEM"),
TRADER_LLAMA_SPAWN_EGG(103, "1.14", "MONSTER_EGG"),
TRADER_LLAMA_SPAWN_EGG(103, "1.14", "MONSTER_EGG", ""),
TRAPPED_CHEST,
TRIDENT("1.13"),
TRIPWIRE,
@ -995,9 +1012,9 @@ public enum Materials {
TUBE_CORAL_BLOCK("1.13"),
TUBE_CORAL_FAN("1.13"),
TUBE_CORAL_WALL_FAN,
TURTLE_EGG("1.13", "EGG"),
TURTLE_HELMET("1.13", "IRON_HELMET"),
TURTLE_SPAWN_EGG("1.13", "CHICKEN_SPAWN_EGG"),
TURTLE_EGG("1.13", "EGG", ""),
TURTLE_HELMET("1.13", "IRON_HELMET", ""),
TURTLE_SPAWN_EGG("1.13", "CHICKEN_SPAWN_EGG", ""),
VEX_SPAWN_EGG(35, "MONSTER_EGG"),
VILLAGER_SPAWN_EGG(120, "MONSTER_EGG"),
VINDICATOR_SPAWN_EGG(36, "MONSTER_EGG"),
@ -1009,7 +1026,7 @@ public enum Materials {
*/
VOID_AIR("AIR"),
WALL_TORCH("TORCH"),
WANDERING_TRADER_SPAWN_EGG("1.14", "VILLAGER_SPAWN_EGG"),
WANDERING_TRADER_SPAWN_EGG("1.14", "VILLAGER_SPAWN_EGG", ""),
/**
* This is used for blocks only.
* In 1.13- WATER will turn into STATIONARY_WATER after it finished spreading.
@ -1020,6 +1037,10 @@ public enum Materials {
WATER("STATIONARY_WATER"),
WATER_BUCKET,
WET_SPONGE(1, "SPONGE"),
/**
* Wheat is a known material in pre-1.13
* Use XBlock when comparing block types.
*/
WHEAT("CROPS"),
WHEAT_SEEDS("SEEDS"),
WHITE_BANNER(15, "BANNER", "STANDING_BANNER"),
@ -1037,7 +1058,7 @@ public enum Materials {
WHITE_WALL_BANNER(15, "WALL_BANNER"),
WHITE_WOOL("WOOL"),
WITCH_SPAWN_EGG(66, "MONSTER_EGG"),
WITHER_ROSE("1.14", "BLACK_DYE"),
WITHER_ROSE("1.14", "BLACK_DYE", ""),
WITHER_SKELETON_SKULL(1, "SKULL", "SKULL_ITEM"),
WITHER_SKELETON_SPAWN_EGG(5, "MONSTER_EGG"),
WITHER_SKELETON_WALL_SKULL(1, "SKULL", "SKULL_ITEM"),
@ -1115,19 +1136,20 @@ public enum Materials {
.put(NETHER_BRICK, NETHER_BRICKS)
.build()
);
/**
/*
* A set of all the legacy names without duplicates.
* <p>
* REMOVE THIS IF YOU DON'T NEED IT.
* It'll help to free up a lot of memory.
* It'll help to free up a lot of memory if it's not used.
* Add it back if you need it.
*
* @see #containsLegacy(String)
* @since 2.2.0
*/
*
private static final ImmutableSet<String> LEGACY_VALUES = VALUES.stream().map(Materials::getLegacy)
.flatMap(Arrays::stream)
.filter(m -> m.charAt(1) == '.')
.collect(Collectors.collectingAndThen(Collectors.toSet(), ImmutableSet::copyOf));
*/
/**
* Guava (Google Core Libraries for Java)'s cache for performance and timed caches.
@ -1145,7 +1167,7 @@ public enum Materials {
*
* @since 3.0.0
*/
private static final Cache<Materials, Material> PARSED_CACHE = CacheBuilder.newBuilder()
private static final Cache<Materials, Optional<Material>> PARSED_CACHE = CacheBuilder.newBuilder()
.softValues()
.expireAfterAccess(10, TimeUnit.MINUTES)
.concurrencyLevel(Runtime.getRuntime().availableProcessors())
@ -1159,19 +1181,18 @@ public enum Materials {
*/
private static final Pattern FORMAT_PATTERN = Pattern.compile("\\W+");
/**
* The current version of the server in the a form of a major {@link MinecraftVersion} version.
* The current version of the server in the a form of a major version.
*
* @since 1.0.0
*/
private static final MinecraftVersion VERSION = valueOfVersion(Bukkit.getVersion());
private static final int VERSION = Integer.parseInt(getMajorVersion(Bukkit.getVersion()).substring(2));
/**
* Cached result if the server version is after the flattening ({@link MinecraftVersion#V1_13}) update.
* Cached result if the server version is after the v1.13 flattening update.
* Please don't mistake this with flat-chested people. It happened.
*
* @since 3.0.0
*/
private static final boolean ISFLAT = isVersionOrHigher(MinecraftVersion.V1_13);
private static final boolean ISFLAT = supports(13);
/**
* The data value of this material https://minecraft.gamepedia.com/Java_Edition_data_values/Pre-flattening
*
@ -1199,16 +1220,16 @@ public enum Materials {
}
/**
* Checks if the version is {@link MinecraftVersion#V1_13} (Aquatic Update) or higher.
* Checks if the version is 1.13 Aquatic Update or higher.
* An invocation of this method yields the cached result from the expression:
* <p>
* <blockquote>
* {@link #isVersionOrHigher(MinecraftVersion V1_13)}
* {@link #supports(int) 13}}
* </blockquote>
*
* @return true if 1.13 or higher.
* @see #getVersion()
* @see #isVersionOrHigher(MinecraftVersion)
* @see #supports(int)
* @since 1.0.0
*/
public static boolean isNewVersion() {
@ -1224,24 +1245,23 @@ public enum Materials {
* An invocation of this method yields exactly the same result as the expression:
* <p>
* <blockquote>
* {@link #getVersion()} == {@link MinecraftVersion#V1_8}
* {@link #getVersion()} == 1.8
* </blockquote>
*
* @since 2.0.0
*/
public static boolean isOneEight() {
return VERSION == MinecraftVersion.V1_8;
return !supports(9);
}
/**
* The current version of the server.
*
* @return the current server version or {@link MinecraftVersion#UNKNOWN} if unknown or below 1.8.
* @return the current server version or 0.0 if unknown.
* @see #isNewVersion()
* @since 2.0.0
*/
@Nonnull
public static MinecraftVersion getVersion() {
public static double getVersion() {
return VERSION;
}
@ -1278,11 +1298,9 @@ public enum Materials {
*
* @param name name of the material.
* @return true if Materials enum has this material.
* @see #containsLegacy(String)
* @since 1.0.0
*/
public static boolean contains(@Nonnull String name) {
Validate.notEmpty(name, "Cannot check for null or empty material name");
name = format(name);
for (Materials materials : VALUES)
@ -1290,21 +1308,6 @@ public enum Materials {
return false;
}
/**
* Checks if the given material matches any of the available legacy names.
* Changed names between the {@code 1.9} and {@code 1.12} versions are not supported (there are only a few anyway).
*
* @param name the material name.
* @return true if it's a legacy name.
* @see #contains(String)
* @see #anyMatchLegacy(String)
* @since 2.0.0
*/
public static boolean containsLegacy(@Nonnull String name) {
Validate.notEmpty(name, "Cannot check legacy names for null or empty material name");
return LEGACY_VALUES.contains(format(name));
}
/**
* Parses the given material name as an Materials with unspecified data value.
*
@ -1322,8 +1325,8 @@ public enum Materials {
* <p>
* <b>Examples</b>
* <pre>
* INK_SACK:1 -> RED_DYE
* WOOL, 14 -> RED_WOOL
* {@code INK_SACK:1 -> RED_DYE}
* {@code WOOL, 14 -> RED_WOOL}
* </pre>
*
* @see #matchDefinedMaterials(String, byte)
@ -1332,7 +1335,6 @@ public enum Materials {
*/
@Nonnull
public static Optional<Materials> matchMaterials(@Nonnull String name, byte data) {
Validate.notEmpty(name, "Cannot match a material with null or empty material name");
Optional<Materials> oldMatch = matchMaterialsWithData(name);
if (oldMatch.isPresent()) return oldMatch;
@ -1348,8 +1350,8 @@ public enum Materials {
* <p>
* <b>Examples</b>
* <p><pre>
* INK_SACK:1 -> RED_DYE
* WOOL, 14 -> RED_WOOL
* {@code INK_SACK:1 -> RED_DYE}
* {@code WOOL, 14 -> RED_WOOL}
* </pre>
*
* @param name the material string that consists of the material name, data and separator character.
@ -1452,7 +1454,6 @@ public enum Materials {
* @since 2.0.0
*/
public static boolean isDuplicated(@Nonnull String name) {
Validate.notEmpty(name, "Cannot check duplication for null or empty material name");
name = format(name);
// Don't use matchMaterials() since this method is being called from matchMaterials() itself and will cause a StackOverflowError.
@ -1507,7 +1508,6 @@ public enum Materials {
*/
@Nonnull
public static Optional<Materials> getNewMaterialsIfDuplicated(@Nonnull String name) {
Validate.notEmpty(name, "Cannot get new duplicated material for null or empty material name");
name = format(name);
for (Map.Entry<Materials, Materials> duplicated : DUPLICATED.entrySet())
@ -1525,7 +1525,6 @@ public enum Materials {
*/
@Nullable
public static Materials getMaterialsIfDuplicated(@Nonnull String name) {
Validate.notEmpty(name, "Cannot get duplicated material for null or empty material name");
name = format(name);
for (Map.Entry<Materials, Materials> duplicated : DUPLICATED.entrySet())
@ -1549,29 +1548,15 @@ public enum Materials {
name.trim().replace('-', '_').replace(' ', '_')).replaceAll("").toUpperCase(Locale.ENGLISH);
}
/**
* Parses the material name if the legacy name has a version attached to it.
*
* @param name the material name to parse.
* @return the material name with the version removed.
* @since 2.0.0
*/
@Nonnull
private static String parseLegacyMaterialName(String name) {
int index = name.indexOf('/');
return index == -1 ? name : name.substring(0, index);
}
/**
* Checks if the specified version is the same version or higher than the current server version.
*
* @param version the version to be checked.
* @param version the major version to be checked. "1." is ignored. E.g. 1.12 = 12 | 1.9 = 9
* @return true of the version is equal or higher than the current version.
* @since 2.0.0
*/
public static boolean isVersionOrHigher(@Nonnull MinecraftVersion version) {
Objects.requireNonNull(version, "Cannot compare to a null version");
return VERSION.ordinal() >= version.ordinal();
public static boolean supports(int version) {
return VERSION >= version;
}
/**
@ -1611,45 +1596,28 @@ public enum Materials {
* Gets the exact major version (..., 1.9, 1.10, ..., 1.14)
*
* @param version Supports {@link Bukkit#getVersion()}, {@link Bukkit#getBukkitVersion()} and normal formats such as "1.14"
* @return the exact major version, or {@link MinecraftVersion#UNKNOWN} if unknown or unsupported.
* @return the exact major version.
* @since 2.0.0
*/
@Nonnull
public static String getMajorVersion(@Nonnull String version) {
Validate.notEmpty(version, "Cannot get exact major minecraft version for null or empty version");
// getBukkitVersion()
if (version.contains("-R") || version.endsWith("SNAPSHOT")) version = version.substring(0, version.indexOf('-'));
// getVersion()
int index = version.indexOf("MC:");
if (index != -1) version = version.substring(index + 4, version.length() - 1);
int index = version.lastIndexOf("MC:");
if (index != -1) {
version = version.substring(index + 4, version.length() - 1);
} else if (version.endsWith("SNAPSHOT")) {
// getBukkitVersion()
index = version.indexOf('-');
version = version.substring(0, index);
}
// 1.13.2, 1.14.4, etc...
int lastDot = version.lastIndexOf('.');
if (version.indexOf('.') != lastDot) version = version.substring(0, lastDot);
return version;
}
/**
* Parses the string arugment to a version.
* Supports {@link Bukkit#getVersion()}, {@link Bukkit#getBukkitVersion()} and normal formats such as "1.14"
*
* @param version the server version.
* @return the Minecraft version represented by the string.
* @since 2.0.0
*/
@Nonnull
public static MinecraftVersion valueOfVersion(@Nonnull String version) {
Validate.notEmpty(version, "Cannot get minecraft version for null or empty version");
version = getMajorVersion(version);
if (version.equals("1.10") || version.equals("1.11") || version.equals("1.12")) return MinecraftVersion.V1_9;
version = 'V' + version.replace('.', '_');
return Enums.getIfPresent(MinecraftVersion.class, version).or(MinecraftVersion.UNKNOWN);
}
/**
* Checks if the material can be damaged by using it.
* Names going through this method are not formatted.
@ -1680,14 +1648,14 @@ public enum Materials {
* <br>
* <b>{@code CONTAINS} Examples:</b>
* <pre>
* "CONTAINS:CHEST" -> CHEST, ENDERCHEST, TRAPPED_CHEST -> true
* "cOnTaINS:dYe" -> GREEN_DYE, YELLOW_DYE, BLUE_DYE, INK_SACK -> true
* {@code "CONTAINS:CHEST" -> CHEST, ENDERCHEST, TRAPPED_CHEST -> true}
* {@code "cOnTaINS:dYe" -> GREEN_DYE, YELLOW_DYE, BLUE_DYE, INK_SACK -> true}
* </pre>
* <p>
* <b>{@code REGEX} Examples</b>
* <pre>
* "REGEX:^.+_.+_.+$" -> Every Material with 3 underlines or more: SHULKER_SPAWN_EGG, SILVERFISH_SPAWN_EGG, SKELETON_HORSE_SPAWN_EGG
* "REGEX:^.{1,3}$" -> Material names that have 3 letters only: BED, MAP, AIR
* {@code "REGEX:^.+_.+_.+$" -> Every Material with 3 underlines or more: SHULKER_SPAWN_EGG, SILVERFISH_SPAWN_EGG, SKELETON_HORSE_SPAWN_EGG}
* {@code "REGEX:^.{1,3}$" -> Material names that have 3 letters only: BED, MAP, AIR}
* </pre>
* <p>
* The reason that there are tags for {@code CONTAINS} and {@code REGEX}
@ -1734,19 +1702,17 @@ public enum Materials {
/**
* Gets the version which this material was added in.
* If the material was added before {@link MinecraftVersion#V1_13} then
* it'll return {@link MinecraftVersion#UNKNOWN}
* If the material doesn't have a version it'll return 0;
*
* @return the Minecraft version which tihs material was added in.
* @since 3.0.0
*/
@Nonnull
public MinecraftVersion getMaterialVersion() {
if (this.legacy.length == 0) return MinecraftVersion.UNKNOWN;
public int getMaterialVersion() {
if (this.legacy.length == 0) return 0;
String version = this.legacy[0];
if (version.charAt(1) != '.') return MinecraftVersion.UNKNOWN;
if (version.charAt(1) != '.') return 0;
return MinecraftVersion.valueOf('V' + version.replace('.', '_'));
return Integer.parseInt(version.substring(2));
}
/**
@ -1790,16 +1756,13 @@ public enum Materials {
*
* @param name the name to check
* @return true if it's one of the legacy names.
* @see #containsLegacy(String)
* @since 2.0.0
*/
private boolean anyMatchLegacy(@Nonnull String name) {
// If it's a new material, everything after this is a suggestion.
// At least until now except one or two materials.
if (this.isNew()) return false;
for (String legacy : this.legacy)
if (parseLegacyMaterialName(legacy).equals(name)) return true;
for (String legacy : this.legacy) {
if (legacy.isEmpty()) break; // Left-side suggestion list
if (name.equals(legacy)) return true;
}
return false;
}
@ -1825,7 +1788,7 @@ public enum Materials {
*/
@SuppressWarnings("deprecation")
public int getId() {
if (this.isNew()) return -1;
if (this.data != 0 || (this.legacy.length != 0 && Integer.parseInt(this.legacy[0].substring(2)) >= 13)) return -1;
Material material = this.parseMaterial();
return material == null ? -1 : material.getId();
}
@ -1884,7 +1847,7 @@ public enum Materials {
/**
* Get a list of materials names that was previously used by older versions.
* If the material was added in a new version {@link #isNewVersion()},
* then the first element will indicate which version the material was added in {@link MinecraftVersion}.
* then the first element will indicate which version the material was added in.
*
* @return a list of legacy material names and the first element as the version the material was added in if new.
* @since 1.0.0
@ -1912,7 +1875,7 @@ public enum Materials {
* Parses an item from this Materials.
* Uses data values on older versions.
*
* @param suggest if true {@link #parseMaterial(boolean true)} will be used.
* @param suggest if true {@link #parseMaterial(boolean)} true will be used.
* @return an ItemStack with the same material (and data value if in older versions.)
* @see #setType(ItemStack)
* @since 2.0.0
@ -1945,10 +1908,12 @@ public enum Materials {
* @see #matchMaterials(String, byte)
* @since 2.0.0
*/
@SuppressWarnings("OptionalAssignedToNull")
@Nullable
public Material parseMaterial(boolean suggest) {
Material mat = PARSED_CACHE.getIfPresent(this);
if (mat != null) return mat;
Optional<Material> cache = PARSED_CACHE.getIfPresent(this);
if (cache != null) return cache.orElse(null);
Material mat;
if (!ISFLAT && this.isDuplicated()) mat = requestOldMaterial(suggest);
else {
@ -1956,7 +1921,7 @@ public enum Materials {
if (mat == null) mat = requestOldMaterial(suggest);
}
if (mat != null) PARSED_CACHE.put(this, mat);
if (mat != null) PARSED_CACHE.put(this, Optional.ofNullable(mat));
return mat;
}
@ -1971,27 +1936,22 @@ public enum Materials {
*/
@Nullable
private Material requestOldMaterial(boolean suggest) {
boolean noMaterialParse = this.isNew() && !suggest;
Material material;
for (int i = this.legacy.length - 1; i >= 0; i--) {
String legacy = this.legacy[i];
// Slash means it's just another name for the material in another version.
int index = legacy.indexOf('/');
if (index != -1) {
legacy = legacy.substring(0, index);
material = Material.getMaterial(legacy);
// Check if we've reached the end and the last string is our
// material version.
if (i == 0 && legacy.charAt(1) == '.') return null;
if (material != null) return material;
else continue;
// According to the suggestion list format, all the other names continuing
// from here are considered as a "suggestion"
// The empty string is an indicator for suggestion list on the left side.
if (legacy.isEmpty()) {
if (suggest) continue;
break;
}
// According to the suggestion format list, all the other names continuing
// from here are considered as a "suggestion" if there's no slash anymore.
// But continue if it's not even a new material.
if (noMaterialParse) return null;
material = Material.getMaterial(legacy);
Material material = Material.getMaterial(legacy);
if (material != null) return material;
}
return null;
@ -2008,7 +1968,7 @@ public enum Materials {
public boolean isSimilar(@Nonnull ItemStack item) {
Objects.requireNonNull(item, "Cannot compare with null ItemStack");
if (item.getType() != this.parseMaterial()) return false;
return (ISFLAT || this.isDamageable()) || item.getDurability() == this.data;
return ISFLAT || this.isDamageable() || item.getDurability() == this.data;
}
/**
@ -2021,7 +1981,13 @@ public enum Materials {
*/
@Nonnull
public List<String> getSuggestions() {
return this.isNew() ? Arrays.stream(this.legacy).skip(1).collect(Collectors.toList()) : new ArrayList<>();
if (this.legacy.length == 0 || this.legacy[0].charAt(1) != '.') return new ArrayList<>();
List<String> suggestions = new ArrayList<>();
for (String legacy : this.legacy) {
if (legacy.isEmpty()) break;
suggestions.add(legacy);
}
return suggestions;
}
/**
@ -2032,92 +1998,25 @@ public enum Materials {
* if you're going to parse and use the material later.
*
* @return true if the material exists in {@link Material} list.
* @see #isNew()
* @since 2.0.0
*/
public boolean isSupported() {
MinecraftVersion version = this.getMaterialVersion();
if (version != MinecraftVersion.UNKNOWN) return isVersionOrHigher(version);
int version = this.getMaterialVersion();
if (version != 0) return supports(version);
Material material = Material.getMaterial(this.name());
if (material == null) {
for (int i = this.legacy.length - 1; i != -1; i--) {
String legacy = this.legacy[i];
if (StringUtils.contains(legacy, '/')) continue;
material = Material.getMaterial(legacy);
if (material != null) break;
}
}
return material != null;
if (material != null) return true;
return requestOldMaterial(false) != null;
}
/**
* Checks if the material is newly added after the 1.13 Aquatic Update ({@link MinecraftVersion#V1_13}).
* Checks if the material is newly added after the 1.13 Aquatic Update.
*
* @return true if the material was newly added, otherwise false.
* @see #getMaterialVersion()
* @since 2.0.0
*/
public boolean isNew() {
return this.legacy.length != 0 && this.legacy[0].charAt(1) == '.';
}
/**
* Only major Minecraft versions related to most changes.
* The enum's order should not be changed.
*
* @since 2.0.0
*/
public enum MinecraftVersion {
/**
* 1.7 or below.
* Using {@link #getMaterialVersion()} it means 1.12 or below.
* https://minecraft.gamepedia.com/Java_Edition_1.7
*
* @since 2.0.0
*/
UNKNOWN,
/**
* Bountiful Update
* https://minecraft.gamepedia.com/Java_Edition_1.18
*
* @since 2.0.0
*/
V1_8,
/**
* Combat Update (Pitiful Update? 90% of the reason why that this class is a thing)
* https://minecraft.gamepedia.com/Java_Edition_1.9
*
* @since 2.0.0
*/
V1_9,
/**
* Aquatic Update
* Includes 1.10, 1.11 and 1.12
* https://minecraft.gamepedia.com/Java_Edition_1.13
*
* @since 2.0.0
*/
V1_13,
/**
* Village Pillage Update
* https://minecraft.gamepedia.com/Java_Edition_1.14
*
* @since 2.0.0
*/
V1_14,
/**
* Buzzy Bees Update
* https://minecraft.gamepedia.com/Java_Edition_1.15
*
* @since 3.0.0
*/
V1_15
public boolean isFromNewSystem() {
return this.legacy.length != 0 && Integer.parseInt(this.legacy[0].substring(2)) > 13;
}
}

View File

@ -1,7 +1,10 @@
package io.izzel.taboolib.util.lite;
import org.bukkit.util.NumberConversions;
import java.text.DecimalFormat;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
/**
* @Author
@ -9,19 +12,42 @@ import java.util.Random;
*/
public class Numbers {
private static Random random = new Random();
private static DecimalFormat doubleFormat = new DecimalFormat("#.##");
private static final DecimalFormat doubleFormat = new DecimalFormat("#.##");
public static int toInt(Object in) {
return NumberConversions.toInt(in);
}
public static long toLong(Object in) {
return NumberConversions.toLong(in);
}
public static short toShort(Object in) {
return NumberConversions.toShort(in);
}
public static float toFloat(Object in) {
return NumberConversions.toFloat(in);
}
public static double toDouble(Object in) {
return NumberConversions.toDouble(in);
}
public static byte toByte(Object in) {
return NumberConversions.toByte(in);
}
public static Random getRandom() {
return random;
return ThreadLocalRandom.current();
}
public static boolean random(double v) {
return random.nextDouble() <= v;
return ThreadLocalRandom.current().nextDouble() <= v;
}
public static int random(int v) {
return random.nextInt(v);
return ThreadLocalRandom.current().nextInt(v);
}
public static Double format(Double num) {
@ -29,15 +55,11 @@ public class Numbers {
}
public static int getRandomInteger(Number num1, Number num2) {
int min = Math.min(num1.intValue(), num2.intValue());
int max = Math.max(num1.intValue(), num2.intValue());
return (int) (random.nextDouble() * (max - min) + min);
return ThreadLocalRandom.current().nextInt(num1.intValue(), num2.intValue() + 1);
}
public static double getRandomDouble(Number num1, Number num2) {
double min = Math.min(num1.doubleValue(), num2.doubleValue());
double max = Math.max(num1.doubleValue(), num2.doubleValue());
return random.nextDouble() * (max - min) + min;
return ThreadLocalRandom.current().nextDouble(num1.doubleValue(), num2.doubleValue());
}
public static Boolean getBoolean(String str) {

View File

@ -46,6 +46,7 @@ import java.util.Random;
* @author DarkBlade12
* @version 1.8
*/
@Deprecated
public enum Particles {
BARRIER,
@ -105,10 +106,11 @@ public enum Particles {
WATER_WAKE,
;
private static int mcVersion = NumberConversions.toInt(Version.getBukkitVersion().split("_")[1]);
private static final int mcVersion = NumberConversions.toInt(Version.getBukkitVersion().split("_")[1]);
private org.bukkit.Particle bukkitParticle;
private final List<ParticleProperty> properties;
private int min, max;
private final int min;
private final int max;
Particles(ParticleProperty... properties) {
this(0, 0, properties);
@ -597,13 +599,13 @@ public enum Particles {
}
public static class Particle {
private static Random random = new Random();
private static final Random random = new Random();
private Particles effect;
private ParticleShape shape;
private OrdinaryColor color;
private final Particles effect;
private final ParticleShape shape;
private final OrdinaryColor color;
private byte typeCode;
private final byte typeCode;
public Particle(Particles effect, ParticleShape shape, OrdinaryColor color) {
this.effect = effect;
@ -742,7 +744,7 @@ public enum Particles {
private float offsetZ;
private final float speed;
private int amount;
private int size = 1;
private final int size = 1;
private final boolean longDistance;
private Object data;
private Object packet;