feat: improve particle api

This commit is contained in:
DeidaraMC 2024-04-24 23:09:59 -04:00 committed by Matt Worzala
parent 72ead6643b
commit 8b82651f5b
26 changed files with 570 additions and 479 deletions

View File

@ -3,6 +3,7 @@ package net.minestom.codegen;
import net.minestom.codegen.color.DyeColorGenerator;
import net.minestom.codegen.fluid.FluidGenerator;
import net.minestom.codegen.recipe.RecipeTypeGenerator;
import net.minestom.codegen.particle.ParticleGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -22,6 +23,7 @@ public class Generators {
// Special generators
new DyeColorGenerator(resource("dye_colors.json"), outputFolder).generate();
new RecipeTypeGenerator(resource("recipe_types.json"), outputFolder).generate();
new ParticleGenerator(resource("particles.json"), outputFolder).generate();
var generator = new CodeGenerator(outputFolder);

View File

@ -0,0 +1,106 @@
package net.minestom.codegen.particle;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.squareup.javapoet.*;
import net.minestom.codegen.MinestomCodeGenerator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.lang.model.element.Modifier;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
public class ParticleGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(ParticleGenerator.class);
// Maintenance note: all you should need to do is add/remove an entry on this map
private static final Map<String, ClassName> PARTICLE_DATA_CLASS_NAMES = Map.of(
"minecraft:block", ClassName.get("net.minestom.server.particle", "BlockParticle"),
"minecraft:block_marker", ClassName.get("net.minestom.server.particle", "BlockParticle"),
"minecraft:dust", ClassName.get("net.minestom.server.particle", "DustParticle"),
"minecraft:dust_color_transition", ClassName.get("net.minestom.server.particle", "DustColorTransitionParticle"),
"minecraft:falling_dust", ClassName.get("net.minestom.server.particle", "BlockParticle"),
"minecraft:sculk_charge", ClassName.get("net.minestom.server.particle", "SculkChargeParticle"),
"minecraft:item", ClassName.get("net.minestom.server.particle", "ItemParticle"),
"minecraft:vibration", ClassName.get("net.minestom.server.particle", "VibrationParticle"),
"minecraft:shriek", ClassName.get("net.minestom.server.particle", "ShriekParticle")
);
private final InputStream particlesFile;
private final File outputFolder;
public ParticleGenerator(@Nullable InputStream particlesFile, @NotNull File outputFolder) {
this.particlesFile = particlesFile;
this.outputFolder = outputFolder;
}
@Override
public void generate() {
if (particlesFile == null) {
LOGGER.error("Failed to find particles.json.");
LOGGER.error("Stopped code generation for particles.");
return;
}
if (!outputFolder.exists() && !outputFolder.mkdirs()) {
LOGGER.error("Output folder for code generation does not exist and could not be created.");
return;
}
// Notify us if not all unique particle data key ids were found and stop the generation
List<String> remainingParticleDataClasses = new ArrayList<>(PARTICLE_DATA_CLASS_NAMES.keySet());
// Important classes we use alot
ClassName particleCN = ClassName.get("net.minestom.server.particle", "Particle");
ClassName particleImplCN = ClassName.get("net.minestom.server.particle", "ParticleImpl");
JsonObject particleObject = GSON.fromJson(new InputStreamReader(particlesFile), JsonObject.class);
List<Map.Entry<String, JsonElement>> orderedParticleIdObjectEntries = particleObject.entrySet().stream()
.sorted(Comparator.comparingInt(o -> o.getValue().getAsJsonObject().get("id").getAsInt())).toList();
// Start code gen
ClassName particlesCN = ClassName.get("net.minestom.server.particle", "Particles");
TypeSpec.Builder particlesInterface = TypeSpec.interfaceBuilder(particlesCN)
.addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
for (Map.Entry<String, JsonElement> particleIdObjectEntry : orderedParticleIdObjectEntries) {
final String key = particleIdObjectEntry.getKey();
ClassName fieldCN = PARTICLE_DATA_CLASS_NAMES.getOrDefault(key, particleCN);
String cast = "";
if (!fieldCN.equals(particleCN)) {
// This is one of the unique particle classes with particle data, cast this
cast = "(" + fieldCN.simpleName() + ") ";
remainingParticleDataClasses.remove(key);
}
String fieldName = key.replace("minecraft:", "").toUpperCase();
particlesInterface.addField(FieldSpec.builder(fieldCN, fieldName)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.initializer("$L$T.get($S)", cast, particleImplCN, key).build());
}
if (!remainingParticleDataClasses.isEmpty()) {
remainingParticleDataClasses.forEach(key -> {
LOGGER.error("Could not find unique particle data key: " + key + " in particles.json, was this key name changed?");
});
LOGGER.error("Stopped code generation for particles.");
return;
}
writeFiles(
List.of(JavaFile.builder("net.minestom.server.particle", particlesInterface.build())
.indent(" ")
.skipJavaLangImports(true)
.build()),
outputFolder);
}
}

View File

