chore: add AlphaColor, convert Color to class, fix entity_effect particle (#2240)

* chore: add AlphaColor, convert Color to class, fix entity_effect particle

* chore: add `Particle.EntityEffect#withColor(RGBLike)`, `Color#withAlpha`

---------

Co-authored-by: mworzala <mattheworzala@gmail.com>
This commit is contained in:
DeidaraMC 2024-07-08 11:38:33 -04:00 committed by GitHub
parent 5caa7ce348
commit 328b0e7868
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 189 additions and 12 deletions

View File

@ -0,0 +1,115 @@
package net.minestom.server.color;
import net.kyori.adventure.util.RGBLike;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
/**
* A general purpose class for representing colors.
* <p>
* Colors must be in the range of 0-255.
*/
public final class AlphaColor extends Color {
private static final int BIT_MASK = 0xff;
public static final NetworkBuffer.Type<AlphaColor> NETWORK_TYPE = new NetworkBuffer.Type<AlphaColor>() {
@Override
public void write(@NotNull NetworkBuffer buffer, AlphaColor value) {
buffer.write(NetworkBuffer.INT, value.asARGB());
}
@Override
public AlphaColor read(@NotNull NetworkBuffer buffer) {
return new AlphaColor(buffer.read(NetworkBuffer.INT));
}
};
private final int alpha;
public AlphaColor(int alpha, int red, int green, int blue) {
super(red, green, blue);
Check.argCondition(!MathUtils.isBetween(alpha, 0, 255), "Alpha is not between 0-255: {0}", alpha);
this.alpha = alpha;
}
/**
* Creates an alpha color from an integer. This is done by reading each color component
* from the lowest order 32 bits of the integer, and creating a color from those
* components.
*
* @param argb the integer
*/
public AlphaColor(int argb) {
this((argb >> 24) & BIT_MASK, (argb >> 16) & BIT_MASK, (argb >> 8) & BIT_MASK, argb & BIT_MASK);
}
/**
* Creates a color from an RGB-like color.
*
* @param rgbLike the color
*/
public AlphaColor(int alpha, @NotNull RGBLike rgbLike) {
this(alpha, rgbLike.red(), rgbLike.green(), rgbLike.blue());
}
@Override
public @NotNull AlphaColor withRed(int red) {
return new AlphaColor(alpha(), red, green(), blue());
}
@Override
public @NotNull AlphaColor withGreen(int green) {
return new AlphaColor(alpha(), red(), green, blue());
}
@Override
public @NotNull AlphaColor withBlue(int blue) {
return new AlphaColor(alpha(), red(), green(), blue);
}
public @NotNull AlphaColor withAlpha(int alpha) {
return new AlphaColor(alpha, red(), green(), blue());
}
/**
* Gets the color as an RGB integer.
*
* @return An integer representation of this color, as 0xRRGGBB
*/
public int asARGB() {
return (alpha << 24) + asRGB();
}
public int alpha() {
return alpha;
}
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null || obj.getClass() != this.getClass()) return false;
var that = (AlphaColor) obj;
return this.alpha == that.alpha &&
red() == that.red() &&
this.green() == that.green() &&
this.blue() == that.blue();
}
@Override
public int hashCode() {
return Objects.hash(alpha, red(), green(), blue());
}
@Override
public String toString() {
return "AlphaColor[" +
"alpha=" + alpha + ", " +
"red=" + red() + ", " +
"green=" + green() + ", " +
"blue=" + blue() + ']';
}
}

View File

