#1279: Back Particle by a minecraft registry
By: DerFrZocker <derrieple@gmail.com>
This commit is contained in:
@@ -1,43 +1,280 @@
|
||||
package org.bukkit;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
import net.minecraft.core.particles.DustColorTransitionOptions;
|
||||
import net.minecraft.core.particles.ParticleParam;
|
||||
import net.minecraft.core.particles.ParticleParamBlock;
|
||||
import net.minecraft.core.particles.ParticleParamItem;
|
||||
import net.minecraft.core.particles.ParticleParamRedstone;
|
||||
import net.minecraft.core.particles.ParticleType;
|
||||
import net.minecraft.core.particles.SculkChargeParticleOptions;
|
||||
import net.minecraft.core.particles.ShriekParticleOption;
|
||||
import net.minecraft.core.particles.VibrationParticleOption;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.DynamicOpsNBT;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.resources.MinecraftKey;
|
||||
import net.minecraft.world.phys.Vec3D;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.craftbukkit.CraftParticle;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.MaterialData;
|
||||
import org.bukkit.support.AbstractTestingBase;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.joml.Vector3f;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.EnumSource;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
public class ParticleTest extends AbstractTestingBase {
|
||||
|
||||
@Test
|
||||
public void verifyMapping() {
|
||||
for (Particle bukkit : Particle.values()) {
|
||||
Object data = null;
|
||||
if (bukkit.getDataType().equals(ItemStack.class)) {
|
||||
data = new ItemStack(Material.STONE);
|
||||
} else if (bukkit.getDataType() == MaterialData.class) {
|
||||
data = new MaterialData(Material.LEGACY_STONE);
|
||||
} else if (bukkit.getDataType() == Particle.DustOptions.class) {
|
||||
data = new Particle.DustOptions(Color.BLACK, 0);
|
||||
} else if (bukkit.getDataType() == Particle.DustTransition.class) {
|
||||
data = new Particle.DustTransition(Color.BLACK, Color.WHITE, 0);
|
||||
} else if (bukkit.getDataType() == Vibration.class) {
|
||||
data = new Vibration(new Location(null, 0, 0, 0), new Vibration.Destination.BlockDestination(new Location(null, 0, 0, 0)), 0);
|
||||
} else if (bukkit.getDataType() == BlockData.class) {
|
||||
data = CraftBlockData.newData(Material.STONE, "");
|
||||
} else if (bukkit.getDataType() == Float.class) {
|
||||
data = 1.0F;
|
||||
} else if (bukkit.getDataType() == Integer.class) {
|
||||
data = 0;
|
||||
}
|
||||
public static Stream<Arguments> data() {
|
||||
return CraftRegistry.getMinecraftRegistry(Registries.PARTICLE_TYPE).keySet().stream().map(Arguments::of);
|
||||
}
|
||||
|
||||
assertNotNull(CraftParticle.toNMS(bukkit, data), "Missing Bukkit->NMS particle mapping for " + bukkit);
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
public void testBukkitValuesPresent(MinecraftKey minecraft) {
|
||||
// TODO: 10/19/23 Remove with enum PR, it is then no longer needed, since the enum PR has a extra test for this
|
||||
assertNotNull(Registry.PARTICLE_TYPE.get(CraftNamespacedKey.fromMinecraft(minecraft)), String.format("""
|
||||
No bukkit particle found for minecraft particle %s.
|
||||
Please add the particle to bukkit.
|
||||
""", minecraft));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@EnumSource(Particle.class)
|
||||
public void testMinecraftValuesPresent(Particle bukkit) {
|
||||
// TODO: 10/19/23 Remove with enum PR, it is then no longer needed, since the enum PR has a extra test for this
|
||||
bukkit = CraftParticle.convertLegacy(bukkit);
|
||||
Particle finalBukkit = bukkit;
|
||||
assertDoesNotThrow(() -> CraftParticle.bukkitToMinecraft(finalBukkit), String.format("""
|
||||
No minecraft particle found for bukkit particle %s.
|
||||
Please map the bukkit particle to a minecraft particle.
|
||||
""", bukkit.getKey()));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@EnumSource(Particle.class)
|
||||
public void testRightParticleParamCreation(Particle bukkit) {
|
||||
bukkit = CraftParticle.convertLegacy(bukkit);
|
||||
net.minecraft.core.particles.Particle<?> minecraft = CraftParticle.bukkitToMinecraft(bukkit);
|
||||
|
||||
if (bukkit.getDataType().equals(Void.class)) {
|
||||
testEmptyData(bukkit, minecraft);
|
||||
return;
|
||||
}
|
||||
for (net.minecraft.core.particles.Particle nms : BuiltInRegistries.PARTICLE_TYPE) {
|
||||
assertNotNull(CraftParticle.minecraftToBukkit(nms), "Missing NMS->Bukkit particle mapping for " + BuiltInRegistries.PARTICLE_TYPE.getKey(nms));
|
||||
|
||||
if (bukkit.getDataType().equals(Particle.DustOptions.class)) {
|
||||
testDustOption(bukkit, minecraft);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bukkit.getDataType().equals(ItemStack.class)) {
|
||||
testItemStack(bukkit, minecraft);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bukkit.getDataType().equals(BlockData.class)) {
|
||||
testBlockData(bukkit, minecraft);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bukkit.getDataType().equals(Particle.DustTransition.class)) {
|
||||
testDustTransition(bukkit, minecraft);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bukkit.getDataType().equals(Vibration.class)) {
|
||||
testVibration(bukkit, minecraft);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bukkit.getDataType().equals(Float.class)) {
|
||||
testFloat(bukkit, minecraft);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bukkit.getDataType().equals(Integer.class)) {
|
||||
testInteger(bukkit, minecraft);
|
||||
return;
|
||||
}
|
||||
|
||||
fail(String.format("""
|
||||
No test found for particle %s.
|
||||
Please add a test case for it here.
|
||||
""", bukkit.getKey()));
|
||||
}
|
||||
|
||||
private <T extends ParticleParam> void testEmptyData(Particle bukkit, net.minecraft.core.particles.Particle<T> minecraft) {
|
||||
createAndTest(bukkit, minecraft, null, ParticleType.class);
|
||||
}
|
||||
|
||||
private <T extends ParticleParam> void testDustOption(Particle bukkit, net.minecraft.core.particles.Particle<T> minecraft) {
|
||||
Particle.DustOptions dustOptions = new Particle.DustOptions(Color.fromRGB(236, 28, 36), 0.1205f);
|
||||
ParticleParamRedstone param = createAndTest(bukkit, minecraft, dustOptions, ParticleParamRedstone.class);
|
||||
|
||||
assertEquals(0.1205f, param.getScale(), 0.001, String.format("""
|
||||
Dust option scale for particle %s do not match.
|
||||
Did something change in the implementation or minecraft?
|
||||
""", bukkit.getKey()));
|
||||
|
||||
Vector3f expectedColor = new Vector3f(0.92549f, 0.1098f, 0.14117647f);
|
||||
assertTrue(expectedColor.equals(param.getColor(), 0.001f), String.format("""
|
||||
Dust option color for particle %s do not match.
|
||||
Did something change in the implementation or minecraft?
|
||||
Expected: %s.
|
||||
Got: %s.
|
||||
""", bukkit.getKey(), expectedColor, param.getColor())); // Print expected and got since we use assert true
|
||||
}
|
||||
|
||||
private <T extends ParticleParam> void testItemStack(Particle bukkit, net.minecraft.core.particles.Particle<T> minecraft) {
|
||||
ItemStack itemStack = new ItemStack(Material.STONE);
|
||||
ParticleParamItem param = createAndTest(bukkit, minecraft, itemStack, ParticleParamItem.class);
|
||||
|
||||
assertEquals(itemStack, CraftItemStack.asBukkitCopy(param.getItem()), String.format("""
|
||||
ItemStack for particle %s do not match.
|
||||
Did something change in the implementation or minecraft?
|
||||
""", bukkit.getKey()));
|
||||
}
|
||||
|
||||
private <T extends ParticleParam> void testBlockData(Particle bukkit, net.minecraft.core.particles.Particle<T> minecraft) {
|
||||
BlockData blockData = Bukkit.createBlockData(Material.STONE);
|
||||
ParticleParamBlock param = createAndTest(bukkit, minecraft, blockData, ParticleParamBlock.class);
|
||||
|
||||
assertEquals(blockData, CraftBlockData.fromData(param.getState()), String.format("""
|
||||
Block data for particle %s do not match.
|
||||
Did something change in the implementation or minecraft?
|
||||
""", bukkit.getKey()));
|
||||
}
|
||||
|
||||
private <T extends ParticleParam> void testDustTransition(Particle bukkit, net.minecraft.core.particles.Particle<T> minecraft) {
|
||||
Particle.DustTransition dustTransition = new Particle.DustTransition(Color.fromRGB(236, 28, 36), Color.fromRGB(107, 159, 181), 0.1205f);
|
||||
DustColorTransitionOptions param = createAndTest(bukkit, minecraft, dustTransition, DustColorTransitionOptions.class);
|
||||
|
||||
assertEquals(0.1205f, param.getScale(), 0.001, String.format("""
|
||||
Dust transition scale for particle %s do not match.
|
||||
Did something change in the implementation or minecraft?
|
||||
""", bukkit.getKey()));
|
||||
|
||||
Vector3f expectedFrom = new Vector3f(0.92549f, 0.1098f, 0.14117647f);
|
||||
assertTrue(expectedFrom.equals(param.getFromColor(), 0.001f), String.format("""
|
||||
Dust transition from color for particle %s do not match.
|
||||
Did something change in the implementation or minecraft?
|
||||
Expected: %s.
|
||||
Got: %s.
|
||||
""", bukkit.getKey(), expectedFrom, param.getColor())); // Print expected and got since we use assert true
|
||||
|
||||
Vector3f expectedTo = new Vector3f(0.4196f, 0.6235294f, 0.7098f);
|
||||
assertTrue(expectedTo.equals(param.getToColor(), 0.001f), String.format("""
|
||||
Dust transition to color for particle %s do not match.
|
||||
Did something change in the implementation or minecraft?
|
||||
Expected: %s.
|
||||
Got: %s.
|
||||
""", bukkit.getKey(), expectedTo, param.getColor())); // Print expected and got since we use assert true
|
||||
}
|
||||
|
||||
private <T extends ParticleParam> void testVibration(Particle bukkit, net.minecraft.core.particles.Particle<T> minecraft) {
|
||||
Vibration vibration = new Vibration(new Location(null, 3, 1, 4), new Vibration.Destination.BlockDestination(new Location(null, 1, 5, 9)), 265);
|
||||
VibrationParticleOption param = createAndTest(bukkit, minecraft, vibration, VibrationParticleOption.class);
|
||||
|
||||
assertEquals(265, param.getArrivalInTicks(), String.format("""
|
||||
Vibration ticks for particle %s do not match.
|
||||
Did something change in the implementation or minecraft?
|
||||
""", bukkit.getKey()));
|
||||
|
||||
Optional<Vec3D> pos = param.getDestination().getPosition(null);
|
||||
assertTrue(pos.isPresent(), String.format("""
|
||||
Vibration position for particle %s is not present.
|
||||
Did something change in the implementation or minecraft?
|
||||
""", bukkit.getKey()));
|
||||
|
||||
// Add 0.5 since it gets centered to the block
|
||||
assertEquals(new Vec3D(1.5, 5.5, 9.5), pos.get(), String.format("""
|
||||
Vibration position for particle %s do not match.
|
||||
Did something change in the implementation or minecraft?
|
||||
""", bukkit.getKey()));
|
||||
}
|
||||
|
||||
private <T extends ParticleParam> void testFloat(Particle bukkit, net.minecraft.core.particles.Particle<T> minecraft) {
|
||||
float role = 0.1205f;
|
||||
SculkChargeParticleOptions param = createAndTest(bukkit, minecraft, role, SculkChargeParticleOptions.class);
|
||||
|
||||
assertEquals(role, param.roll(), 0.001, String.format("""
|
||||
Float role for particle %s do not match.
|
||||
Did something change in the implementation or minecraft?
|
||||
""", bukkit.getKey()));
|
||||
}
|
||||
|
||||
private <T extends ParticleParam> void testInteger(Particle bukkit, net.minecraft.core.particles.Particle<T> minecraft) {
|
||||
int delay = 1205;
|
||||
ShriekParticleOption param = createAndTest(bukkit, minecraft, delay, ShriekParticleOption.class);
|
||||
|
||||
assertEquals(delay, param.getDelay(), String.format("""
|
||||
Integer delay for particle %s do not match.
|
||||
Did something change in the implementation or minecraft?
|
||||
""", bukkit.getKey()));
|
||||
}
|
||||
|
||||
private <D extends ParticleParam, T extends ParticleParam> D createAndTest(Particle bukkit, net.minecraft.core.particles.Particle<T> minecraft, Object data, Class<D> paramClass) {
|
||||
@SuppressWarnings("unchecked")
|
||||
T particleParam = (T) assertDoesNotThrow(() -> CraftParticle.createParticleParam(bukkit, data), String.format("""
|
||||
Could not create particle param for particle %s.
|
||||
This can indicated, that the default particle param is used, but the particle requires extra data.
|
||||
Or that something is wrong with the logic which creates the particle param with extra data.
|
||||
Check in CraftParticle if the conversion is still correct.
|
||||
""", bukkit.getKey()));
|
||||
|
||||
DataResult<NBTBase> encoded = assertDoesNotThrow(() -> minecraft.codec().encodeStart(DynamicOpsNBT.INSTANCE, particleParam),
|
||||
String.format("""
|
||||
Could not encoded particle param for particle %s.
|
||||
This can indicated, that the wrong particle param is created in CraftParticle.
|
||||
Particle param is of type %s.
|
||||
""", bukkit.getKey(), particleParam.getClass()));
|
||||
|
||||
Optional<DataResult.PartialResult<NBTBase>> encodeError = encoded.error();
|
||||
assertTrue(encodeError.isEmpty(), () -> String.format("""
|
||||
Could not encoded particle param for particle %s.
|
||||
This is possible because the wrong particle param is created in CraftParticle.
|
||||
Particle param is of type %s.
|
||||
Error message: %s.
|
||||
""", bukkit.getKey(), particleParam.getClass(), encoded.error().get().message()));
|
||||
|
||||
Optional<NBTBase> encodeResult = encoded.result();
|
||||
assertTrue(encodeResult.isPresent(), String.format("""
|
||||
Result is not present for particle %s.
|
||||
Even though there is also no error, this should not happen.
|
||||
Particle param is of type %s.
|
||||
""", bukkit.getKey(), particleParam.getClass()));
|
||||
|
||||
DataResult<T> decoded = minecraft.codec().parse(DynamicOpsNBT.INSTANCE, encodeResult.get());
|
||||
|
||||
Optional<DataResult.PartialResult<T>> decodeError = decoded.error();
|
||||
assertTrue(decodeError.isEmpty(), () -> String.format("""
|
||||
Could not decoded particle param for particle %s.
|
||||
This is possible because the wrong particle param is created in CraftParticle.
|
||||
Particle param is of type %s.
|
||||
Error message: %s.
|
||||
|
||||
|
||||
NBT data: %s.
|
||||
""", bukkit.getKey(), particleParam.getClass(), decodeError.get().message(), encodeResult.get()));
|
||||
|
||||
Optional<T> decodeResult = decoded.result();
|
||||
assertTrue(decodeResult.isPresent(), String.format("""
|
||||
Result is not present for particle %s.
|
||||
Even though there is also no error, this should not happen.
|
||||
Particle param is of type %s.
|
||||
""", bukkit.getKey(), particleParam.getClass()));
|
||||
|
||||
return assertInstanceOf(paramClass, decodeResult.get(), String.format("""
|
||||
Result is not of the right type for particle %s.
|
||||
""", bukkit.getKey()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user