Skip to content

Commit 2c48b1c

Browse files
authored
Added support for dust color transition particles (#2455)
1 parent 6ee4bbf commit 2c48b1c

File tree

2 files changed

+102
-8
lines changed

2 files changed

+102
-8
lines changed

src/main/java/com/comphenix/protocol/wrappers/WrappedParticle.java

Lines changed: 84 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,31 @@ public Particle getParticle() {
7575

7676
/**
7777
* Gets this Particle's Bukkit/ProtocolLib data. The type of this data depends on the
78-
* {@link #getParticle() Particle type}. For Block particles it will be {@link WrappedBlockData},
79-
* for Item crack particles, it will be an {@link ItemStack}, and for redstone particles it will
80-
* be {@link Particle.DustOptions}
78+
* {@link #getParticle() Particle type}. Refer to the table below for the corresponding data types.
79+
* <p>
80+
* <table border="1">
81+
* <caption>Particle Data Types</caption>
82+
* <tr>
83+
* <td><b>Particle Type</b></td>
84+
* <td><b>Particle Data Type</b></td>
85+
* </tr>
86+
* <tr>
87+
* <td>Block particles (BLOCK_CRACK, BLOCK_DUST, FALLING_DUST)</td>
88+
* <td>{@link WrappedBlockData}</td>
89+
* </tr>
90+
* <tr>
91+
* <td>Item crack particles</td>
92+
* <td>{@link ItemStack}</td>
93+
* </tr>
94+
* <tr>
95+
* <td>Redstone particles</td>
96+
* <td>{@link Particle.DustOptions}</td>
97+
* </tr>
98+
* <tr>
99+
* <td>Dust color transition particles</td>
100+
* <td>{@link Particle.DustTransition}</td>
101+
* </tr>
102+
* </table>
81103
*
82104
* @return The particle data
83105
*/
@@ -110,6 +132,9 @@ public static WrappedParticle fromHandle(Object handle) {
110132
case REDSTONE:
111133
data = getRedstone(handle);
112134
break;
135+
case DUST_COLOR_TRANSITION:
136+
data = getDustTransition(handle);
137+
break;
113138
default:
114139
break;
115140
}
@@ -133,7 +158,7 @@ private static Object getItem(Object handle) {
133158

134159
private static Object getRedstone(Object handle) {
135160
int r, g, b;
136-
float alpha;
161+
float size;
137162

138163
if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) {
139164
StructureModifier<Object> modifier = new StructureModifier<>(handle.getClass()).withTarget(handle);
@@ -142,7 +167,7 @@ private static Object getRedstone(Object handle) {
142167
r = (int) (rgb.x() * 255);
143168
g = (int) (rgb.y() * 255);
144169
b = (int) (rgb.z() * 255);
145-
alpha = (float) modifier.withType(float.class).read(0);
170+
size = (float) modifier.withType(float.class).read(0);
146171
} else if (MinecraftVersion.CAVES_CLIFFS_1.atOrAbove()) {
147172
if (VECTOR_3FA == null) {
148173
VECTOR_3FA = MinecraftReflection.getLibraryClass("com.mojang.math.Vector3fa");
@@ -156,16 +181,67 @@ private static Object getRedstone(Object handle) {
156181
r = (int) (rgbModifier.<Float>withType(float.class).read(0) * 255);
157182
g = (int) (rgbModifier.<Float>withType(float.class).read(1) * 255);
158183
b = (int) (rgbModifier.<Float>withType(float.class).read(2) * 255);
159-
alpha = (float) modifier.withType(float.class).read(0);
184+
size = (float) modifier.withType(float.class).read(0);
160185
} else {
161186
StructureModifier<Float> modifier = new StructureModifier<>(handle.getClass()).withTarget(handle).withType(float.class);
162187
r = (int) (modifier.read(0) * 255);
163188
g = (int) (modifier.read(1) * 255);
164189
b = (int) (modifier.read(2) * 255);
165-
alpha = modifier.read(3);
190+
size = modifier.read(3);
191+
}
192+
193+
return new Particle.DustOptions(Color.fromRGB(r, g, b), size);
194+
}
195+
196+
private static Object getDustTransition(Object handle) {
197+
int fromR, fromG, fromB, toR, toG, toB;
198+
float size;
199+
200+
if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) {
201+
StructureModifier<Object> modifier = new StructureModifier<>(handle.getClass()).withTarget(handle);
202+
org.joml.Vector3f toRGB = (org.joml.Vector3f) modifier.withType(org.joml.Vector3f.class).read(0);
203+
org.joml.Vector3f fromRGB = (org.joml.Vector3f) modifier.withType(org.joml.Vector3f.class).read(1);
204+
size = (float) modifier.withType(float.class).read(0);
205+
206+
fromR = (int) (fromRGB.x() * 255);
207+
fromG = (int) (fromRGB.y() * 255);
208+
fromB = (int) (fromRGB.z() * 255);
209+
210+
toR = (int) (toRGB.x() * 255);
211+
toG = (int) (toRGB.y() * 255);
212+
toB = (int) (toRGB.z() * 255);
213+
} else if (MinecraftVersion.CAVES_CLIFFS_1.atOrAbove()) {
214+
if (VECTOR_3FA == null) {
215+
VECTOR_3FA = MinecraftReflection.getLibraryClass("com.mojang.math.Vector3fa");
216+
}
217+
218+
StructureModifier<Object> modifier = new StructureModifier<>(handle.getClass()).withTarget(handle);
219+
220+
Object toRGB = modifier.withType(VECTOR_3FA).read(0);
221+
Object fromRGB = modifier.withType(VECTOR_3FA).read(1);
222+
size = (float) modifier.withType(float.class).read(0);
223+
StructureModifier<Object> rgbModifier = new StructureModifier<>(VECTOR_3FA).withTarget(fromRGB);
224+
StructureModifier<Object> rgbModifier2 = new StructureModifier<>(VECTOR_3FA).withTarget(toRGB);
225+
226+
fromR = (int) (rgbModifier.<Float>withType(float.class).read(0) * 255);
227+
fromG = (int) (rgbModifier.<Float>withType(float.class).read(1) * 255);
228+
fromB = (int) (rgbModifier.<Float>withType(float.class).read(2) * 255);
229+
230+
toR = (int) (rgbModifier2.<Float>withType(float.class).read(0) * 255);
231+
toG = (int) (rgbModifier2.<Float>withType(float.class).read(1) * 255);
232+
toB = (int) (rgbModifier2.<Float>withType(float.class).read(2) * 255);
233+
} else {
234+
StructureModifier<Float> modifier = new StructureModifier<>(handle.getClass()).withTarget(handle).withType(float.class);
235+
toR = (int) (modifier.read(0) * 255);
236+
toG = (int) (modifier.read(1) * 255);
237+
toB = (int) (modifier.read(2) * 255);
238+
size = modifier.read(3);
239+
fromR = (int) (modifier.read(4) * 255);
240+
fromG = (int) (modifier.read(5) * 255);
241+
fromB = (int) (modifier.read(6) * 255);
166242
}
167243

168-
return new Particle.DustOptions(Color.fromRGB(r, g, b), alpha);
244+
return new Particle.DustTransition(Color.fromRGB(fromR, fromG, fromB), Color.fromRGB(toR, toG, toB), size);
169245
}
170246

171247
public static <T> WrappedParticle<T> create(Particle particle, T data) {

src/test/java/com/comphenix/protocol/wrappers/WrappedParticleTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.bukkit.Material;
1111
import org.bukkit.Particle;
1212
import org.bukkit.Particle.DustOptions;
13+
import org.bukkit.Particle.DustTransition;
1314
import org.bukkit.inventory.ItemStack;
1415
import org.junit.jupiter.api.BeforeAll;
1516
import org.junit.jupiter.api.Test;
@@ -59,4 +60,21 @@ public void testRedstone() {
5960
assertEquals(beforeDust.getColor(), afterDust.getColor());
6061
assertEquals(beforeDust.getSize(), afterDust.getSize(), 0);
6162
}
63+
64+
@Test
65+
public void testDustColorTransition() {
66+
PacketContainer packet = new PacketContainer(PacketType.Play.Server.WORLD_PARTICLES);
67+
WrappedParticle before = WrappedParticle.create(Particle.DUST_COLOR_TRANSITION, new DustTransition(Color.BLUE, Color.RED, 1));
68+
packet.getNewParticles().write(0, before);
69+
70+
WrappedParticle after = packet.getNewParticles().read(0);
71+
assertEquals(before.getParticle(), after.getParticle());
72+
73+
Particle.DustTransition beforeDust = (Particle.DustTransition) before.getData();
74+
Particle.DustTransition afterDust = (Particle.DustTransition) after.getData();
75+
76+
assertEquals(beforeDust.getColor(), afterDust.getColor());
77+
assertEquals(beforeDust.getToColor(), afterDust.getToColor());
78+
assertEquals(beforeDust.getSize(), afterDust.getSize(), 0);
79+
}
6280
}

0 commit comments

Comments
 (0)