feat: generate particle data names automatically

This commit is contained in:
mworzala 2024-05-30 12:26:40 -04:00 committed by Matt Worzala
parent 8b82651f5b
commit 7fef89253e
20 changed files with 229 additions and 93 deletions

View File

@ -23,6 +23,7 @@ allprojects {
description = shortDescription
repositories {
mavenLocal()
mavenCentral()
}

View File

@ -2,8 +2,8 @@ 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 net.minestom.codegen.recipe.RecipeTypeGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -34,7 +34,6 @@ public class Generators {
generator.generate(resource("enchantments.json"), "net.minestom.server.item.enchant", "Enchantment", "EnchantmentImpl", "Enchantments");
generator.generate(resource("potion_effects.json"), "net.minestom.server.potion", "PotionEffect", "PotionEffectImpl", "PotionEffects");
generator.generate(resource("potions.json"), "net.minestom.server.potion", "PotionType", "PotionTypeImpl", "PotionTypes");
generator.generate(resource("particles.json"), "net.minestom.server.particle", "Particle", "ParticleImpl", "Particles");
generator.generate(resource("sounds.json"), "net.minestom.server.sound", "SoundEvent", "BuiltinSoundEvent", "SoundEvents");
generator.generate(resource("custom_statistics.json"), "net.minestom.server.statistic", "StatisticType", "StatisticTypeImpl", "StatisticTypes");
generator.generate(resource("attributes.json"), "net.minestom.server.entity.attribute", "Attribute", "AttributeImpl", "Attributes");

View File

@ -58,7 +58,7 @@ public class DyeColorGenerator extends MinestomCodeGenerator {
dyeColorEnum.addFields(
List.of(
FieldSpec.builder(networkBufferTypeCN, "NETWORK_TYPE", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.initializer("$T.fromEnum($T.class)", networkBufferCN, dyeColorCN)
.initializer("$T.Enum($T.class)", networkBufferCN, dyeColorCN)
.build(),
FieldSpec.builder(binaryTagSerializerTypeCN, "NBT_TYPE", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.initializer("$T.fromEnumStringable($T.class)", binaryTagSerializerCN, dyeColorCN)

View File

@ -2,7 +2,10 @@ package net.minestom.codegen.particle;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.squareup.javapoet.*;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.TypeSpec;
import net.minestom.codegen.MinestomCodeGenerator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -13,27 +16,14 @@ 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;
import java.util.regex.Pattern;
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;
@ -54,9 +44,6 @@ public class ParticleGenerator extends MinestomCodeGenerator {
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");
@ -73,12 +60,19 @@ public class ParticleGenerator extends MinestomCodeGenerator {
for (Map.Entry<String, JsonElement> particleIdObjectEntry : orderedParticleIdObjectEntries) {
final String key = particleIdObjectEntry.getKey();
ClassName fieldCN = PARTICLE_DATA_CLASS_NAMES.getOrDefault(key, particleCN);
final JsonObject value = particleIdObjectEntry.getValue().getAsJsonObject();
ClassName fieldCN = particleCN;
if (value.get("hasData").getAsBoolean()) {
// This particle has data, use the particle implementation class
fieldCN = ClassName.get("net.minestom.server.particle",
toPascalCase(key.replace("minecraft:", "")) + "Particle");
}
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();
@ -88,14 +82,6 @@ public class ParticleGenerator extends MinestomCodeGenerator {
.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(" ")
@ -103,4 +89,11 @@ public class ParticleGenerator extends MinestomCodeGenerator {
.build()),
outputFolder);
}
private static String toPascalCase(@NotNull String input) {
String camelCase = Pattern.compile("_([a-z])")
.matcher(input)
.replaceAll(m -> m.group(1).toUpperCase());
return camelCase.substring(0, 1).toUpperCase() + camelCase.substring(1);
}
}

View File

@ -55,7 +55,7 @@ public class RecipeTypeGenerator extends MinestomCodeGenerator {
recipeTypeEnum.addFields(
List.of(
FieldSpec.builder(networkBufferTypeCN, "NETWORK_TYPE", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.initializer("$T.fromEnum($T.class)", networkBufferCN, recipeTypeCN)
.initializer("$T.Enum($T.class)", networkBufferCN, recipeTypeCN)
.build(),
FieldSpec.builder(namespaceIdCN, "namespace", Modifier.PRIVATE, Modifier.FINAL).build()
)

View File

@ -3,7 +3,7 @@ metadata.format.version = "1.1"
[versions]
# Important dependencies
data = "1.20.5-rv2"
data = "1.20.5-dev"
adventure = "4.17.0"
jetbrainsAnnotations = "23.0.0"
slf4j = "2.0.7"

View File

@ -8,7 +8,7 @@ interface Particles {
BlockParticle BLOCK = (BlockParticle) ParticleImpl.get("minecraft:block");
BlockParticle BLOCK_MARKER = (BlockParticle) ParticleImpl.get("minecraft:block_marker");
BlockMarkerParticle BLOCK_MARKER = (BlockMarkerParticle) ParticleImpl.get("minecraft:block_marker");
Particle BUBBLE = ParticleImpl.get("minecraft:bubble");
@ -44,7 +44,7 @@ interface Particles {
Particle END_ROD = ParticleImpl.get("minecraft:end_rod");
Particle ENTITY_EFFECT = ParticleImpl.get("minecraft:entity_effect");
EntityEffectParticle ENTITY_EFFECT = (EntityEffectParticle) ParticleImpl.get("minecraft:entity_effect");
Particle EXPLOSION_EMITTER = ParticleImpl.get("minecraft:explosion_emitter");
@ -60,7 +60,7 @@ interface Particles {
Particle SONIC_BOOM = ParticleImpl.get("minecraft:sonic_boom");
BlockParticle FALLING_DUST = (BlockParticle) ParticleImpl.get("minecraft:falling_dust");
FallingDustParticle FALLING_DUST = (FallingDustParticle) ParticleImpl.get("minecraft:falling_dust");
Particle FIREWORK = ParticleImpl.get("minecraft:firework");
@ -214,7 +214,7 @@ interface Particles {
Particle VAULT_CONNECTION = ParticleImpl.get("minecraft:vault_connection");
Particle DUST_PILLAR = ParticleImpl.get("minecraft:dust_pillar");
DustPillarParticle DUST_PILLAR = (DustPillarParticle) ParticleImpl.get("minecraft:dust_pillar");
Particle OMINOUS_SPAWNING = ParticleImpl.get("minecraft:ominous_spawning");

View File

@ -14,6 +14,7 @@ import net.minestom.server.tag.Tag;
import net.minestom.server.tag.TagReadable;
import net.minestom.server.tag.TagWritable;
import net.minestom.server.utils.nbt.BinaryTagSerializer;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -33,9 +34,36 @@ import java.util.function.UnaryOperator;
public sealed interface ItemStack extends TagReadable, DataComponent.Holder, HoverEventSource<HoverEvent.ShowItem>
permits ItemStackImpl {
@NotNull NetworkBuffer.Type<ItemStack> NETWORK_TYPE = ItemStackImpl.NETWORK_TYPE;
@NotNull NetworkBuffer.Type<ItemStack> STRICT_NETWORK_TYPE = ItemStackImpl.STRICT_NETWORK_TYPE;
@NotNull BinaryTagSerializer<ItemStack> NBT_TYPE = ItemStackImpl.NBT_TYPE;
@NotNull NetworkBuffer.Type<ItemStack> NETWORK_TYPE = new NetworkBuffer.Type<>() {
@Override
public void write(@NotNull NetworkBuffer buffer, ItemStack value) {
if (value.isAir()) {
buffer.write(NetworkBuffer.VAR_INT, 0);
return;
}
buffer.write(NetworkBuffer.VAR_INT, value.amount());
buffer.write(NetworkBuffer.VAR_INT, value.material().id());
buffer.write(DataComponentMap.PATCH_NETWORK_TYPE, ((ItemStackImpl) value).components());
}
@Override
public ItemStack read(@NotNull NetworkBuffer buffer) {
int amount = buffer.read(NetworkBuffer.VAR_INT);
if (amount <= 0) return ItemStack.AIR;
Material material = Material.fromId(buffer.read(NetworkBuffer.VAR_INT));
DataComponentMap components = buffer.read(DataComponentMap.PATCH_NETWORK_TYPE);
return ItemStackImpl.create(material, amount, components);
}
};
@NotNull NetworkBuffer.Type<ItemStack> STRICT_NETWORK_TYPE = NETWORK_TYPE.map(itemStack -> {
Check.argCondition(itemStack.amount() == 0 || itemStack.isAir(), "ItemStack cannot be empty");
return itemStack;
}, itemStack -> {
Check.argCondition(itemStack.amount() == 0 || itemStack.isAir(), "ItemStack cannot be empty");
return itemStack;
});
@NotNull BinaryTagSerializer<ItemStack> NBT_TYPE = BinaryTagSerializer.COMPOUND.map(ItemStackImpl::fromCompound, ItemStackImpl::toCompound);
/**
* Constant AIR item. Should be used instead of 'null'.

View File

@ -4,9 +4,7 @@ import net.kyori.adventure.nbt.CompoundBinaryTag;
import net.minestom.server.component.DataComponent;
import net.minestom.server.component.DataComponentMap;
import net.minestom.server.item.component.CustomData;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.tag.Tag;
import net.minestom.server.utils.nbt.BinaryTagSerializer;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
@ -16,37 +14,6 @@ import java.util.function.Consumer;
record ItemStackImpl(Material material, int amount, DataComponentMap components) implements ItemStack {
static final NetworkBuffer.Type<ItemStack> NETWORK_TYPE = new NetworkBuffer.Type<>() {
@Override
public void write(@NotNull NetworkBuffer buffer, ItemStack value) {
if (value.isAir()) {
buffer.write(NetworkBuffer.VAR_INT, 0);
return;
}
buffer.write(NetworkBuffer.VAR_INT, value.amount());
buffer.write(NetworkBuffer.VAR_INT, value.material().id());
buffer.write(DataComponentMap.PATCH_NETWORK_TYPE, ((ItemStackImpl) value).components);
}
@Override
public ItemStack read(@NotNull NetworkBuffer buffer) {
int amount = buffer.read(NetworkBuffer.VAR_INT);
if (amount <= 0) return ItemStack.AIR;
Material material = Material.fromId(buffer.read(NetworkBuffer.VAR_INT));
DataComponentMap components = buffer.read(DataComponentMap.PATCH_NETWORK_TYPE);
return create(material, amount, components);
}
};
static final NetworkBuffer.Type<ItemStack> STRICT_NETWORK_TYPE = NETWORK_TYPE.map(itemStack -> {
Check.argCondition(itemStack.amount() == 0 || itemStack.isAir(), "ItemStack cannot be empty");
return itemStack;
}, itemStack -> {
Check.argCondition(itemStack.amount() == 0 || itemStack.isAir(), "ItemStack cannot be empty");
return itemStack;
});
static final BinaryTagSerializer<ItemStack> NBT_TYPE = BinaryTagSerializer.COMPOUND.map(ItemStackImpl::fromCompound, ItemStackImpl::toCompound);
static ItemStack create(Material material, int amount, DataComponentMap components) {
if (amount <= 0) return AIR;
return new ItemStackImpl(material, amount, components);
@ -132,7 +99,7 @@ record ItemStackImpl(Material material, int amount, DataComponentMap components)
return new Builder(material, amount, components.toBuilder());
}
private static @NotNull ItemStack fromCompound(@NotNull CompoundBinaryTag tag) {
static @NotNull ItemStack fromCompound(@NotNull CompoundBinaryTag tag) {
String id = tag.getString("id");
Material material = Material.fromNamespaceId(id);
Check.notNull(material, "Unknown material: {0}", id);
@ -141,7 +108,7 @@ record ItemStackImpl(Material material, int amount, DataComponentMap components)
return new ItemStackImpl(material, count, patch);
}
private static @NotNull CompoundBinaryTag toCompound(@NotNull ItemStack itemStack) {
static @NotNull CompoundBinaryTag toCompound(@NotNull ItemStack itemStack) {
CompoundBinaryTag.Builder tag = CompoundBinaryTag.builder();
tag.putString("id", itemStack.material().name());
tag.putInt("count", itemStack.amount());

View File

@ -16,8 +16,8 @@ import java.util.Collection;
public sealed interface Material extends StaticProtocolObject, Materials permits MaterialImpl {
NetworkBuffer.Type<Material> NETWORK_TYPE = MaterialImpl.NETWORK_TYPE;
BinaryTagSerializer<Material> NBT_TYPE = BinaryTagSerializer.lazy(() -> MaterialImpl.NBT_TYPE);
NetworkBuffer.Type<Material> NETWORK_TYPE = NetworkBuffer.VAR_INT.map(MaterialImpl::getId, Material::id);
BinaryTagSerializer<Material> NBT_TYPE = BinaryTagSerializer.STRING.map(MaterialImpl::getSafe, Material::name);
/**
* Returns the raw registry data for the material.

View File

@ -1,8 +1,6 @@
package net.minestom.server.item;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.registry.Registry;
import net.minestom.server.utils.nbt.BinaryTagSerializer;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
@ -11,9 +9,6 @@ record MaterialImpl(Registry.MaterialEntry registry) implements Material {
private static final Registry.Container<Material> CONTAINER = Registry.createStaticContainer(Registry.Resource.ITEMS,
(namespace, properties) -> new MaterialImpl(Registry.material(namespace, properties)));
static final NetworkBuffer.Type<Material> NETWORK_TYPE = NetworkBuffer.VAR_INT.map(MaterialImpl::getId, Material::id);
static final BinaryTagSerializer<Material> NBT_TYPE = BinaryTagSerializer.STRING.map(MaterialImpl::getSafe, Material::name);
static Material get(@NotNull String namespace) {
return CONTAINER.get(namespace);
}

View File

@ -8,7 +8,6 @@ import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.network.packet.server.play.data.WorldPos;
import net.minestom.server.particle.Particle;
import net.minestom.server.particle.data.ParticleData;
import net.minestom.server.registry.DynamicRegistry;
import net.minestom.server.registry.ProtocolObject;
import net.minestom.server.registry.Registries;

View File

@ -46,7 +46,7 @@ public record ParticlePacket(@NotNull Particle particle, boolean longDistance, d
Particle particle = Particle.fromId(reader.read(VAR_INT));
Objects.requireNonNull(particle);
return new ParticlePacket(particle.readData(reader), 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);
}
@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 BlockMarkerParticle extends ParticleImpl {
private final @NotNull Block block;
BlockMarkerParticle(@NotNull NamespaceID namespace, int id, @NotNull Block block) {
super(namespace, id);
this.block = block;
}
@Contract(pure = true)
public @NotNull BlockMarkerParticle withBlock(@NotNull Block block) {
return new BlockMarkerParticle(namespace(), id(), block);
}
public @NotNull Block block() {
return block;
}
@Override
public @NotNull BlockMarkerParticle 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,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 DustPillarParticle extends ParticleImpl {
private final @NotNull Block block;
DustPillarParticle(@NotNull NamespaceID namespace, int id, @NotNull Block block) {
super(namespace, id);
this.block = block;
}
@Contract(pure = true)
public @NotNull DustPillarParticle withBlock(@NotNull Block block) {
return new DustPillarParticle(namespace(), id(), block);
}
public @NotNull Block block() {
return block;
}
@Override
public @NotNull DustPillarParticle 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,36 @@
package net.minestom.server.particle;
import net.kyori.adventure.util.RGBLike;
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 EntityEffectParticle extends ParticleImpl {
private final @NotNull RGBLike color;
EntityEffectParticle(@NotNull NamespaceID namespace, int id, @NotNull RGBLike color) {
super(namespace, id);
this.color = color;
}
@Contract(pure = true)
public @NotNull EntityEffectParticle withColor(@NotNull RGBLike color) {
return new EntityEffectParticle(namespace(), id(), color);
}
public @NotNull RGBLike color() {
return color;
}
@Override
public @NotNull EntityEffectParticle readData(@NotNull NetworkBuffer reader) {
return withColor(reader.read(Color.NETWORK_TYPE));
}
@Override
public void writeData(@NotNull NetworkBuffer writer) {
writer.write(Color.NETWORK_TYPE, color);
}
}

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 FallingDustParticle extends ParticleImpl {
private final @NotNull Block block;
FallingDustParticle(@NotNull NamespaceID namespace, int id, @NotNull Block block) {
super(namespace, id);
this.block = block;
}
@Contract(pure = true)
public @NotNull FallingDustParticle withBlock(@NotNull Block block) {
return new FallingDustParticle(namespace(), id(), block);
}
public @NotNull Block block() {
return block;
}
@Override
public @NotNull FallingDustParticle 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

@ -25,11 +25,11 @@ public final class ItemParticle extends ParticleImpl {
@Override
public @NotNull ItemParticle readData(@NotNull NetworkBuffer reader) {
return this.withItem(reader.read(NetworkBuffer.ITEM));
return this.withItem(reader.read(ItemStack.NETWORK_TYPE));
}
@Override
public void writeData(@NotNull NetworkBuffer writer) {
writer.write(NetworkBuffer.ITEM, item);
writer.write(ItemStack.NETWORK_TYPE, item);
}
}

View File

@ -9,11 +9,9 @@ import net.minestom.server.registry.Registry;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.util.Collection;
sealed class ParticleImpl implements Particle permits BlockParticle, DustParticle, DustColorTransitionParticle,
SculkChargeParticle, ItemParticle, VibrationParticle, ShriekParticle {
sealed class ParticleImpl implements Particle permits BlockMarkerParticle, BlockParticle, DustColorTransitionParticle, DustParticle, DustPillarParticle, EntityEffectParticle, FallingDustParticle, ItemParticle, SculkChargeParticle, ShriekParticle, VibrationParticle {
private static final Registry.Container<Particle> CONTAINER = Registry.createStaticContainer(Registry.Resource.PARTICLES,
(namespace, properties) -> defaultParticle(NamespaceID.from(namespace), properties.getInt("id")));
@ -67,7 +65,10 @@ sealed class ParticleImpl implements Particle permits BlockParticle, DustParticl
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:block" -> new BlockParticle(namespace, id, Block.STONE);
case "minecraft:block_marker" -> new BlockMarkerParticle(namespace, id, Block.STONE);
case "minecraft:falling_dust" -> new FallingDustParticle(namespace, id, Block.STONE);
case "minecraft:dust_pillar" -> new DustPillarParticle(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));
@ -75,6 +76,7 @@ sealed class ParticleImpl implements Particle permits BlockParticle, DustParticl
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);
case "minecraft:entity_effect" -> new EntityEffectParticle(namespace, id, new Color(0));
default -> new ParticleImpl(namespace, id);
};
}

View File

@ -5,11 +5,10 @@ import net.minestom.server.entity.metadata.other.AreaEffectCloudMeta;
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.*;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertNotNull;
public class AreaEffectCloudTest {
@Test
@ -102,7 +101,7 @@ public class AreaEffectCloudTest {
var gotParticle = meta.getParticle();
assert gotParticle == particle;
BlockParticle gotBlock = (BlockParticle) gotParticle;
BlockMarkerParticle gotBlock = (BlockMarkerParticle) gotParticle;
assert gotBlock.block() == block;
}