diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java
new file mode 100644
index 00000000..5f4c4d50
--- /dev/null
+++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java
@@ -0,0 +1,68 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.entity;
+
+import de.steamwar.Reflection;
+import de.steamwar.core.BountifulWrapper;
+import lombok.Getter;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.entity.EntityType;
+
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+/**
+ * !! This class cannot be used in Versions lower than or equal to 1.19.4 !!
+ */
+@Getter
+public class RBlockDisplay extends RDisplay {
+
+ public static final BlockData DEFAULT_BLOCK = Material.AIR.createBlockData();
+
+ private BlockData block;
+
+ public RBlockDisplay(REntityServer server, Location location) {
+ super(server, EntityType.BLOCK_DISPLAY, location);
+ this.block = DEFAULT_BLOCK;
+ server.addEntity(this);
+ }
+
+ @Override
+ protected void postSpawn(Consumer packetSink) {
+ super.postSpawn(packetSink);
+ sendPacket(packetSink, this::getBlock);
+ }
+
+ public void setBlock(BlockData block) {
+ this.block = block;
+ sendPacket(updatePacketSink, this::getBlock);
+ }
+
+ private static final Class> iBlockDataClass = Reflection.getClass("net.minecraft.world.level.block.state.BlockState");
+ private static final Reflection.Method getState = Reflection.getTypedMethod(Reflection.getClass("org.bukkit.craftbukkit.block.data.CraftBlockData"), "getState", iBlockDataClass);
+ private static final Object blockWatcher = BountifulWrapper.impl.getDataWatcherObject(22, iBlockDataClass);
+ private void getBlock(boolean ignoreDefault, BiConsumer packetSink) {
+ if (ignoreDefault || !block.getAsString(true).equals(DEFAULT_BLOCK.getAsString(true))) {
+ packetSink.accept(blockWatcher, getState.invoke(block));
+ }
+ }
+}
diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java
new file mode 100644
index 00000000..863dc658
--- /dev/null
+++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java
@@ -0,0 +1,258 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.entity;
+
+import de.steamwar.core.BountifulWrapper;
+import lombok.Getter;
+import lombok.NonNull;
+import org.bukkit.Color;
+import org.bukkit.Location;
+import org.bukkit.entity.Display;
+import org.bukkit.entity.EntityType;
+import org.bukkit.util.Transformation;
+import org.joml.Quaternionf;
+import org.joml.Vector3f;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+/**
+ * !! This class cannot be used in Versions lower than or equal to 1.19.4 !!
+ */
+@Getter
+public abstract class RDisplay extends REntity {
+
+ protected final Consumer updatePacketSink = o -> server.updateEntity(this, o);
+
+ public static final Transformation DEFAULT_TRANSFORM = new Transformation(new Vector3f(), new Quaternionf(0, 0, 0, 1), new Vector3f(1, 1, 1), new Quaternionf(0, 0, 0, 1));
+
+ private Transformation transform;
+ private int interpolationDuration;
+ private float viewRange;
+ private float shadowRadius;
+ private float shadowStrength;
+ private float displayWidth;
+ private float displayHeight;
+ private int interpolationDelay;
+ private Display.Billboard billboard;
+ private Color glowColorOverride;
+ private Display.Brightness brightness;
+
+ protected RDisplay(REntityServer server, EntityType entityType, Location location) {
+ super(server, entityType, location, 0);
+ this.transform = DEFAULT_TRANSFORM;
+ this.interpolationDuration = 0;
+ this.viewRange = 1.0F;
+ this.shadowRadius = 0.0F;
+ this.shadowStrength = 1.0F;
+ this.displayWidth = 0.0F;
+ this.displayHeight = 0.0F;
+ this.interpolationDelay = 0;
+ this.billboard = Display.Billboard.FIXED;
+ this.glowColorOverride = null;
+ this.brightness = null;
+ }
+
+ @Override
+ protected void postSpawn(Consumer packetSink) {
+ super.postSpawn(packetSink);
+ sendPacket(packetSink,
+ this::getTransformData,
+ this::getInterpolationDuration,
+ this::getViewRange,
+ this::getShadowRadius,
+ this::getShadowStrength,
+ this::getDisplayWidth,
+ this::getDisplayHeight,
+ this::getInterpolationDelay,
+ this::getBillboard,
+ this::getGlowColorOverride,
+ this::getBrightness
+ );
+ }
+
+ @SafeVarargs
+ protected final void sendPacket(Consumer packetSink, BiConsumer>... dataSinkSinks) {
+ List keyValueData = new ArrayList<>();
+ boolean ignoreDefault = packetSink == updatePacketSink;
+ for (BiConsumer> dataSinkSink : dataSinkSinks) {
+ dataSinkSink.accept(ignoreDefault, (dataWatcher, value) -> {
+ keyValueData.add(dataWatcher);
+ keyValueData.add(value);
+ });
+ }
+ if (!keyValueData.isEmpty()) {
+ packetSink.accept(getDataWatcherPacket(keyValueData.toArray()));
+ }
+ }
+
+ public void setTransform(@NonNull Transformation transform) {
+ this.transform = transform;
+ sendPacket(updatePacketSink, this::getTransformData);
+ }
+
+ private static final Object translationWatcher = BountifulWrapper.impl.getDataWatcherObject(10, Vector3f.class);
+ private static final Object leftRotationWatcher = BountifulWrapper.impl.getDataWatcherObject(12, Quaternionf.class);
+ private static final Object scaleWatcher = BountifulWrapper.impl.getDataWatcherObject(11, Vector3f.class);
+ private static final Object rightRotationWatcher = BountifulWrapper.impl.getDataWatcherObject(13, Quaternionf.class);
+
+ private void getTransformData(boolean ignoreDefault, BiConsumer dataSink) {
+ if (ignoreDefault || !transform.equals(DEFAULT_TRANSFORM)) {
+ dataSink.accept(translationWatcher, transform.getTranslation());
+ dataSink.accept(leftRotationWatcher, transform.getLeftRotation());
+ dataSink.accept(scaleWatcher, transform.getScale());
+ dataSink.accept(rightRotationWatcher, transform.getRightRotation());
+ }
+ }
+
+ public void setInterpolationDuration(int interpolationDuration) {
+ this.interpolationDuration = interpolationDuration;
+ sendPacket(updatePacketSink, this::getInterpolationDuration);
+ }
+
+ private static final Object transformationInterpolationDurationWatcher = BountifulWrapper.impl.getDataWatcherObject(8, Integer.class);
+ private static final Object positionOrRotationInterpolationDurationWatcher = BountifulWrapper.impl.getDataWatcherObject(9, Integer.class);
+
+ private void getInterpolationDuration(boolean ignoreDefault, BiConsumer packetSink) {
+ if (ignoreDefault || interpolationDelay != 0) {
+ packetSink.accept(transformationInterpolationDurationWatcher, interpolationDuration);
+ packetSink.accept(positionOrRotationInterpolationDurationWatcher, interpolationDuration);
+ }
+ }
+
+ public void setViewRange(float viewRange) {
+ this.viewRange = viewRange;
+ sendPacket(updatePacketSink, this::getViewRange);
+ }
+
+ private static final Object viewRangeWatcher = BountifulWrapper.impl.getDataWatcherObject(16, Float.class);
+
+ private void getViewRange(boolean ignoreDefault, BiConsumer packetSink) {
+ if (ignoreDefault || viewRange != 1.0F) {
+ packetSink.accept(viewRangeWatcher, viewRange);
+ }
+ }
+
+ public void setShadowRadius(float shadowRadius) {
+ this.shadowRadius = shadowRadius;
+ sendPacket(updatePacketSink, this::getShadowRadius);
+ }
+
+ private static final Object shadowRadiusWatcher = BountifulWrapper.impl.getDataWatcherObject(17, Float.class);
+
+ private void getShadowRadius(boolean ignoreDefault, BiConsumer packetSink) {
+ if (ignoreDefault || shadowRadius != 0.0F) {
+ packetSink.accept(shadowRadiusWatcher, shadowRadius);
+ }
+ }
+
+ public void setShadowStrength(float shadowStrength) {
+ this.shadowStrength = shadowStrength;
+ sendPacket(updatePacketSink, this::getShadowStrength);
+ }
+
+ private static final Object shadowStrengthWatcher = BountifulWrapper.impl.getDataWatcherObject(18, Float.class);
+
+ private void getShadowStrength(boolean ignoreDefault, BiConsumer packetSink) {
+ if (ignoreDefault || shadowStrength != 1.0F) {
+ packetSink.accept(shadowStrengthWatcher, shadowStrength);
+ }
+ }
+
+ public void setDisplayWidth(float displayWidth) {
+ this.displayWidth = displayWidth;
+ sendPacket(updatePacketSink, this::getDisplayWidth);
+ }
+
+ private static final Object displayWidthWatcher = BountifulWrapper.impl.getDataWatcherObject(19, Float.class);
+
+ private void getDisplayWidth(boolean ignoreDefault, BiConsumer packetSink) {
+ if (ignoreDefault || displayWidth != 0.0F) {
+ packetSink.accept(displayWidthWatcher, displayWidth);
+ }
+ }
+
+ public void setDisplayHeight(float displayHeight) {
+ this.displayHeight = displayHeight;
+ sendPacket(updatePacketSink, this::getDisplayHeight);
+ }
+
+ private static final Object displayHeightWatcher = BountifulWrapper.impl.getDataWatcherObject(20, Float.class);
+
+ private void getDisplayHeight(boolean ignoreDefault, BiConsumer packetSink) {
+ if (ignoreDefault || displayHeight != 0.0F) {
+ packetSink.accept(displayHeightWatcher, displayHeight);
+ }
+ }
+
+ public void setInterpolationDelay(int interpolationDelay) {
+ this.interpolationDelay = interpolationDelay;
+ sendPacket(updatePacketSink, this::getInterpolationDelay);
+ }
+
+ private static final Object interpolationDelayWatcher = BountifulWrapper.impl.getDataWatcherObject(7, Integer.class);
+
+ private void getInterpolationDelay(boolean ignoreDefault, BiConsumer packetSink) {
+ if (ignoreDefault || interpolationDelay != 0) {
+ packetSink.accept(interpolationDelayWatcher, interpolationDelay);
+ }
+ }
+
+ public void setBillboard(Display.Billboard billboard) {
+ this.billboard = billboard;
+ sendPacket(updatePacketSink, this::getBillboard);
+ }
+
+ private static final Object billboardWatcher = BountifulWrapper.impl.getDataWatcherObject(14, Byte.class);
+
+ private void getBillboard(boolean ignoreDefault, BiConsumer packetSink) {
+ if (ignoreDefault || billboard != Display.Billboard.FIXED) {
+ packetSink.accept(billboardWatcher, (byte) billboard.ordinal());
+ }
+ }
+
+ public void setGlowColorOverride(Color glowColorOverride) {
+ this.glowColorOverride = glowColorOverride;
+ sendPacket(updatePacketSink, this::getGlowColorOverride);
+ }
+
+ private static final Object glowColorOverrideWatcher = BountifulWrapper.impl.getDataWatcherObject(21, Integer.class);
+
+ private void getGlowColorOverride(boolean ignoreDefault, BiConsumer packetSink) {
+ if (ignoreDefault || glowColorOverride != null) {
+ packetSink.accept(glowColorOverrideWatcher, glowColorOverride == null ? -1 : glowColorOverride.asARGB());
+ }
+ }
+
+ public void setBrightness(Display.Brightness brightness) {
+ this.brightness = brightness;
+ sendPacket(updatePacketSink, this::getBrightness);
+ }
+
+ private static final Object brightnessWatcher = BountifulWrapper.impl.getDataWatcherObject(15, Integer.class);
+
+ private void getBrightness(boolean ignoreDefault, BiConsumer packetSink) {
+ if (ignoreDefault || brightness != null) {
+ packetSink.accept(brightnessWatcher, brightness == null ? -1 : brightness.getBlockLight() << 4 | brightness.getSkyLight() << 20);
+ }
+ }
+}
diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java
index e7ecb1a8..0c02a889 100644
--- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java
+++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java
@@ -45,7 +45,7 @@ public class REntity {
private static int entityIdCounter = -1;
private static final Random random = new Random();
- private final REntityServer server;
+ protected final REntityServer server;
private final EntityType entityType;
@Getter
protected final int entityId;
@@ -441,7 +441,7 @@ public class REntity {
private static final Reflection.Field equipmentEntity = Reflection.getField(ProtocolWrapper.equipmentPacket, int.class, 0);
private static final Class> craftItemStack = Reflection.getClass("org.bukkit.craftbukkit.inventory.CraftItemStack");
- private static final Reflection.Method asNMSCopy = Reflection.getTypedMethod(REntity.craftItemStack, "asNMSCopy", ProtocolWrapper.itemStack, ItemStack.class);
+ protected static final Reflection.Method asNMSCopy = Reflection.getTypedMethod(REntity.craftItemStack, "asNMSCopy", ProtocolWrapper.itemStack, ItemStack.class);
protected Object getEquipmentPacket(Object slot, ItemStack stack){
Object packet = Reflection.newInstance(ProtocolWrapper.equipmentPacket);
equipmentEntity.set(packet, entityId);
diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java
new file mode 100644
index 00000000..52cbfc31
--- /dev/null
+++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java
@@ -0,0 +1,81 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.entity;
+
+import de.steamwar.core.BountifulWrapper;
+import de.steamwar.core.ProtocolWrapper;
+import lombok.Getter;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.ItemDisplay;
+import org.bukkit.inventory.ItemStack;
+
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+/**
+ * !! This class cannot be used in Versions lower than or equal to 1.19.4 !!
+ */
+@Getter
+public class RItemDisplay extends RDisplay {
+
+ public static final ItemStack DEFAULT_ITEM_STACK = new ItemStack(Material.AIR);
+
+ private ItemStack itemStack;
+ private ItemDisplay.ItemDisplayTransform itemDisplayTransform;
+
+ public RItemDisplay(REntityServer server, Location location) {
+ super(server, EntityType.ITEM_DISPLAY, location);
+ this.itemStack = DEFAULT_ITEM_STACK;
+ this.itemDisplayTransform = ItemDisplay.ItemDisplayTransform.NONE;
+ server.addEntity(this);
+ }
+
+ @Override
+ protected void postSpawn(Consumer packetSink) {
+ super.postSpawn(packetSink);
+ sendPacket(packetSink, this::getItemStack, this::getItemDisplayTransform);
+ }
+
+ public void setItemStack(ItemStack itemStack) {
+ this.itemStack = itemStack;
+ sendPacket(updatePacketSink, this::getItemStack);
+ }
+
+ private static final Object itemStackWatcher = BountifulWrapper.impl.getDataWatcherObject(22, ProtocolWrapper.itemStack);
+ private void getItemStack(boolean ignoreDefault, BiConsumer packetSink) {
+ if (ignoreDefault || !itemStack.equals(DEFAULT_ITEM_STACK)) {
+ packetSink.accept(itemStackWatcher, asNMSCopy.invoke(null, itemStack));
+ }
+ }
+
+ private static final Object itemDisplayTransformWatcher = BountifulWrapper.impl.getDataWatcherObject(23, Byte.class);
+ public void setItemDisplayTransform(ItemDisplay.ItemDisplayTransform itemDisplayTransform) {
+ this.itemDisplayTransform = itemDisplayTransform;
+ sendPacket(updatePacketSink, this::getItemDisplayTransform);
+ }
+
+ private void getItemDisplayTransform(boolean ignoreDefault, BiConsumer packetSink) {
+ if (ignoreDefault || itemDisplayTransform != ItemDisplay.ItemDisplayTransform.NONE) {
+ packetSink.accept(itemDisplayTransformWatcher, (byte) itemDisplayTransform.ordinal());
+ }
+ }
+}
diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java
new file mode 100644
index 00000000..605b6770
--- /dev/null
+++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java
@@ -0,0 +1,153 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2023 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.entity;
+
+import de.steamwar.Reflection;
+import de.steamwar.core.BountifulWrapper;
+import de.steamwar.core.ChatWrapper;
+import lombok.Getter;
+import org.bukkit.Location;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.TextDisplay;
+
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+/**
+ * !! This class cannot be used in Versions lower than or equal to 1.19.4 !!
+ */
+@Getter
+public class RTextDisplay extends RDisplay {
+
+ private String text;
+
+ private int lineWidth;
+
+ private byte textOpacity;
+
+ private boolean shadowed;
+
+ private boolean seeThrough;
+
+ private boolean defaultBackground;
+
+ private TextDisplay.TextAlignment alignment;
+
+ public RTextDisplay(REntityServer server, Location location) {
+ super(server, EntityType.TEXT_DISPLAY, location);
+ this.text = "";
+ this.lineWidth = 200;
+ this.textOpacity = (byte) -1;
+ this.shadowed = false;
+ this.seeThrough = false;
+ this.defaultBackground = false;
+ this.alignment = TextDisplay.TextAlignment.CENTER;
+ server.addEntity(this);
+ }
+
+ @Override
+ protected void postSpawn(Consumer packetSink) {
+ super.postSpawn(packetSink);
+ sendPacket(packetSink, this::getText, this::getLineWidth, this::getTextOpacity, this::getTextStatus);
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ sendPacket(updatePacketSink, this::getText);
+ }
+
+ private static final Class> iChatBaseComponent = Reflection.getClass("net.minecraft.network.chat.Component");
+ private static final Object textWatcher = BountifulWrapper.impl.getDataWatcherObject(22, iChatBaseComponent);
+ private void getText(boolean ignoreDefault, BiConsumer packetSink) {
+ if (ignoreDefault || !text.isEmpty()) {
+ packetSink.accept(textWatcher, ChatWrapper.impl.stringToChatComponent(text));
+ }
+ }
+
+ public void setLineWidth(int lineWidth) {
+ this.lineWidth = lineWidth;
+ sendPacket(updatePacketSink, this::getLineWidth);
+ }
+
+ private static final Object lineWidthWatcher = BountifulWrapper.impl.getDataWatcherObject(23, Integer.class);
+ private void getLineWidth(boolean ignoreDefault, BiConsumer packetSink) {
+ if (ignoreDefault || lineWidth != 200) {
+ packetSink.accept(lineWidthWatcher, lineWidth);
+ }
+ }
+
+ public void setTextOpacity(byte textOpacity) {
+ this.textOpacity = textOpacity;
+ sendPacket(updatePacketSink, this::getTextOpacity);
+ }
+
+ private static final Object textOpacityWatcher = BountifulWrapper.impl.getDataWatcherObject(25, Byte.class);
+ private void getTextOpacity(boolean ignoreDefault, BiConsumer packetSink) {
+ if (ignoreDefault || textOpacity != (byte) -1) {
+ packetSink.accept(textOpacityWatcher, textOpacity);
+ }
+ }
+
+ public void setShadowed(boolean shadowed) {
+ this.shadowed = shadowed;
+ sendPacket(updatePacketSink, this::getTextStatus);
+ }
+
+ public void setSeeThrough(boolean seeThrough) {
+ this.seeThrough = seeThrough;
+ sendPacket(updatePacketSink, this::getTextStatus);
+ }
+
+ public void setDefaultBackground(boolean defaultBackground) {
+ this.defaultBackground = defaultBackground;
+ sendPacket(updatePacketSink, this::getTextStatus);
+ }
+
+ public void setAlignment(TextDisplay.TextAlignment alignment) {
+ this.alignment = alignment;
+ sendPacket(updatePacketSink, this::getTextStatus);
+ }
+
+ private static final Object textStatusWatcher = BountifulWrapper.impl.getDataWatcherObject(26, Byte.class);
+ private void getTextStatus(boolean ignoreDefault, BiConsumer packetSink) {
+ byte status = 0;
+
+ if (shadowed) {
+ status |= 0x01;
+ }
+ if (seeThrough) {
+ status |= 0x02;
+ }
+ if (defaultBackground) {
+ status |= 0x04;
+ }
+ if (alignment == TextDisplay.TextAlignment.CENTER) {
+ // Do nothing
+ } else if (alignment == TextDisplay.TextAlignment.LEFT) {
+ status |= 0x08;
+ } else if (alignment == TextDisplay.TextAlignment.RIGHT) {
+ status |= 0x0F;
+ }
+
+ if (ignoreDefault || status != 0) {
+ packetSink.accept(textStatusWatcher, status);
+ }
+ }
+}