@ -1,15 +1,14 @@
package net.minestom.server.particle;
/**
* Code autogenerated, do not edit!
* AUTOGENERATED by ParticleGenerator
*/
@SuppressWarnings("unused")
interface Particles {
Particle ANGRY_VILLAGER = ParticleImpl.get("minecraft:angry_villager");
Particle BLOCK = ParticleImpl.get("minecraft:block");
BlockParticle BLOCK = (BlockParticle) ParticleImpl.get("minecraft:block");
Particle BLOCK_MARKER = ParticleImpl.get("minecraft:block_marker");
BlockParticle BLOCK_MARKER = (BlockParticle) ParticleImpl.get("minecraft:block_marker");
Particle BUBBLE = ParticleImpl.get("minecraft:bubble");
@ -31,9 +30,9 @@ interface Particles {
Particle FALLING_WATER = ParticleImpl.get("minecraft:falling_water");
Particle DUST = ParticleImpl.get("minecraft:dust");
DustParticle DUST = (DustParticle) ParticleImpl.get("minecraft:dust");
Particle DUST_COLOR_TRANSITION = ParticleImpl.get("minecraft:dust_color_transition");
DustColorTransitionParticle DUST_COLOR_TRANSITION = (DustColorTransitionParticle) ParticleImpl.get("minecraft:dust_color_transition");
Particle EFFECT = ParticleImpl.get("minecraft:effect");
@ -61,7 +60,7 @@ interface Particles {
Particle SONIC_BOOM = ParticleImpl.get("minecraft:sonic_boom");
Particle FALLING_DUST = ParticleImpl.get("minecraft:falling_dust");
BlockParticle FALLING_DUST = (BlockParticle) ParticleImpl.get("minecraft:falling_dust");
Particle FIREWORK = ParticleImpl.get("minecraft:firework");
@ -75,7 +74,7 @@ interface Particles {
Particle SCULK_SOUL = ParticleImpl.get("minecraft:sculk_soul");
Particle SCULK_CHARGE = ParticleImpl.get("minecraft:sculk_charge");
SculkChargeParticle SCULK_CHARGE = (SculkChargeParticle) ParticleImpl.get("minecraft:sculk_charge");
Particle SCULK_CHARGE_POP = ParticleImpl.get("minecraft:sculk_charge_pop");
@ -93,9 +92,9 @@ interface Particles {
Particle INSTANT_EFFECT = ParticleImpl.get("minecraft:instant_effect");
Particle ITEM = ParticleImpl.get("minecraft:item");
ItemParticle ITEM = (ItemParticle) ParticleImpl.get("minecraft:item");
Particle VIBRATION = ParticleImpl.get("minecraft:vibration");
VibrationParticle VIBRATION = (VibrationParticle) ParticleImpl.get("minecraft:vibration");
Particle ITEM_SLIME = ParticleImpl.get("minecraft:item_slime");
@ -203,7 +202,7 @@ interface Particles {
Particle SCRAPE = ParticleImpl.get("minecraft:scrape");
Particle SHRIEK = ParticleImpl.get("minecraft:shriek");
ShriekParticle SHRIEK = (ShriekParticle) ParticleImpl.get("minecraft:shriek");
Particle EGG_CRACK = ParticleImpl.get("minecraft:egg_crack");

View File

@ -575,10 +575,8 @@ interface NetworkBufferTypeImpl<T> extends NetworkBuffer.Type<T> {
record ParticleType() implements NetworkBufferTypeImpl<Particle> {
@Override
public void write(@NotNull NetworkBuffer buffer, Particle value) {
Check.stateCondition(value.data() != null && !value.data().validate(value.id()), "Particle data {0} is not valid for this particle type {1}", value.data(), value.namespace());
Check.stateCondition(value.data() == null && ParticleData.requiresData(value.id()), "Particle data is required for this particle type {0}", value.namespace());
buffer.write(VAR_INT, value.id());
if (value.data() != null) value.data().write(buffer);
value.writeData(buffer);
}
@Override

View File

@ -5,28 +5,23 @@ import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.particle.Particle;
import net.minestom.server.particle.data.ParticleData;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import static net.minestom.server.network.NetworkBuffer.*;
public record ParticlePacket(int particleId, boolean longDistance, double x, double y, double z, float offsetX, float offsetY, float offsetZ, float maxSpeed, int particleCount, @Nullable ParticleData data) implements ServerPacket.Play {
public record ParticlePacket(@NotNull Particle particle, boolean longDistance, double x, double y, double z, float offsetX, float offsetY, float offsetZ, float maxSpeed, int particleCount) implements ServerPacket.Play {
private ParticlePacket(ParticlePacket copy) {
this(copy.particleId, copy.longDistance, copy.x, copy.y, copy.z, copy.offsetX, copy.offsetY, copy.offsetZ, copy.maxSpeed, copy.particleCount, copy.data);
this(copy.particle, copy.longDistance, copy.x, copy.y, copy.z, copy.offsetX, copy.offsetY, copy.offsetZ, copy.maxSpeed, copy.particleCount);
}
public ParticlePacket(@NotNull NetworkBuffer reader) {
this(readPacket(reader));
}
public ParticlePacket(@NotNull Particle particle, boolean longDistance, double x, double y, double z, float offsetX, float offsetY, float offsetZ, float maxSpeed, int particleCount) {
this(particle.id(), longDistance, x, y, z, offsetX, offsetY, offsetZ, maxSpeed, particleCount, particle.data());
}
public ParticlePacket(@NotNull Particle particle, double x, double y, double z, float offsetX, float offsetY, float offsetZ, float maxSpeed, int particleCount) {
this(particle.id(), false, x, y, z, offsetX, offsetY, offsetZ, maxSpeed, particleCount, particle.data());
this(particle, false, x, y, z, offsetX, offsetY, offsetZ, maxSpeed, particleCount);
}
public ParticlePacket(@NotNull Particle particle, boolean longDistance, @NotNull Point position, @NotNull Point offset, float maxSpeed, int particleCount) {
@ -48,17 +43,14 @@ public record ParticlePacket(int particleId, boolean longDistance, double x, dou
Float maxSpeed = reader.read(FLOAT);
Integer particleCount = reader.read(INT);
int particleId = reader.read(VAR_INT);
ParticleData data = ParticleData.read(particleId, reader);
Particle particle = Particle.fromId(reader.read(VAR_INT));
Objects.requireNonNull(particle);
return new ParticlePacket(particleId, longDistance, x, y, z, offsetX, offsetY, offsetZ, maxSpeed, particleCount, data);
return new ParticlePacket(particle.readData(reader), longDistance, x, y, z, offsetX, offsetY, offsetZ, maxSpeed, particleCount, data);
}
@Override
public void write(@NotNull NetworkBuffer writer) {
Check.stateCondition(data != null && !data.validate(particleId), "Particle data {0} is not valid for this particle type {1}", data, Particle.fromId(particleId));
Check.stateCondition(data == null && ParticleData.requiresData(particleId), "Particle data is required for this particle type {0}", Particle.fromId(particleId));
writer.write(BOOLEAN, longDistance);
writer.write(DOUBLE, x);
writer.write(DOUBLE, y);
@ -68,9 +60,8 @@ public record ParticlePacket(int particleId, boolean longDistance, double x, dou
writer.write(FLOAT, offsetZ);
writer.write(FLOAT, maxSpeed);
writer.write(INT, particleCount);
writer.write(VAR_INT, particleId);
if (data != null) data.write(writer);
writer.write(VAR_INT, particle.id());
particle.writeData(writer);
}
@Override

View File

@ -0,0 +1,39 @@
package net.minestom.server.particle;
import net.minestom.server.instance.block.Block;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.NamespaceID;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
public final class BlockParticle extends ParticleImpl {
private final @NotNull Block block;
BlockParticle(@NotNull NamespaceID namespace, int id, @NotNull Block block) {
super(namespace, id);
this.block = block;
}
@Contract(pure = true)
public @NotNull BlockParticle withBlock(@NotNull Block block) {
return new BlockParticle(namespace(), id(), block);
}
public @NotNull Block block() {
return block;
}
@Override
public @NotNull BlockParticle readData(@NotNull NetworkBuffer reader) {
short blockState = reader.read(NetworkBuffer.VAR_INT).shortValue();
Block block = Block.fromStateId(blockState);
Check.stateCondition(block == null, "Block state " + blockState + " is invalid");
return this.withBlock(block);
}
@Override
public void writeData(@NotNull NetworkBuffer writer) {
writer.write(NetworkBuffer.VAR_INT, (int) block.stateId());
}
}

View File

@ -0,0 +1,76 @@
package net.minestom.server.particle;
import net.minestom.server.color.Color;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
public final class DustColorTransitionParticle extends ParticleImpl {
private final @NotNull Color color;
private final float scale;
private final @NotNull Color transitionColor;
DustColorTransitionParticle(@NotNull NamespaceID namespace, int id, @NotNull Color color, float scale, @NotNull Color transitionColor) {
super(namespace, id);
this.color = color;
this.scale = scale;
this.transitionColor = transitionColor;
}
@Contract (pure = true)
public @NotNull DustColorTransitionParticle withProperties(@NotNull Color color, float scale, @NotNull Color transitionColor) {
return new DustColorTransitionParticle(namespace(), id(), color, scale, transitionColor);
}
@Contract(pure = true)
public @NotNull DustColorTransitionParticle withColor(@NotNull Color color) {
return this.withProperties(color, scale, transitionColor);
}
public @NotNull Color color() {
return color;
}
@Contract(pure = true)
public @NotNull DustColorTransitionParticle withScale(float scale) {
return this.withProperties(color, scale, transitionColor);
}
public float scale() {
return scale;
}
@Contract(pure = true)
public @NotNull DustColorTransitionParticle withTransitionColor(@NotNull Color transitionColor) {
return this.withProperties(color, scale, transitionColor);
}
public @NotNull Color transitionColor() {
return color;
}
@Override
public @NotNull DustColorTransitionParticle readData(@NotNull NetworkBuffer reader) {
return this.withProperties(new Color(
(int) (reader.read(NetworkBuffer.FLOAT) * 255),
(int) (reader.read(NetworkBuffer.FLOAT) * 255),
(int) (reader.read(NetworkBuffer.FLOAT) * 255)
), reader.read(NetworkBuffer.FLOAT), new Color(
(int) (reader.read(NetworkBuffer.FLOAT) * 255),
(int) (reader.read(NetworkBuffer.FLOAT) * 255),
(int) (reader.read(NetworkBuffer.FLOAT) * 255)
));
}
@Override
public void writeData(@NotNull NetworkBuffer writer) {
writer.write(NetworkBuffer.FLOAT, color.red() / 255f);
writer.write(NetworkBuffer.FLOAT, color.green() / 255f);
writer.write(NetworkBuffer.FLOAT, color.blue() / 255f);
writer.write(NetworkBuffer.FLOAT, scale);
writer.write(NetworkBuffer.FLOAT, transitionColor.red() / 255f);
writer.write(NetworkBuffer.FLOAT, transitionColor.green() / 255f);
writer.write(NetworkBuffer.FLOAT, transitionColor.blue() / 255f);
}
}

View File

@ -0,0 +1,58 @@
package net.minestom.server.particle;
import net.minestom.server.color.Color;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
public final class DustParticle extends ParticleImpl {
private final @NotNull Color color;
private final float scale;
DustParticle(@NotNull NamespaceID namespace, int id, @NotNull Color color, float scale) {
super(namespace, id);
this.color = color;
this.scale = scale;
}
@Contract (pure = true)
public @NotNull DustParticle withProperties(@NotNull Color color, float scale) {
return new DustParticle(namespace(), id(), color, scale);
}
@Contract(pure = true)
public @NotNull DustParticle withColor(@NotNull Color color) {
return this.withProperties(color, scale);
}
public @NotNull Color color() {
return color;
}
@Contract(pure = true)
public @NotNull DustParticle withScale(float scale) {
return this.withProperties(color, scale);
}
public float scale() {
return scale;
}
@Override
public @NotNull DustParticle readData(@NotNull NetworkBuffer reader) {
return this.withProperties(new Color(
(int) (reader.read(NetworkBuffer.FLOAT) * 255),
(int) (reader.read(NetworkBuffer.FLOAT) * 255),
(int) (reader.read(NetworkBuffer.FLOAT) * 255)
), reader.read(NetworkBuffer.FLOAT));
}
@Override
public void writeData(@NotNull NetworkBuffer writer) {
writer.write(NetworkBuffer.FLOAT, color.red() / 255f);
writer.write(NetworkBuffer.FLOAT, color.green() / 255f);
writer.write(NetworkBuffer.FLOAT, color.blue() / 255f);
writer.write(NetworkBuffer.FLOAT, scale);
}
}

View File

@ -0,0 +1,35 @@
package net.minestom.server.particle;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
public final class ItemParticle extends ParticleImpl {
private final @NotNull ItemStack item;
ItemParticle(@NotNull NamespaceID namespace, int id, @NotNull ItemStack item) {
super(namespace, id);
this.item = item;
}
@Contract(pure = true)
public @NotNull ItemParticle withItem(@NotNull ItemStack item) {
return new ItemParticle(namespace(), id(), item);
}
public @NotNull ItemStack item() {
return item;
}
@Override
public @NotNull ItemParticle readData(@NotNull NetworkBuffer reader) {
return this.withItem(reader.read(NetworkBuffer.ITEM));
}
@Override
public void writeData(@NotNull NetworkBuffer writer) {
writer.write(NetworkBuffer.ITEM, item);
}
}

View File

@ -1,6 +1,6 @@
package net.minestom.server.particle;
import net.minestom.server.particle.data.ParticleData;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.registry.StaticProtocolObject;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
@ -9,7 +9,6 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collection;
public sealed interface Particle extends StaticProtocolObject, Particles permits ParticleImpl {
static @NotNull Collection<@NotNull Particle> values() {
return ParticleImpl.values();
}
@ -26,6 +25,7 @@ public sealed interface Particle extends StaticProtocolObject, Particles permits
return ParticleImpl.getId(id);
}
@NotNull Particle withData(@Nullable ParticleData data);
@Nullable ParticleData data();
@NotNull Particle readData(@NotNull NetworkBuffer reader);
void writeData(@NotNull NetworkBuffer writer);
}

View File

@ -1,16 +1,21 @@
package net.minestom.server.particle;
import net.minestom.server.particle.data.ParticleData;
import net.minestom.server.color.Color;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.registry.Registry;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.util.Collection;
record ParticleImpl(NamespaceID namespace, int id, ParticleData data) implements Particle {
sealed class ParticleImpl implements Particle permits BlockParticle, DustParticle, DustColorTransitionParticle,
SculkChargeParticle, ItemParticle, VibrationParticle, ShriekParticle {
private static final Registry.Container<Particle> CONTAINER = Registry.createStaticContainer(Registry.Resource.PARTICLES,
(namespace, properties) -> new ParticleImpl(NamespaceID.from(namespace), properties.getInt("id"), ParticleData.defaultData(namespace)));
(namespace, properties) -> defaultParticle(NamespaceID.from(namespace), properties.getInt("id")));
static Particle get(@NotNull String namespace) {
return CONTAINER.get(namespace);
@ -28,17 +33,49 @@ record ParticleImpl(NamespaceID namespace, int id, ParticleData data) implements
return CONTAINER.values();
}
public @NotNull Particle withData(@Nullable ParticleData object) {
return new ParticleImpl(namespace, id, object);
private final NamespaceID namespace;
private final int id;
ParticleImpl(@NotNull NamespaceID namespace, int id) {
this.namespace = namespace;
this.id = id;
}
@Override
public @Nullable ParticleData data() {
return data;
public @NotNull NamespaceID namespace() {
return namespace;
}
@Override
public int id() {
return id;
}
@Override
public @NotNull ParticleImpl readData(@NotNull NetworkBuffer reader) {
return this;
}
@Override
public void writeData(@NotNull NetworkBuffer writer) {
}
@Override
public @NotNull String toString() {
return name();
}
private static Particle defaultParticle(@NotNull NamespaceID namespace, int id) {
return switch (namespace.asString()) {
case "minecraft:block", "minecraft:block_marker", "minecraft:falling_dust" -> new BlockParticle(namespace, id, Block.STONE);
case "minecraft:dust" -> new DustParticle(namespace, id, new Color(255, 255, 255), 1);
case "minecraft:dust_color_transition" -> new DustColorTransitionParticle(namespace, id, new Color(255, 255, 255),
1, new Color(255, 255, 255));
case "minecraft:sculk_charge" -> new SculkChargeParticle(namespace, id, 0);
case "minecraft:item" -> new ItemParticle(namespace, id, ItemStack.AIR);
case "minecraft:vibration" -> new VibrationParticle(namespace, id, VibrationParticle.SourceType.BLOCK, Vec.ZERO, 0, 0, 0);
case "minecraft:shriek" -> new ShriekParticle(namespace, id, 0);
default -> new ParticleImpl(namespace, id);
};
}
}

View File

@ -0,0 +1,35 @@
package net.minestom.server.particle;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
public final class SculkChargeParticle extends ParticleImpl {
private final float roll;
SculkChargeParticle(@NotNull NamespaceID namespace, int id, float roll) {
super(namespace, id);
this.roll = roll;
}
@Contract(pure = true)
public @NotNull SculkChargeParticle withRoll(float roll) {
return new SculkChargeParticle(namespace(), id(), roll);
}
public float roll() {
return roll;
}
@Override
public @NotNull SculkChargeParticle readData(@NotNull NetworkBuffer reader) {
return this.withRoll(reader.read(NetworkBuffer.FLOAT));
}
@Override
public void writeData(@NotNull NetworkBuffer writer) {
writer.write(NetworkBuffer.FLOAT, roll);
}
}

View File

@ -0,0 +1,34 @@
package net.minestom.server.particle;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
public final class ShriekParticle extends ParticleImpl {
private final int delay;
ShriekParticle(@NotNull NamespaceID namespace, int id, int delay) {
super(namespace, id);
this.delay = delay;
}
@Contract(pure = true)
public @NotNull ShriekParticle withDelay(int delay) {
return new ShriekParticle(namespace(), id(), delay);
}
public int delay() {
return delay;
}
@Override
public @NotNull ShriekParticle readData(@NotNull NetworkBuffer reader) {
return this.withDelay(reader.read(NetworkBuffer.VAR_INT));
}
@Override
public void writeData(@NotNull NetworkBuffer writer) {
writer.write(NetworkBuffer.VAR_INT, delay);
}
}

View File

@ -0,0 +1,93 @@
package net.minestom.server.particle;
import net.minestom.server.coordinate.Point;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
public final class VibrationParticle extends ParticleImpl {
private final SourceType sourceType;
private final Point sourceBlockPosition;
private final int sourceEntityId;
private final float sourceEntityEyeHeight;
private final int travelTicks;
VibrationParticle(@NotNull NamespaceID namespace, int id, @NotNull SourceType sourceType, @Nullable Point sourceBlockPosition,
int sourceEntityId, float sourceEntityEyeHeight, int travelTicks) {
super(namespace, id);
this.sourceType = sourceType;
this.sourceBlockPosition = sourceBlockPosition;
this.sourceEntityId = sourceEntityId;
this.sourceEntityEyeHeight = sourceEntityEyeHeight;
this.travelTicks = travelTicks;
}
@Contract(pure = true)
public @NotNull VibrationParticle withProperties(@NotNull SourceType sourceType, @Nullable Point sourceBlockPosition,
int sourceEntityId, float sourceEntityEyeHeight, int travelTicks) {
return new VibrationParticle(namespace(), id(), sourceType, sourceBlockPosition, sourceEntityId, sourceEntityEyeHeight, travelTicks);
}
@Contract(pure = true)
public @NotNull VibrationParticle withSourceBlockPosition(@Nullable Point sourceBlockPosition, int travelTicks) {
return new VibrationParticle(namespace(), id(), SourceType.BLOCK, sourceBlockPosition, sourceEntityId, sourceEntityEyeHeight, travelTicks);
}
@Contract(pure = true)
public @NotNull VibrationParticle withSourceEntity(int sourceEntityId, float sourceEntityEyeHeight, int travelTicks) {
return new VibrationParticle(namespace(), id(), SourceType.ENTITY, sourceBlockPosition, sourceEntityId, sourceEntityEyeHeight, travelTicks);
}
public @NotNull SourceType sourceType() {
return sourceType;
}
public @Nullable Point sourceBlockPosition() {
return sourceBlockPosition;
}
public int sourceEntityId() {
return sourceEntityId;
}
public float sourceEntityEyeHeight() {
return sourceEntityEyeHeight;
}
public int travelTick() {
return travelTicks;
}
@Override
public @NotNull VibrationParticle readData(@NotNull NetworkBuffer reader) {
SourceType type = reader.readEnum(SourceType.class);
if (type == SourceType.BLOCK) {
return this.withSourceBlockPosition(reader.read(NetworkBuffer.BLOCK_POSITION), reader.read(NetworkBuffer.VAR_INT));
} else {
return this.withSourceEntity(reader.read(NetworkBuffer.VAR_INT), reader.read(NetworkBuffer.FLOAT), reader.read(NetworkBuffer.VAR_INT));
}
}
@Override
public void writeData(@NotNull NetworkBuffer writer) {
writer.writeEnum(SourceType.class, sourceType);
if (sourceType == SourceType.BLOCK) {
Objects.requireNonNull(sourceBlockPosition);
writer.write(NetworkBuffer.BLOCK_POSITION, sourceBlockPosition);
writer.write(NetworkBuffer.VAR_INT, travelTicks);
} else {
writer.write(NetworkBuffer.VAR_INT, sourceEntityId);
writer.write(NetworkBuffer.FLOAT, sourceEntityEyeHeight);
writer.write(NetworkBuffer.VAR_INT, travelTicks);
}
}
public enum SourceType {
BLOCK, ENTITY
}
}

View File

@ -1,34 +0,0 @@
package net.minestom.server.particle.data;
import net.minestom.server.instance.block.Block;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.particle.Particle;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
public record BlockMarkerParticleData(@NotNull Block block) implements ParticleData {
BlockMarkerParticleData(NetworkBuffer reader) {
this(read(reader));
}
BlockMarkerParticleData() {
this(Block.STONE);
}
private static Block read(NetworkBuffer reader) {
short blockState = reader.read(NetworkBuffer.VAR_INT).shortValue();
Block block = Block.fromStateId(blockState);
Check.stateCondition(block == null, "Block state " + blockState + " is invalid");
return block;
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(NetworkBuffer.VAR_INT, (int) block.stateId());
}
@Override
public boolean validate(int particleId) {
return particleId == Particle.BLOCK_MARKER.id();
}
}

View File

@ -1,34 +0,0 @@
package net.minestom.server.particle.data;
import net.minestom.server.instance.block.Block;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.particle.Particle;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
public record BlockParticleData(Block block) implements ParticleData {
BlockParticleData(NetworkBuffer reader) {
this(read(reader));
}
BlockParticleData() {
this(Block.STONE);
}
private static Block read(NetworkBuffer reader) {
short blockState = reader.read(NetworkBuffer.VAR_INT).shortValue();
Block block = Block.fromStateId(blockState);
Check.stateCondition(block == null, "Block state " + blockState + " is invalid");
return block;
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(NetworkBuffer.VAR_INT, (int) block.stateId());
}
@Override
public boolean validate(int particleId) {
return particleId == Particle.BLOCK.id();
}
}

View File

@ -1,46 +0,0 @@
package net.minestom.server.particle.data;
import net.kyori.adventure.util.RGBLike;
import net.minestom.server.color.Color;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.particle.Particle;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
public record DustColorTransitionParticleData(@NotNull RGBLike from, float scale, @NotNull RGBLike to) implements ParticleData {
public DustColorTransitionParticleData {
Check.argCondition(scale < 0.01 || scale > 4, "scale must be between 0.01 and 4: was {0}", scale);
}
DustColorTransitionParticleData() {
this(new Color(255, 255, 255), 1, new Color(255, 255, 255));
}
DustColorTransitionParticleData(NetworkBuffer buffer) {
this(new Color(
(int) (buffer.read(NetworkBuffer.FLOAT) * 255),
(int) (buffer.read(NetworkBuffer.FLOAT) * 255),
(int) (buffer.read(NetworkBuffer.FLOAT) * 255)
), buffer.read(NetworkBuffer.FLOAT), new Color(
(int) (buffer.read(NetworkBuffer.FLOAT) * 255),
(int) (buffer.read(NetworkBuffer.FLOAT) * 255),
(int) (buffer.read(NetworkBuffer.FLOAT) * 255)
));
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(NetworkBuffer.FLOAT, from.red() / 255f);
writer.write(NetworkBuffer.FLOAT, from.green() / 255f);
writer.write(NetworkBuffer.FLOAT, from.blue() / 255f);
writer.write(NetworkBuffer.FLOAT, scale);
writer.write(NetworkBuffer.FLOAT, to.red() / 255f);
writer.write(NetworkBuffer.FLOAT, to.green() / 255f);
writer.write(NetworkBuffer.FLOAT, to.blue() / 255f);
}
@Override
public boolean validate(int particleId) {
return particleId == Particle.DUST_COLOR_TRANSITION.id();
}
}

View File

@ -1,39 +0,0 @@
package net.minestom.server.particle.data;
import net.kyori.adventure.util.RGBLike;
import net.minestom.server.color.Color;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.particle.Particle;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
public record DustParticleData(@NotNull RGBLike color, float scale) implements ParticleData {
public DustParticleData {
Check.argCondition(scale < 0.01 || scale > 4, "scale must be between 0.01 and 4");
}
DustParticleData(NetworkBuffer buffer) {
this(new Color(
(int) (buffer.read(NetworkBuffer.FLOAT) * 255),
(int) (buffer.read(NetworkBuffer.FLOAT) * 255),
(int) (buffer.read(NetworkBuffer.FLOAT) * 255)
), buffer.read(NetworkBuffer.FLOAT));
}
DustParticleData() {
this(new Color(255, 255, 255), 1);
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(NetworkBuffer.FLOAT, color.red() / 255f);
writer.write(NetworkBuffer.FLOAT, color.green() / 255f);
writer.write(NetworkBuffer.FLOAT, color.blue() / 255f);
writer.write(NetworkBuffer.FLOAT, scale);
}
@Override
public boolean validate(int particleId) {
return particleId == Particle.DUST.id();
}
}

View File

@ -1,34 +0,0 @@
package net.minestom.server.particle.data;
import net.minestom.server.instance.block.Block;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.particle.Particle;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
public record FallingDustParticleData(Block block) implements ParticleData {
FallingDustParticleData(NetworkBuffer reader) {
this(read(reader));
}
FallingDustParticleData() {
this(Block.STONE);
}
private static Block read(NetworkBuffer reader) {
short blockState = reader.read(NetworkBuffer.VAR_INT).shortValue();
Block block = Block.fromStateId(blockState);
Check.stateCondition(block == null, "Block state {0} is invalid", blockState);
return block;
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(NetworkBuffer.VAR_INT, (int) block.stateId());
}
@Override
public boolean validate(int particleId) {
return particleId == Particle.FALLING_DUST.id();
}
}

View File

@ -1,27 +0,0 @@
package net.minestom.server.particle.data;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.particle.Particle;
import org.jetbrains.annotations.NotNull;
public record ItemParticleData(ItemStack item) implements ParticleData {
ItemParticleData(NetworkBuffer reader) {
this(reader.read(ItemStack.NETWORK_TYPE));
}
ItemParticleData() {
this(ItemStack.of(Material.STONE));
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(ItemStack.NETWORK_TYPE, item);
}
@Override
public boolean validate(int particleId) {
return particleId == Particle.ITEM.id();
}
}

View File

@ -1,51 +0,0 @@
package net.minestom.server.particle.data;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.particle.Particle;
import org.jetbrains.annotations.NotNull;
public interface ParticleData {
void write(@NotNull NetworkBuffer writer);
static ParticleData read(int particleId, NetworkBuffer reader) {
if (particleId == Particle.BLOCK.id()) return new BlockParticleData(reader);
else if (particleId == Particle.BLOCK_MARKER.id()) return new BlockMarkerParticleData(reader);
else if (particleId == Particle.DUST.id()) return new DustParticleData(reader);
else if (particleId == Particle.DUST_COLOR_TRANSITION.id()) return new DustColorTransitionParticleData(reader);
else if (particleId == Particle.FALLING_DUST.id()) return new FallingDustParticleData(reader);
else if (particleId == Particle.SCULK_CHARGE.id()) return new SculkChargeParticleData(reader);
else if (particleId == Particle.ITEM.id()) return new ItemParticleData(reader);
else if (particleId == Particle.VIBRATION.id()) return new VibrationParticleData(reader);
else if (particleId == Particle.SHRIEK.id()) return new ShriekParticleData(reader);
else return null;
}
boolean validate(int particleId);
static boolean requiresData(int particleId) {
return particleId == Particle.BLOCK.id()
|| particleId == Particle.BLOCK_MARKER.id()
|| particleId == Particle.DUST.id()
|| particleId == Particle.DUST_COLOR_TRANSITION.id()
|| particleId == Particle.FALLING_DUST.id()
|| particleId == Particle.SCULK_CHARGE.id()
|| particleId == Particle.ITEM.id()
|| particleId == Particle.VIBRATION.id()
|| particleId == Particle.SHRIEK.id();
}
static ParticleData defaultData(String id) {
return switch (id) {
case "minecraft:block" -> new BlockParticleData();
case "minecraft:block_marker" -> new BlockMarkerParticleData();
case "minecraft:dust" -> new DustParticleData();
case "minecraft:dust_color_transition" -> new DustColorTransitionParticleData();
case "minecraft:falling_dust" -> new FallingDustParticleData();
case "minecraft:sculk_charge" -> new SculkChargeParticleData();
case "minecraft:item" -> new ItemParticleData();
case "minecraft:vibration" -> new VibrationParticleData();
case "minecraft:shriek" -> new ShriekParticleData();
default -> null;
};
}
}

View File

@ -1,25 +0,0 @@
package net.minestom.server.particle.data;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.particle.Particle;
import org.jetbrains.annotations.NotNull;
public record SculkChargeParticleData(float roll) implements ParticleData {
SculkChargeParticleData(NetworkBuffer reader) {
this(reader.read(NetworkBuffer.FLOAT));
}
SculkChargeParticleData() {
this(0);
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(NetworkBuffer.FLOAT, roll);
}
@Override
public boolean validate(int particleId) {
return particleId == Particle.SCULK_CHARGE.id();
}
}

View File

@ -1,25 +0,0 @@
package net.minestom.server.particle.data;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.particle.Particle;
import org.jetbrains.annotations.NotNull;
public record ShriekParticleData(int delay) implements ParticleData {
ShriekParticleData(NetworkBuffer reader) {
this(reader.read(NetworkBuffer.VAR_INT));
}
ShriekParticleData() {
this(0);
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(NetworkBuffer.VAR_INT, delay);
}
@Override
public boolean validate(int particleId) {
return particleId == Particle.SHRIEK.id();
}
}

View File

@ -1,55 +0,0 @@
package net.minestom.server.particle.data;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.particle.Particle;
import org.jetbrains.annotations.NotNull;
public record VibrationParticleData(@NotNull VibrationSource type, @NotNull Point source, int entityId, float entityEyeHeight, int ticks) implements ParticleData {
public enum VibrationSource {
BLOCK,
ENTITY
}
VibrationParticleData(NetworkBuffer buffer) {
this(read(buffer));
}
VibrationParticleData() {
this(VibrationSource.BLOCK, Vec.ZERO, 0, 0, 0);
}
private VibrationParticleData(VibrationParticleData copy) {
this(copy.type, copy.source, copy.entityId, copy.entityEyeHeight, copy.ticks);
}
private static VibrationParticleData read(NetworkBuffer buffer) {
VibrationSource type = buffer.readEnum(VibrationSource.class);
if (type == VibrationSource.BLOCK) {
return new VibrationParticleData(type, buffer.read(NetworkBuffer.BLOCK_POSITION), 0, 0, buffer.read(NetworkBuffer.VAR_INT));
} else {
return new VibrationParticleData(type, Vec.ZERO, buffer.read(NetworkBuffer.VAR_INT), buffer.read(NetworkBuffer.FLOAT), buffer.read(NetworkBuffer.VAR_INT));
}
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.writeEnum(VibrationSource.class, type);
if (type == VibrationSource.BLOCK) {
writer.write(NetworkBuffer.BLOCK_POSITION, source);
writer.write(NetworkBuffer.VAR_INT, ticks);
} else {
writer.write(NetworkBuffer.VAR_INT, entityId);
writer.write(NetworkBuffer.FLOAT, entityEyeHeight);
writer.write(NetworkBuffer.VAR_INT, ticks);
}
}
@Override
public boolean validate(int particleId) {
return particleId == Particle.VIBRATION.id();
}
}

View File

@ -6,8 +6,7 @@ import net.minestom.server.instance.block.Block;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.particle.Particle;
import net.minestom.server.particle.data.*;
import net.minestom.server.particle.*;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@ -23,7 +22,7 @@ public class AreaEffectCloudTest {
float size = 0.1f;
Particle particle = Particle.DUST.withData(new DustParticleData(new Color(r, g, b), size));
Particle particle = Particle.DUST.withProperties(new Color(r, g, b), size);
Entity entity = new Entity(EntityTypes.AREA_EFFECT_CLOUD);
AreaEffectCloudMeta meta = (AreaEffectCloudMeta) entity.getEntityMeta();
@ -32,7 +31,7 @@ public class AreaEffectCloudTest {
var gotParticle = meta.getParticle();
assert gotParticle == particle;
DustParticleData gotData = (DustParticleData) gotParticle.data();
DustParticle gotData = (DustParticle) gotParticle;
assertNotNull(gotData);
assert gotData.color().red() == r;
assert gotData.color().green() == g;
@ -55,7 +54,7 @@ public class AreaEffectCloudTest {
float size = 0.1f;
Particle particle = Particle.DUST_COLOR_TRANSITION.withData(new DustColorTransitionParticleData(new Color(r, g, b), size, new Color(r2, g2, b2)));
Particle particle = Particle.DUST_COLOR_TRANSITION.withProperties(new Color(r, g, b), size, new Color(r2, g2, b2));
Entity entity = new Entity(EntityTypes.AREA_EFFECT_CLOUD);
AreaEffectCloudMeta meta = (AreaEffectCloudMeta) entity.getEntityMeta();
@ -64,21 +63,21 @@ public class AreaEffectCloudTest {
var gotParticle = meta.getParticle();
assert gotParticle == particle;
DustColorTransitionParticleData gotData = (DustColorTransitionParticleData) gotParticle.data();
DustColorTransitionParticle gotData = (DustColorTransitionParticle) gotParticle;
assertNotNull(gotData);
assert gotData.from().red() == r;
assert gotData.from().green() == g;
assert gotData.from().blue() == b;
assert gotData.color().red() == r;
assert gotData.color().green() == g;
assert gotData.color().blue() == b;
assert gotData.scale() == size;
assert gotData.to().red() == r2;
assert gotData.to().green() == g2;
assert gotData.to().blue() == b2;
assert gotData.transitionColor().red() == r2;
assert gotData.transitionColor().green() == g2;
assert gotData.transitionColor().blue() == b2;
}
@Test
public void createWithBlockParticle() {
Block block = Block.GRASS_BLOCK;
Particle particle = Particle.BLOCK.withData(new BlockParticleData(block));
Particle particle = Particle.BLOCK.withBlock(block);
Entity entity = new Entity(EntityTypes.AREA_EFFECT_CLOUD);
AreaEffectCloudMeta meta = (AreaEffectCloudMeta) entity.getEntityMeta();
@ -87,14 +86,14 @@ public class AreaEffectCloudTest {
var gotParticle = meta.getParticle();
assert gotParticle == particle;
BlockParticleData gotBlock = (BlockParticleData) gotParticle.data();
BlockParticle gotBlock = (BlockParticle) gotParticle;
assert gotBlock.block() == block;
}
@Test
public void createWithBlockMarkerParticle() {
Block block = Block.GRASS_BLOCK;
Particle particle = Particle.BLOCK_MARKER.withData(new BlockMarkerParticleData(block));
Particle particle = Particle.BLOCK_MARKER.withBlock(block);
Entity entity = new Entity(EntityTypes.AREA_EFFECT_CLOUD);
AreaEffectCloudMeta meta = (AreaEffectCloudMeta) entity.getEntityMeta();
@ -103,13 +102,13 @@ public class AreaEffectCloudTest {
var gotParticle = meta.getParticle();
assert gotParticle == particle;
BlockMarkerParticleData gotBlock = (BlockMarkerParticleData) gotParticle.data();
BlockParticle gotBlock = (BlockParticle) gotParticle;
assert gotBlock.block() == block;
}
@Test
public void createWithItemParticle() {
Particle particle = Particle.ITEM.withData(new ItemParticleData(ItemStack.of(Material.ACACIA_LOG)));
Particle particle = Particle.ITEM.withItem(ItemStack.of(Material.ACACIA_LOG));
Entity entity = new Entity(EntityTypes.AREA_EFFECT_CLOUD);
AreaEffectCloudMeta meta = (AreaEffectCloudMeta) entity.getEntityMeta();
@ -118,13 +117,13 @@ public class AreaEffectCloudTest {
var gotParticle = meta.getParticle();
assert gotParticle == particle;
ItemParticleData gotBlock = (ItemParticleData) gotParticle.data();
ItemParticle gotBlock = (ItemParticle) gotParticle;
assert gotBlock.item().material() == Material.ACACIA_LOG;
}
@Test
public void createWithSculkChargeParticle() {
Particle particle = Particle.SCULK_CHARGE.withData(new SculkChargeParticleData(3));
Particle particle = Particle.SCULK_CHARGE.withRoll(3);
Entity entity = new Entity(EntityTypes.AREA_EFFECT_CLOUD);
AreaEffectCloudMeta meta = (AreaEffectCloudMeta) entity.getEntityMeta();
@ -133,32 +132,7 @@ public class AreaEffectCloudTest {
var gotParticle = meta.getParticle();
assert gotParticle == particle;
SculkChargeParticleData gotBlock = (SculkChargeParticleData) gotParticle.data();
SculkChargeParticle gotBlock = (SculkChargeParticle) gotParticle;
assert gotBlock.roll() == 3;
}
@Test
public void createWithDustParticleIncorrectType() {
Particle particle = Particle.DUST.withData(new FallingDustParticleData(Block.GLOWSTONE));
Entity entity = new Entity(EntityTypes.AREA_EFFECT_CLOUD);
AreaEffectCloudMeta meta = (AreaEffectCloudMeta) entity.getEntityMeta();
meta.setParticle(particle);
assertThrows(IllegalStateException.class, () -> entity.getMetadataPacket().write(new NetworkBuffer()));
}
@Test
public void createWithComposterParticle() {
Particle particle = Particle.COMPOSTER;
Entity entity = new Entity(EntityTypes.AREA_EFFECT_CLOUD);
AreaEffectCloudMeta meta = (AreaEffectCloudMeta) entity.getEntityMeta();
meta.setParticle(particle);
var gotParticle = meta.getParticle();
assert gotParticle == particle;
ParticleData gotBlock = gotParticle.data();
assertNull(gotBlock);
}
}

View File

@ -1,11 +1,7 @@
package net.minestom.server.particle;
import net.minestom.server.color.Color;
import net.minestom.server.instance.block.Block;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.network.packet.server.play.ParticlePacket;
import net.minestom.server.particle.data.BlockParticleData;
import net.minestom.server.particle.data.DustParticleData;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
@ -22,21 +18,9 @@ public class ParticleDataTest {
@Test
public void testDustParticleInvalid() {
var particle = Particle.DUST.withData(null);
var particle = Particle.DUST.withProperties(null, 1);
ParticlePacket packet = new ParticlePacket(particle, true, 0, 0, 0, 0, 0, 0, 0, 0);
assertThrows(IllegalStateException.class, () -> packet.write(new NetworkBuffer()));
}
@Test
public void testDustParticleWrongData() {
var particle = Particle.DUST.withData(new BlockParticleData(Block.STONE));
ParticlePacket packet = new ParticlePacket(particle, true, 0, 0, 0, 0, 0, 0, 0, 0);
assertThrows(IllegalStateException.class, () -> packet.write(new NetworkBuffer()));
}
@Test
public void testDustParticleWrongParameters() {
assertThrows(IllegalArgumentException.class, () -> Particle.DUST.withData(new DustParticleData(new Color(255, 255, 255), 0)));
assertThrows(NullPointerException.class, () -> packet.write(new NetworkBuffer()));
}
@Test
@ -55,7 +39,7 @@ public class ParticleDataTest {
@Test
public void invalidBlock() {
var particle = Particle.BLOCK.withData(new BlockParticleData(null));
var particle = Particle.BLOCK.withBlock(null);
ParticlePacket packet = new ParticlePacket(particle, true, 0, 0, 0, 0, 0, 0, 0, 0);
assertThrows(NullPointerException.class, () -> packet.write(new NetworkBuffer()));
}