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 11db913..5ac4796 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java @@ -3,6 +3,9 @@ package lol.pyr.znpcsplus.entity; import com.github.retrooper.packetevents.PacketEvents; import com.github.retrooper.packetevents.manager.server.ServerVersion; import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes; +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 lol.pyr.znpcsplus.api.entity.EntityProperty; import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry; @@ -72,10 +75,6 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { /* registerType("using_item", false); // TODO: fix it for 1.8 and add new property to use offhand item and riptide animation - // Player - registerType("shoulder_entity_left", ParrotVariant.NONE); - registerType("shoulder_entity_right", ParrotVariant.NONE); - // End Crystal registerType("beam_target", null); // TODO: Make a block pos class for this registerType("show_base", true); // TODO @@ -368,6 +367,17 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { else parrotIndex = 15; register(new EncodedIntegerProperty<>("parrot_variant", ParrotVariant.RED_BLUE, parrotIndex, Enum::ordinal)); + // Player + NBTProperty.NBTDecoder parrotVariantDecoder = (variant) -> { + NBTCompound compound = new NBTCompound(); + compound.setTag("id", new NBTString("minecraft:parrot")); + compound.setTag("Variant", new NBTInt(variant.ordinal())); + return compound; + }; + int shoulderIndex = skinLayersIndex+2; + register(new NBTProperty<>("shoulder_entity_left", ParrotVariant.class, shoulderIndex++, parrotVariantDecoder)); + register(new NBTProperty<>("shoulder_entity_right", ParrotVariant.class, shoulderIndex, parrotVariantDecoder)); + if (!ver.isNewerThanOrEquals(ServerVersion.V_1_14)) return; // Pose register(new NpcPoseProperty()); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/NBTProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/NBTProperty.java new file mode 100644 index 0000000..9829790 --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/NBTProperty.java @@ -0,0 +1,49 @@ +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 com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes; +import com.github.retrooper.packetevents.protocol.nbt.NBTCompound; +import lol.pyr.znpcsplus.entity.EntityPropertyImpl; +import lol.pyr.znpcsplus.entity.PacketEntity; +import org.bukkit.entity.Player; + +import java.util.Map; + +public class NBTProperty extends EntityPropertyImpl { + private final EntityDataType type; + private final NBTDecoder decoder; + private final int index; + + public NBTProperty(String name, T defaultValue, Class clazz, int index, NBTDecoder decoder, EntityDataType type) { + super(name, defaultValue, clazz); + this.decoder = decoder; + this.index = index; + this.type = type; + } + + @SuppressWarnings("unchecked") + public NBTProperty(String name, T defaultValue, int index, NBTDecoder decoder) { + this(name, defaultValue, (Class) defaultValue.getClass(), index, decoder, EntityDataTypes.NBT); + } + + @SuppressWarnings("unchecked") + public NBTProperty(String name, T defaultValue, int index, NBTDecoder decoder, EntityDataType type) { + this(name, defaultValue, (Class) defaultValue.getClass(), index, decoder, type); + } + + public NBTProperty(String name, Class clazz, int index, NBTDecoder decoder) { + this(name, null, clazz, index, decoder, EntityDataTypes.NBT); + } + + @Override + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + T value = entity.getProperty(this); + if (value == null) return; + properties.put(index, newEntityData(index, type, decoder.decode(value))); + } + + public interface NBTDecoder { + NBTCompound decode(T obj); + } +}