diff --git a/api/src/main/java/lol/pyr/znpcsplus/util/AttachDirection.java b/api/src/main/java/lol/pyr/znpcsplus/util/AttachDirection.java new file mode 100644 index 0000000..9322749 --- /dev/null +++ b/api/src/main/java/lol/pyr/znpcsplus/util/AttachDirection.java @@ -0,0 +1,10 @@ +package lol.pyr.znpcsplus.util; + +public enum AttachDirection { + DOWN, + UP, + NORTH, + SOUTH, + WEST, + EAST +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java index 3de25dc..e076bc5 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java @@ -65,10 +65,7 @@ import java.io.PrintWriter; import java.io.Reader; import java.nio.file.Files; import java.nio.file.StandardOpenOption; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; +import java.util.*; public class ZNpcsPlus extends JavaPlugin { private final LegacyComponentSerializer textSerializer = LegacyComponentSerializer.builder() @@ -281,6 +278,7 @@ public class ZNpcsPlus extends JavaPlugin { registerEnumParser(manager, TropicalFishVariant.TropicalFishPattern.class, incorrectUsageMessage); registerEnumParser(manager, SnifferState.class, incorrectUsageMessage); registerEnumParser(manager, RabbitType.class, incorrectUsageMessage); + registerEnumParser(manager, AttachDirection.class, incorrectUsageMessage); manager.registerCommand("npc", new MultiCommand(loadHelpMessage("root")) .addSubcommand("center", new CenterCommand(npcRegistry)) diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java index 5c018ef..23e8d52 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java @@ -7,6 +7,7 @@ import com.github.retrooper.packetevents.protocol.nbt.NBTCompound; import com.github.retrooper.packetevents.protocol.nbt.NBTInt; import com.github.retrooper.packetevents.protocol.nbt.NBTString; import com.github.retrooper.packetevents.protocol.player.EquipmentSlot; +import com.github.retrooper.packetevents.protocol.world.BlockFace; import lol.pyr.znpcsplus.api.entity.EntityProperty; import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry; import lol.pyr.znpcsplus.api.skin.SkinDescriptor; @@ -79,6 +80,7 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { registerEnumSerializer(TropicalFishVariant.TropicalFishPattern.class); registerEnumSerializer(SnifferState.class); registerEnumSerializer(RabbitType.class); + registerEnumSerializer(AttachDirection.class); registerPrimitiveSerializers(Integer.class, Boolean.class, Double.class, Float.class, Long.class, Short.class, Byte.class, String.class); @@ -364,6 +366,18 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { } if (!ver.isNewerThanOrEquals(ServerVersion.V_1_9)) return; + // Shulker + int shulkerIndex; + if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) shulkerIndex = 16; + else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) shulkerIndex = 15; + else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) shulkerIndex = 14; + else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) shulkerIndex = 12; + else shulkerIndex = 11; + register(new CustomTypeProperty<>("attach_direction", shulkerIndex++, AttachDirection.DOWN, EntityDataTypes.BLOCK_FACE, attachDir -> BlockFace.valueOf(attachDir.name()))); + register(new EncodedByteProperty<>("shield_height", 0, shulkerIndex++, value -> (byte) Math.max(0, Math.min(100, value)))); + // noinspection deprecation + register(new EncodedByteProperty<>("shulker_color", DyeColor.class, shulkerIndex, DyeColor::getWoolData)); + // Snow Golem int snowGolemIndex; if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) snowGolemIndex = 16; diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/CustomTypeProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/CustomTypeProperty.java new file mode 100644 index 0000000..9946778 --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/CustomTypeProperty.java @@ -0,0 +1,32 @@ +package lol.pyr.znpcsplus.entity.properties; + +import com.github.retrooper.packetevents.protocol.entity.data.EntityData; +import com.github.retrooper.packetevents.protocol.entity.data.EntityDataType; +import lol.pyr.znpcsplus.entity.EntityPropertyImpl; +import lol.pyr.znpcsplus.entity.PacketEntity; +import org.bukkit.entity.Player; + +import java.util.Map; + +public class CustomTypeProperty extends EntityPropertyImpl { + private final int index; + private final EntityDataType type; + private final TypeDecoder decoder; + + @SuppressWarnings("unchecked") + public CustomTypeProperty(String name, int index, T def, EntityDataType type, TypeDecoder decoder) { + super(name, def, (Class) def.getClass()); + this.index = index; + this.type = type; + this.decoder = decoder; + } + + @Override + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + properties.put(index, newEntityData(index, type, decoder.decode(entity.getProperty(this)))); + } + + public interface TypeDecoder { + U decode(T obj); + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeRegistryImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeRegistryImpl.java index efaaba1..3780ed0 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeRegistryImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeRegistryImpl.java @@ -173,7 +173,8 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry { if (!version.isNewerThanOrEquals(ServerVersion.V_1_9)) return; register(builder(p, "shulker", EntityTypes.SHULKER) - .setHologramOffset(-0.975)); + .setHologramOffset(-0.975) + .addProperties("attach_direction", "shield_height", "shulker_color")); if (!version.isNewerThanOrEquals(ServerVersion.V_1_10)) return;