@ -7,12 +7,14 @@ import net.minestom.server.utils.nbt.BinaryTagSerializer;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
/**
* A general purpose class for representing colors.
* <p>
* Colors must be in the range of 0-255.
*/
public record Color(int red, int green, int blue) implements RGBLike {
public class Color implements RGBLike {
private static final int BIT_MASK = 0xff;
public static final NetworkBuffer.Type<RGBLike> NETWORK_TYPE = new NetworkBuffer.Type<RGBLike>() {
@ -28,16 +30,17 @@ public record Color(int red, int green, int blue) implements RGBLike {
};
public static final BinaryTagSerializer<RGBLike> NBT_TYPE = BinaryTagSerializer.INT
.map(Color::new, color -> Color.fromRGBLike(color).asRGB());
private final int red;
private final int green;
private final int blue;
public static @NotNull Color fromRGBLike(@NotNull RGBLike rgbLike) {
if (rgbLike instanceof Color color) return color;
return new Color(rgbLike.red(), rgbLike.green(), rgbLike.blue());
}
public Color {
public Color(int red, int green, int blue) {
Check.argCondition(!MathUtils.isBetween(red, 0, 255), "Red is not between 0-255: {0}", red);
Check.argCondition(!MathUtils.isBetween(green, 0, 255), "Green is not between 0-255: {0}", green);
Check.argCondition(!MathUtils.isBetween(blue, 0, 255), "Blue is not between 0-255: {0}", blue);
this.red = red;
this.green = green;
this.blue = blue;
}
/**
@ -60,6 +63,11 @@ public record Color(int red, int green, int blue) implements RGBLike {
this(rgbLike.red(), rgbLike.green(), rgbLike.blue());
}
public static @NotNull Color fromRGBLike(@NotNull RGBLike rgbLike) {
if (rgbLike instanceof Color color) return color;
return new Color(rgbLike.red(), rgbLike.green(), rgbLike.blue());
}
public @NotNull Color withRed(int red) {
return new Color(red, green, blue);
}
@ -72,6 +80,10 @@ public record Color(int red, int green, int blue) implements RGBLike {
return new Color(red, green, blue);
}
public @NotNull AlphaColor withAlpha(int alpha) {
return new AlphaColor(alpha, red, green, blue);
}
/**
* Gets the color as an RGB integer.
*
@ -138,4 +150,42 @@ public record Color(int red, int green, int blue) implements RGBLike {
public int getBlue() {
return this.blue;
}
@Override
public int red() {
return red;
}
@Override
public int green() {
return green;
}
@Override
public int blue() {
return blue;
}
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null || obj.getClass() != this.getClass()) return false;
var that = (Color) obj;
return this.red == that.red &&
this.green == that.green &&
this.blue == that.blue;
}
@Override
public int hashCode() {
return Objects.hash(red, green, blue);
}
@Override
public String toString() {
return "Color[" +
"red=" + red + ", " +
"green=" + green + ", " +
"blue=" + blue + ']';
}
}

View File

@ -1,6 +1,7 @@
package net.minestom.server.particle;
import net.kyori.adventure.util.RGBLike;
import net.minestom.server.color.AlphaColor;
import net.minestom.server.color.Color;
import net.minestom.server.coordinate.Point;
import net.minestom.server.item.ItemStack;
@ -255,21 +256,31 @@ public sealed interface Particle extends StaticProtocolObject, Particles permits
}
}
record EntityEffect(@NotNull NamespaceID namespace, int id, @NotNull RGBLike color) implements Particle {
record EntityEffect(@NotNull NamespaceID namespace, int id, @NotNull AlphaColor color) implements Particle {
@Contract(pure = true)
public @NotNull EntityEffect withColor(@NotNull AlphaColor color) {
return new EntityEffect(namespace(), id(), color);
}
@Contract(pure = true)
public @NotNull EntityEffect withColor(@NotNull RGBLike color) {
return new EntityEffect(namespace(), id(), color);
return new EntityEffect(namespace(), id(), new AlphaColor(1, color));
}
@Contract(pure = true)
public @NotNull EntityEffect withColor(int alpha, @NotNull RGBLike color) {
return new EntityEffect(namespace(), id(), new AlphaColor(alpha, color));
}
@Override
public @NotNull EntityEffect readData(@NotNull NetworkBuffer reader) {
return withColor(reader.read(Color.NETWORK_TYPE));
return withColor(reader.read(AlphaColor.NETWORK_TYPE));
}
@Override
public void writeData(@NotNull NetworkBuffer writer) {
writer.write(Color.NETWORK_TYPE, color);
writer.write(AlphaColor.NETWORK_TYPE, color);
}
}

View File

@ -1,5 +1,6 @@
package net.minestom.server.particle;
import net.minestom.server.color.AlphaColor;
import net.minestom.server.color.Color;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.instance.block.Block;
@ -43,7 +44,7 @@ final class ParticleImpl {
case "minecraft:item" -> new Particle.Item(namespace, id, ItemStack.AIR);
case "minecraft:vibration" -> new Particle.Vibration(namespace, id, Particle.Vibration.SourceType.BLOCK, Vec.ZERO, 0, 0, 0);
case "minecraft:shriek" -> new Particle.Shriek(namespace, id, 0);
case "minecraft:entity_effect" -> new Particle.EntityEffect(namespace, id, new Color(0));
case "minecraft:entity_effect" -> new Particle.EntityEffect(namespace, id, new AlphaColor(255, 0, 0, 0));
default -> new Particle.Simple(namespace, id);
};
}