Created
May 18, 2024 05:30
-
-
Save mworzala/10c3b54295f64c0d946b1b3b073e6b20 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.hollowcube.mapmaker.map.entity.impl; | |
import net.hollowcube.mapmaker.map.entity.MapEntity; | |
import net.hollowcube.mapmaker.map.util.NbtUtil; | |
import net.kyori.adventure.nbt.*; | |
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; | |
import net.minestom.server.coordinate.Vec; | |
import net.minestom.server.entity.EntityType; | |
import net.minestom.server.entity.metadata.display.AbstractDisplayMeta; | |
import net.minestom.server.entity.metadata.display.BlockDisplayMeta; | |
import net.minestom.server.entity.metadata.display.ItemDisplayMeta; | |
import net.minestom.server.entity.metadata.display.TextDisplayMeta; | |
import net.minestom.server.item.ItemStack; | |
import net.minestom.server.utils.nbt.BinaryTagSerializer; | |
import org.jetbrains.annotations.NotNull; | |
import java.util.List; | |
import java.util.UUID; | |
import static net.kyori.adventure.nbt.FloatBinaryTag.floatBinaryTag; | |
public class DisplayEntity extends MapEntity { | |
private static final BinaryTagSerializer<AbstractDisplayMeta.BillboardConstraints> BILLBOARD_CONSTRAINTS = BinaryTagSerializer.fromEnumStringable(AbstractDisplayMeta.BillboardConstraints.class); | |
protected DisplayEntity(@NotNull EntityType entityType, @NotNull UUID uuid) { | |
super(entityType, uuid); | |
setNoGravity(true); | |
hasPhysics = false; | |
} | |
@Override | |
public @NotNull AbstractDisplayMeta getEntityMeta() { | |
return (AbstractDisplayMeta) super.getEntityMeta(); | |
} | |
@Override | |
public void writeData(CompoundBinaryTag.@NotNull Builder tag) { | |
super.writeData(tag); | |
final AbstractDisplayMeta meta = getEntityMeta(); | |
if (meta.getTransformationInterpolationStartDelta() != 0) | |
tag.putInt("start_interpolation", meta.getTransformationInterpolationStartDelta()); | |
if (meta.getTransformationInterpolationDuration() != 0) | |
tag.putInt("interpolation_duration", meta.getTransformationInterpolationDuration()); | |
if (meta.getPosRotInterpolationDuration() != 0) | |
tag.putInt("teleport_duration", meta.getPosRotInterpolationDuration()); | |
// Write transformation as decomposed form always. | |
var transformationTag = CompoundBinaryTag.builder(); | |
var translation = meta.getTranslation(); | |
if (!translation.isZero()) { | |
var elems = List.<BinaryTag>of(floatBinaryTag((float) translation.x()), floatBinaryTag((float) translation.y()), floatBinaryTag((float) translation.z())); | |
transformationTag.put("translation", ListBinaryTag.listBinaryTag(BinaryTagTypes.FLOAT, elems)); | |
} | |
var scale = meta.getScale(); | |
if (!scale.isZero()) { | |
var elems = List.<BinaryTag>of(floatBinaryTag((float) scale.x()), floatBinaryTag((float) scale.y()), floatBinaryTag((float) scale.z())); | |
transformationTag.put("scale", ListBinaryTag.listBinaryTag(BinaryTagTypes.FLOAT, elems)); | |
} | |
var leftRotation = meta.getLeftRotation(); | |
if (leftRotation[0] != 0 || leftRotation[1] != 0 || leftRotation[2] != 0 || leftRotation[3] != 0) { | |
var elems = List.<BinaryTag>of(floatBinaryTag(leftRotation[0]), floatBinaryTag(leftRotation[1]), floatBinaryTag(leftRotation[2]), floatBinaryTag(leftRotation[3])); | |
transformationTag.put("left_rotation", ListBinaryTag.listBinaryTag(BinaryTagTypes.FLOAT, elems)); | |
} | |
var rightRotation = meta.getRightRotation(); | |
if (rightRotation[0] != 0 || rightRotation[1] != 0 || rightRotation[2] != 0 || rightRotation[3] != 0) { | |
var elems = List.<BinaryTag>of(floatBinaryTag(rightRotation[0]), floatBinaryTag(rightRotation[1]), floatBinaryTag(rightRotation[2]), floatBinaryTag(rightRotation[3])); | |
transformationTag.put("right_rotation", ListBinaryTag.listBinaryTag(BinaryTagTypes.FLOAT, elems)); | |
} | |
var transformation = transformationTag.build(); | |
if (transformation.size() > 0) tag.put("transformation", transformation); | |
if (meta.getBillboardRenderConstraints() != AbstractDisplayMeta.BillboardConstraints.FIXED) | |
tag.put("billboard", BILLBOARD_CONSTRAINTS.write(meta.getBillboardRenderConstraints())); | |
//todo brightness override | |
if (meta.getViewRange() != 0) | |
tag.putFloat("view_range", meta.getViewRange()); | |
if (meta.getShadowRadius() != 0) | |
tag.putFloat("shadow_radius", meta.getShadowRadius()); | |
if (meta.getShadowStrength() != 0) | |
tag.putFloat("shadow_strength", meta.getShadowStrength()); | |
if (meta.getWidth() != 0) | |
tag.putFloat("width", meta.getWidth()); | |
if (meta.getHeight() != 0) | |
tag.putFloat("height", meta.getHeight()); | |
if (meta.getGlowColorOverride() != 0) | |
tag.putInt("glow_color_override", meta.getGlowColorOverride()); | |
} | |
@Override | |
public void readData(@NotNull CompoundBinaryTag tag) { | |
super.readData(tag); | |
final AbstractDisplayMeta meta = getEntityMeta(); | |
if (tag.get("start_interpolation") instanceof NumberBinaryTag startInterpolation) | |
meta.setTransformationInterpolationStartDelta(startInterpolation.intValue()); | |
if (tag.get("interpolation_duration") instanceof NumberBinaryTag interpolationDuration) | |
meta.setTransformationInterpolationDuration(interpolationDuration.intValue()); | |
if (tag.get("teleport_duration") instanceof NumberBinaryTag teleportDuration) | |
meta.setPosRotInterpolationDuration(teleportDuration.intValue()); | |
var transformationTag = tag.get("transformation"); | |
if (transformationTag instanceof CompoundBinaryTag transform) { | |
if (transform.get("translation") instanceof ListBinaryTag translate && translate.size() == 3 && translate.elementType() == BinaryTagTypes.FLOAT) | |
meta.setTranslation(new Vec(translate.getFloat(0), translate.getFloat(1), translate.getFloat(2))); | |
if (transform.get("scale") instanceof ListBinaryTag scale && scale.size() == 3 && scale.elementType() == BinaryTagTypes.FLOAT) | |
meta.setScale(new Vec(scale.getFloat(0), scale.getFloat(1), scale.getFloat(2))); | |
if (transform.get("left_rotation") instanceof ListBinaryTag leftRot && leftRot.size() == 4 && leftRot.elementType() == BinaryTagTypes.FLOAT) | |
meta.setLeftRotation(new float[]{leftRot.getFloat(0), leftRot.getFloat(1), leftRot.getFloat(2), leftRot.getFloat(3)}); | |
if (transform.get("right_rotation") instanceof ListBinaryTag rightRot && rightRot.size() == 4 && rightRot.elementType() == BinaryTagTypes.FLOAT) | |
meta.setRightRotation(new float[]{rightRot.getFloat(0), rightRot.getFloat(1), rightRot.getFloat(2), rightRot.getFloat(3)}); | |
} else if (transformationTag instanceof ListBinaryTag transformation && transformation.size() == 16 && transformation.elementType() == BinaryTagTypes.FLOAT) { | |
// https://github.com/apache/commons-math/blob/ffcdf39f8fa7ccd19c5c21a73fccb90c753592cd/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/linear/SingularValueDecomposition.java#L53 | |
throw new UnsupportedOperationException("SVD is not supported yet."); | |
} | |
if (tag.get("billboard") instanceof StringBinaryTag billboardName) | |
meta.setBillboardRenderConstraints(BILLBOARD_CONSTRAINTS.read(billboardName)); | |
//todo brightness override | |
if (tag.get("view_range") instanceof NumberBinaryTag viewRange) | |
meta.setViewRange(viewRange.floatValue()); | |
if (tag.get("shadow_radius") instanceof NumberBinaryTag shadowRadius) | |
meta.setShadowRadius(shadowRadius.floatValue()); | |
if (tag.get("shadow_strength") instanceof NumberBinaryTag shadowStrength) | |
meta.setShadowStrength(shadowStrength.floatValue()); | |
if (tag.get("width") instanceof NumberBinaryTag width) | |
meta.setWidth(width.floatValue()); | |
if (tag.get("height") instanceof NumberBinaryTag height) | |
meta.setHeight(height.floatValue()); | |
if (tag.get("glow_color_override") instanceof NumberBinaryTag glowColor) | |
meta.setGlowColorOverride(glowColor.intValue()); | |
} | |
public static class Block extends DisplayEntity { | |
public Block(@NotNull UUID uuid) { | |
super(EntityType.BLOCK_DISPLAY, uuid); | |
} | |
@Override | |
public @NotNull BlockDisplayMeta getEntityMeta() { | |
return (BlockDisplayMeta) super.getEntityMeta(); | |
} | |
@Override | |
public void writeData(CompoundBinaryTag.@NotNull Builder tag) { | |
super.writeData(tag); | |
final BlockDisplayMeta meta = getEntityMeta(); | |
var block = net.minestom.server.instance.block.Block.fromStateId((short) meta.getBlockStateId()); | |
if (block != null && !block.isAir()) | |
tag.put("block_state", NbtUtil.BLOCK_COMPOUND.write(block)); | |
} | |
@Override | |
public void readData(@NotNull CompoundBinaryTag tag) { | |
super.readData(tag); | |
final BlockDisplayMeta meta = getEntityMeta(); | |
if (tag.get("block_state") instanceof CompoundBinaryTag blockState) { | |
var block = NbtUtil.BLOCK_COMPOUND.read(blockState); | |
if (!block.isAir()) meta.setBlockState(block.stateId()); | |
} | |
} | |
} | |
public static class Item extends DisplayEntity { | |
private static final BinaryTagSerializer<ItemDisplayMeta.DisplayContext> DISPLAY_CONTEXT = BinaryTagSerializer.fromEnumStringable(ItemDisplayMeta.DisplayContext.class); | |
public Item(@NotNull UUID uuid) { | |
super(EntityType.ITEM_DISPLAY, uuid); | |
} | |
@Override | |
public @NotNull ItemDisplayMeta getEntityMeta() { | |
return (ItemDisplayMeta) super.getEntityMeta(); | |
} | |
@Override | |
public void writeData(CompoundBinaryTag.@NotNull Builder tag) { | |
super.writeData(tag); | |
final ItemDisplayMeta meta = getEntityMeta(); | |
var itemStack = meta.getItemStack(); | |
if (!itemStack.isAir() && itemStack.amount() > 0) | |
tag.put("item", ItemStack.NBT_TYPE.write(itemStack)); | |
if (meta.getDisplayContext() != ItemDisplayMeta.DisplayContext.NONE) | |
tag.put("item_display", DISPLAY_CONTEXT.write(meta.getDisplayContext())); | |
} | |
@Override | |
public void readData(@NotNull CompoundBinaryTag tag) { | |
super.readData(tag); | |
final ItemDisplayMeta meta = getEntityMeta(); | |
if (tag.get("item") instanceof CompoundBinaryTag item) | |
meta.setItemStack(ItemStack.NBT_TYPE.read(item)); | |
if (tag.get("item_display") instanceof StringBinaryTag itemDisplay) | |
meta.setDisplayContext(DISPLAY_CONTEXT.read(itemDisplay)); | |
} | |
} | |
public static class Text extends DisplayEntity { | |
public Text(@NotNull UUID uuid) { | |
super(EntityType.TEXT_DISPLAY, uuid); | |
} | |
@Override | |
public @NotNull TextDisplayMeta getEntityMeta() { | |
return (TextDisplayMeta) super.getEntityMeta(); | |
} | |
@Override | |
public void writeData(CompoundBinaryTag.@NotNull Builder tag) { | |
super.writeData(tag); | |
final TextDisplayMeta meta = getEntityMeta(); | |
tag.putString("text", GsonComponentSerializer.gson().serialize(meta.getText())); | |
if (meta.getLineWidth() != 0) | |
tag.putInt("line_width", meta.getLineWidth()); | |
if (meta.getBackgroundColor() != 0) | |
tag.putInt("background", meta.getBackgroundColor()); | |
if (meta.getTextOpacity() != 0) | |
tag.putByte("text_opacity", (byte) meta.getTextOpacity()); | |
if (meta.isShadow()) | |
tag.putByte("shadow", (byte) 1); | |
if (meta.isSeeThrough()) | |
tag.putByte("see_through", (byte) 1); | |
if (meta.isUseDefaultBackground()) | |
tag.putByte("default_background", (byte) 1); | |
if (meta.isAlignLeft() && !meta.isAlignRight()) | |
tag.putString("alignment", "left"); | |
if (meta.isAlignRight() && !meta.isAlignLeft()) | |
tag.putString("alignment", "right"); | |
} | |
@Override | |
public void readData(@NotNull CompoundBinaryTag tag) { | |
super.readData(tag); | |
final TextDisplayMeta meta = getEntityMeta(); | |
if (tag.get("text") instanceof StringBinaryTag text) | |
meta.setText(GsonComponentSerializer.gson().deserialize(text.value())); | |
if (tag.get("line_width") instanceof NumberBinaryTag lineWidth) | |
meta.setLineWidth(lineWidth.intValue()); | |
if (tag.get("background") instanceof NumberBinaryTag background) | |
meta.setBackgroundColor(background.intValue()); | |
if (tag.get("text_opacity") instanceof NumberBinaryTag textOpacity) | |
meta.setTextOpacity(textOpacity.byteValue()); | |
if (tag.get("shadow") instanceof NumberBinaryTag shadow) | |
meta.setShadow(shadow.byteValue() != 0); | |
if (tag.get("see_through") instanceof NumberBinaryTag seeThrough) | |
meta.setSeeThrough(seeThrough.byteValue() != 0); | |
if (tag.get("default_background") instanceof NumberBinaryTag defaultBackground) | |
meta.setUseDefaultBackground(defaultBackground.byteValue() != 0); | |
if (tag.get("alignment") instanceof StringBinaryTag align) { | |
meta.setAlignLeft("left".equals(align.value()) || "center".equals(align.value())); | |
meta.setAlignRight("right".equals(align.value()) || "center".equals(align.value())); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment