Added support for dust color transition particles (#2455)

This commit is contained in:
RobotHanzo 2023-07-03 05:49:29 +08:00 committed by GitHub
parent 6ee4bbfe3d
commit 2c48b1c019
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 102 additions and 8 deletions

View File

@ -75,9 +75,31 @@ public class WrappedParticle<T> {
/** /**
* Gets this Particle's Bukkit/ProtocolLib data. The type of this data depends on the * Gets this Particle's Bukkit/ProtocolLib data. The type of this data depends on the
* {@link #getParticle() Particle type}. For Block particles it will be {@link WrappedBlockData}, * {@link #getParticle() Particle type}. Refer to the table below for the corresponding data types.
* for Item crack particles, it will be an {@link ItemStack}, and for redstone particles it will * <p>
* be {@link Particle.DustOptions} * <table border="1">
* <caption>Particle Data Types</caption>
* <tr>
* <td><b>Particle Type</b></td>
* <td><b>Particle Data Type</b></td>
* </tr>
* <tr>
* <td>Block particles (BLOCK_CRACK, BLOCK_DUST, FALLING_DUST)</td>
* <td>{@link WrappedBlockData}</td>
* </tr>
* <tr>
* <td>Item crack particles</td>
* <td>{@link ItemStack}</td>
* </tr>
* <tr>
* <td>Redstone particles</td>
* <td>{@link Particle.DustOptions}</td>
* </tr>
* <tr>
* <td>Dust color transition particles</td>
* <td>{@link Particle.DustTransition}</td>
* </tr>
* </table>
* *
* @return The particle data * @return The particle data
*/ */
@ -110,6 +132,9 @@ public class WrappedParticle<T> {
case REDSTONE: case REDSTONE:
data = getRedstone(handle); data = getRedstone(handle);
break; break;
case DUST_COLOR_TRANSITION:
data = getDustTransition(handle);
break;
default: default:
break; break;
} }
@ -133,7 +158,7 @@ public class WrappedParticle<T> {
private static Object getRedstone(Object handle) { private static Object getRedstone(Object handle) {
int r, g, b; int r, g, b;
float alpha; float size;
if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) { if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) {
StructureModifier<Object> modifier = new StructureModifier<>(handle.getClass()).withTarget(handle); StructureModifier<Object> modifier = new StructureModifier<>(handle.getClass()).withTarget(handle);
@ -142,7 +167,7 @@ public class WrappedParticle<T> {
r = (int) (rgb.x() * 255); r = (int) (rgb.x() * 255);
g = (int) (rgb.y() * 255); g = (int) (rgb.y() * 255);
b = (int) (rgb.z() * 255); b = (int) (rgb.z() * 255);
alpha = (float) modifier.withType(float.class).read(0); size = (float) modifier.withType(float.class).read(0);
} else if (MinecraftVersion.CAVES_CLIFFS_1.atOrAbove()) { } else if (MinecraftVersion.CAVES_CLIFFS_1.atOrAbove()) {
if (VECTOR_3FA == null) { if (VECTOR_3FA == null) {
VECTOR_3FA = MinecraftReflection.getLibraryClass("com.mojang.math.Vector3fa"); VECTOR_3FA = MinecraftReflection.getLibraryClass("com.mojang.math.Vector3fa");
@ -156,16 +181,67 @@ public class WrappedParticle<T> {
r = (int) (rgbModifier.<Float>withType(float.class).read(0) * 255); r = (int) (rgbModifier.<Float>withType(float.class).read(0) * 255);
g = (int) (rgbModifier.<Float>withType(float.class).read(1) * 255); g = (int) (rgbModifier.<Float>withType(float.class).read(1) * 255);
b = (int) (rgbModifier.<Float>withType(float.class).read(2) * 255); b = (int) (rgbModifier.<Float>withType(float.class).read(2) * 255);
alpha = (float) modifier.withType(float.class).read(0); size = (float) modifier.withType(float.class).read(0);
} else { } else {
StructureModifier<Float> modifier = new StructureModifier<>(handle.getClass()).withTarget(handle).withType(float.class); StructureModifier<Float> modifier = new StructureModifier<>(handle.getClass()).withTarget(handle).withType(float.class);
r = (int) (modifier.read(0) * 255); r = (int) (modifier.read(0) * 255);
g = (int) (modifier.read(1) * 255); g = (int) (modifier.read(1) * 255);
b = (int) (modifier.read(2) * 255); b = (int) (modifier.read(2) * 255);
alpha = modifier.read(3); size = modifier.read(3);
} }
return new Particle.DustOptions(Color.fromRGB(r, g, b), alpha); return new Particle.DustOptions(Color.fromRGB(r, g, b), size);
}
private static Object getDustTransition(Object handle) {
int fromR, fromG, fromB, toR, toG, toB;
float size;
if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) {
StructureModifier<Object> modifier = new StructureModifier<>(handle.getClass()).withTarget(handle);
org.joml.Vector3f toRGB = (org.joml.Vector3f) modifier.withType(org.joml.Vector3f.class).read(0);
org.joml.Vector3f fromRGB = (org.joml.Vector3f) modifier.withType(org.joml.Vector3f.class).read(1);
size = (float) modifier.withType(float.class).read(0);
fromR = (int) (fromRGB.x() * 255);
fromG = (int) (fromRGB.y() * 255);
fromB = (int) (fromRGB.z() * 255);
toR = (int) (toRGB.x() * 255);
toG = (int) (toRGB.y() * 255);
toB = (int) (toRGB.z() * 255);
} else if (MinecraftVersion.CAVES_CLIFFS_1.atOrAbove()) {
if (VECTOR_3FA == null) {
VECTOR_3FA = MinecraftReflection.getLibraryClass("com.mojang.math.Vector3fa");
}
StructureModifier<Object> modifier = new StructureModifier<>(handle.getClass()).withTarget(handle);
Object toRGB = modifier.withType(VECTOR_3FA).read(0);
Object fromRGB = modifier.withType(VECTOR_3FA).read(1);
size = (float) modifier.withType(float.class).read(0);
StructureModifier<Object> rgbModifier = new StructureModifier<>(VECTOR_3FA).withTarget(fromRGB);
StructureModifier<Object> rgbModifier2 = new StructureModifier<>(VECTOR_3FA).withTarget(toRGB);
fromR = (int) (rgbModifier.<Float>withType(float.class).read(0) * 255);
fromG = (int) (rgbModifier.<Float>withType(float.class).read(1) * 255);
fromB = (int) (rgbModifier.<Float>withType(float.class).read(2) * 255);
toR = (int) (rgbModifier2.<Float>withType(float.class).read(0) * 255);
toG = (int) (rgbModifier2.<Float>withType(float.class).read(1) * 255);
toB = (int) (rgbModifier2.<Float>withType(float.class).read(2) * 255);
} else {
StructureModifier<Float> modifier = new StructureModifier<>(handle.getClass()).withTarget(handle).withType(float.class);
toR = (int) (modifier.read(0) * 255);
toG = (int) (modifier.read(1) * 255);
toB = (int) (modifier.read(2) * 255);
size = modifier.read(3);
fromR = (int) (modifier.read(4) * 255);
fromG = (int) (modifier.read(5) * 255);
fromB = (int) (modifier.read(6) * 255);
}
return new Particle.DustTransition(Color.fromRGB(fromR, fromG, fromB), Color.fromRGB(toR, toG, toB), size);
} }
public static <T> WrappedParticle<T> create(Particle particle, T data) { public static <T> WrappedParticle<T> create(Particle particle, T data) {

View File

@ -10,6 +10,7 @@ import org.bukkit.Color;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Particle; import org.bukkit.Particle;
import org.bukkit.Particle.DustOptions; import org.bukkit.Particle.DustOptions;
import org.bukkit.Particle.DustTransition;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -59,4 +60,21 @@ public class WrappedParticleTest {
assertEquals(beforeDust.getColor(), afterDust.getColor()); assertEquals(beforeDust.getColor(), afterDust.getColor());
assertEquals(beforeDust.getSize(), afterDust.getSize(), 0); assertEquals(beforeDust.getSize(), afterDust.getSize(), 0);
} }
@Test
public void testDustColorTransition() {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.WORLD_PARTICLES);
WrappedParticle before = WrappedParticle.create(Particle.DUST_COLOR_TRANSITION, new DustTransition(Color.BLUE, Color.RED, 1));
packet.getNewParticles().write(0, before);
WrappedParticle after = packet.getNewParticles().read(0);
assertEquals(before.getParticle(), after.getParticle());
Particle.DustTransition beforeDust = (Particle.DustTransition) before.getData();
Particle.DustTransition afterDust = (Particle.DustTransition) after.getData();
assertEquals(beforeDust.getColor(), afterDust.getColor());
assertEquals(beforeDust.getToColor(), afterDust.getToColor());
assertEquals(beforeDust.getSize(), afterDust.getSize(), 0);
}
} }