commit
						fb3a22a355
					
				
					 22 changed files with 481 additions and 86 deletions
				
			
		| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					package lol.pyr.znpcsplus.util;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public enum LlamaVariant {
 | 
				
			||||||
 | 
					    CREAMY,
 | 
				
			||||||
 | 
					    WHITE,
 | 
				
			||||||
 | 
					    BROWN,
 | 
				
			||||||
 | 
					    GRAY
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					package lol.pyr.znpcsplus.util;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public enum MooshroomVariant {
 | 
				
			||||||
 | 
					    RED,
 | 
				
			||||||
 | 
					    BROWN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static String getVariantName(MooshroomVariant variant) {
 | 
				
			||||||
 | 
					        return variant.name().toLowerCase();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										8
									
								
								api/src/main/java/lol/pyr/znpcsplus/util/OcelotType.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								api/src/main/java/lol/pyr/znpcsplus/util/OcelotType.java
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					package lol.pyr.znpcsplus.util;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public enum OcelotType {
 | 
				
			||||||
 | 
					    OCELOT,
 | 
				
			||||||
 | 
					    TUXEDO,
 | 
				
			||||||
 | 
					    TABBY,
 | 
				
			||||||
 | 
					    SIAMESE,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								api/src/main/java/lol/pyr/znpcsplus/util/PandaGene.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								api/src/main/java/lol/pyr/znpcsplus/util/PandaGene.java
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					package lol.pyr.znpcsplus.util;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public enum PandaGene {
 | 
				
			||||||
 | 
					    NORMAL,
 | 
				
			||||||
 | 
					    LAZY,
 | 
				
			||||||
 | 
					    WORRIED,
 | 
				
			||||||
 | 
					    PLAYFUL,
 | 
				
			||||||
 | 
					    BROWN,
 | 
				
			||||||
 | 
					    WEAK,
 | 
				
			||||||
 | 
					    AGGRESSIVE
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,5 @@ public enum ParrotVariant {
 | 
				
			||||||
    BLUE,
 | 
					    BLUE,
 | 
				
			||||||
    GREEN,
 | 
					    GREEN,
 | 
				
			||||||
    YELLOW_BLUE,
 | 
					    YELLOW_BLUE,
 | 
				
			||||||
    GRAY,
 | 
					    GRAY
 | 
				
			||||||
    NONE // only used to set empty nbt compound
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										7
									
								
								api/src/main/java/lol/pyr/znpcsplus/util/PuffState.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								api/src/main/java/lol/pyr/znpcsplus/util/PuffState.java
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					package lol.pyr.znpcsplus.util;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public enum PuffState {
 | 
				
			||||||
 | 
					    DEFLATED,
 | 
				
			||||||
 | 
					    HALF_INFLATED,
 | 
				
			||||||
 | 
					    FULLY_INFLATED,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -145,7 +145,7 @@ public class ZNpcsPlus extends JavaPlugin {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        DataImporterRegistry importerRegistry = new DataImporterRegistry(configManager, adventure, bungeeConnector,
 | 
					        DataImporterRegistry importerRegistry = new DataImporterRegistry(configManager, adventure, bungeeConnector,
 | 
				
			||||||
                scheduler, packetFactory, textSerializer, typeRegistry, getDataFolder().getParentFile(),
 | 
					                scheduler, packetFactory, textSerializer, typeRegistry, getDataFolder().getParentFile(),
 | 
				
			||||||
                propertyRegistry, skinCache);
 | 
					                propertyRegistry, skinCache, npcRegistry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        log(ChatColor.WHITE + " * Registerring components...");
 | 
					        log(ChatColor.WHITE + " * Registerring components...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -270,6 +270,11 @@ public class ZNpcsPlus extends JavaPlugin {
 | 
				
			||||||
        registerEnumParser(manager, HorseStyle.class, incorrectUsageMessage);
 | 
					        registerEnumParser(manager, HorseStyle.class, incorrectUsageMessage);
 | 
				
			||||||
        registerEnumParser(manager, HorseColor.class, incorrectUsageMessage);
 | 
					        registerEnumParser(manager, HorseColor.class, incorrectUsageMessage);
 | 
				
			||||||
        registerEnumParser(manager, HorseArmor.class, incorrectUsageMessage);
 | 
					        registerEnumParser(manager, HorseArmor.class, incorrectUsageMessage);
 | 
				
			||||||
 | 
					        registerEnumParser(manager, LlamaVariant.class, incorrectUsageMessage);
 | 
				
			||||||
 | 
					        registerEnumParser(manager, MooshroomVariant.class, incorrectUsageMessage);
 | 
				
			||||||
 | 
					        registerEnumParser(manager, OcelotType.class, incorrectUsageMessage);
 | 
				
			||||||
 | 
					        registerEnumParser(manager, PandaGene.class, incorrectUsageMessage);
 | 
				
			||||||
 | 
					        registerEnumParser(manager, PuffState.class, incorrectUsageMessage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        manager.registerCommand("npc", new MultiCommand(loadHelpMessage("root"))
 | 
					        manager.registerCommand("npc", new MultiCommand(loadHelpMessage("root"))
 | 
				
			||||||
                .addSubcommand("create", new CreateCommand(npcRegistry, typeRegistry))
 | 
					                .addSubcommand("create", new CreateCommand(npcRegistry, typeRegistry))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,7 @@
 | 
				
			||||||
package lol.pyr.znpcsplus.commands.property;
 | 
					package lol.pyr.znpcsplus.commands.property;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.github.retrooper.packetevents.PacketEvents;
 | 
				
			||||||
 | 
					import com.github.retrooper.packetevents.manager.server.ServerVersion;
 | 
				
			||||||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
 | 
					import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
 | 
				
			||||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
 | 
					import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
 | 
				
			||||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
 | 
					import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
 | 
				
			||||||
| 
						 | 
					@ -18,6 +20,7 @@ import net.kyori.adventure.text.format.NamedTextColor;
 | 
				
			||||||
import org.bukkit.Color;
 | 
					import org.bukkit.Color;
 | 
				
			||||||
import com.github.retrooper.packetevents.protocol.item.ItemStack;
 | 
					import com.github.retrooper.packetevents.protocol.item.ItemStack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.Arrays;
 | 
				
			||||||
import java.util.Collections;
 | 
					import java.util.Collections;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,7 +63,7 @@ public class PropertySetCommand implements CommandHandler {
 | 
				
			||||||
            valueName = "NONE";
 | 
					            valueName = "NONE";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (type == ParrotVariant.class && context.argSize() < 1 && npc.getProperty(property) != null) {
 | 
					        else if (type == ParrotVariant.class && context.argSize() < 1 && npc.getProperty(property) != null) {
 | 
				
			||||||
            value = ParrotVariant.NONE;
 | 
					            value = null;
 | 
				
			||||||
            valueName = "NONE";
 | 
					            valueName = "NONE";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (type == BlockState.class) {
 | 
					        else if (type == BlockState.class) {
 | 
				
			||||||
| 
						 | 
					@ -96,6 +99,24 @@ public class PropertySetCommand implements CommandHandler {
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        else if (type == SpellType.class) {
 | 
				
			||||||
 | 
					            if (PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_13)) {
 | 
				
			||||||
 | 
					                value = context.parse(type);
 | 
				
			||||||
 | 
					                valueName = String.valueOf(value);
 | 
				
			||||||
 | 
					                if (((SpellType) value).ordinal() > 3) {
 | 
				
			||||||
 | 
					                    context.send(Component.text("Spell type " + valueName + " is not supported on this version", NamedTextColor.RED));
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                value = context.parse(type);
 | 
				
			||||||
 | 
					                valueName = String.valueOf(value);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if (type == NpcEntryImpl.class) {
 | 
				
			||||||
 | 
					            value = context.parse(type);
 | 
				
			||||||
 | 
					            valueName = value == null ? "NONE" : ((NpcEntryImpl) value).getId();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            value = context.parse(type);
 | 
					            value = context.parse(type);
 | 
				
			||||||
            valueName = String.valueOf(value);
 | 
					            valueName = String.valueOf(value);
 | 
				
			||||||
| 
						 | 
					@ -119,6 +140,9 @@ public class PropertySetCommand implements CommandHandler {
 | 
				
			||||||
                if (type == NamedTextColor.class) return context.suggestCollection(NamedTextColor.NAMES.keys());
 | 
					                if (type == NamedTextColor.class) return context.suggestCollection(NamedTextColor.NAMES.keys());
 | 
				
			||||||
                if (type == Color.class) return context.suggestLiteral("0x0F00FF", "#FFFFFF");
 | 
					                if (type == Color.class) return context.suggestLiteral("0x0F00FF", "#FFFFFF");
 | 
				
			||||||
                if (type == BlockState.class) return context.suggestLiteral("hand", "looking_at", "block");
 | 
					                if (type == BlockState.class) return context.suggestLiteral("hand", "looking_at", "block");
 | 
				
			||||||
 | 
					                if (type == SpellType.class) return PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_13) ?
 | 
				
			||||||
 | 
					                        context.suggestEnum(Arrays.stream(SpellType.values()).filter(spellType -> spellType.ordinal() <= 3).toArray(SpellType[]::new)) :
 | 
				
			||||||
 | 
					                        context.suggestEnum(SpellType.values());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Suggest enum values directly
 | 
					                // Suggest enum values directly
 | 
				
			||||||
                if (type.isEnum()) {
 | 
					                if (type.isEnum()) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,7 @@ import lol.pyr.znpcsplus.config.ConfigManager;
 | 
				
			||||||
import lol.pyr.znpcsplus.conversion.citizens.CitizensImporter;
 | 
					import lol.pyr.znpcsplus.conversion.citizens.CitizensImporter;
 | 
				
			||||||
import lol.pyr.znpcsplus.conversion.znpcs.ZNpcImporter;
 | 
					import lol.pyr.znpcsplus.conversion.znpcs.ZNpcImporter;
 | 
				
			||||||
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
 | 
					import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
 | 
				
			||||||
 | 
					import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
 | 
				
			||||||
import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl;
 | 
					import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl;
 | 
				
			||||||
import lol.pyr.znpcsplus.packets.PacketFactory;
 | 
					import lol.pyr.znpcsplus.packets.PacketFactory;
 | 
				
			||||||
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
 | 
					import lol.pyr.znpcsplus.scheduling.TaskScheduler;
 | 
				
			||||||
| 
						 | 
					@ -25,14 +26,14 @@ public class DataImporterRegistry {
 | 
				
			||||||
    public DataImporterRegistry(ConfigManager configManager, BukkitAudiences adventure, BungeeConnector bungeeConnector,
 | 
					    public DataImporterRegistry(ConfigManager configManager, BukkitAudiences adventure, BungeeConnector bungeeConnector,
 | 
				
			||||||
                                TaskScheduler taskScheduler, PacketFactory packetFactory, LegacyComponentSerializer textSerializer,
 | 
					                                TaskScheduler taskScheduler, PacketFactory packetFactory, LegacyComponentSerializer textSerializer,
 | 
				
			||||||
                                NpcTypeRegistryImpl typeRegistry, File pluginsFolder, EntityPropertyRegistryImpl propertyRegistry,
 | 
					                                NpcTypeRegistryImpl typeRegistry, File pluginsFolder, EntityPropertyRegistryImpl propertyRegistry,
 | 
				
			||||||
                                MojangSkinCache skinCache) {
 | 
					                                MojangSkinCache skinCache, NpcRegistryImpl npcRegistry) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register("znpcs", LazyLoader.of(() -> new ZNpcImporter(configManager, adventure, bungeeConnector, taskScheduler,
 | 
					        register("znpcs", LazyLoader.of(() -> new ZNpcImporter(configManager, adventure, bungeeConnector, taskScheduler,
 | 
				
			||||||
                packetFactory, textSerializer, typeRegistry, propertyRegistry, skinCache, new File(pluginsFolder, "ServersNPC/data.json"))));
 | 
					                packetFactory, textSerializer, typeRegistry, propertyRegistry, skinCache, new File(pluginsFolder, "ServersNPC/data.json"))));
 | 
				
			||||||
        register("znpcsplus_legacy", LazyLoader.of(() -> new ZNpcImporter(configManager, adventure, bungeeConnector, taskScheduler,
 | 
					        register("znpcsplus_legacy", LazyLoader.of(() -> new ZNpcImporter(configManager, adventure, bungeeConnector, taskScheduler,
 | 
				
			||||||
                packetFactory, textSerializer, typeRegistry, propertyRegistry, skinCache, new File(pluginsFolder, "ZNPCsPlusLegacy/data.json"))));
 | 
					                packetFactory, textSerializer, typeRegistry, propertyRegistry, skinCache, new File(pluginsFolder, "ZNPCsPlusLegacy/data.json"))));
 | 
				
			||||||
        register("citizens", LazyLoader.of(() -> new CitizensImporter(configManager, adventure, bungeeConnector, taskScheduler,
 | 
					        register("citizens", LazyLoader.of(() -> new CitizensImporter(configManager, adventure, bungeeConnector, taskScheduler,
 | 
				
			||||||
                packetFactory, textSerializer, typeRegistry, propertyRegistry, skinCache, new File(pluginsFolder, "Citizens/saves.yml"))));
 | 
					                packetFactory, textSerializer, typeRegistry, propertyRegistry, skinCache, new File(pluginsFolder, "Citizens/saves.yml"), npcRegistry)));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void register(String id, LazyLoader<DataImporter> loader) {
 | 
					    private void register(String id, LazyLoader<DataImporter> loader) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,5 @@
 | 
				
			||||||
package lol.pyr.znpcsplus.conversion.citizens;
 | 
					package lol.pyr.znpcsplus.conversion.citizens;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import lol.pyr.znpcsplus.api.NpcApiProvider;
 | 
					 | 
				
			||||||
import lol.pyr.znpcsplus.config.ConfigManager;
 | 
					import lol.pyr.znpcsplus.config.ConfigManager;
 | 
				
			||||||
import lol.pyr.znpcsplus.conversion.DataImporter;
 | 
					import lol.pyr.znpcsplus.conversion.DataImporter;
 | 
				
			||||||
import lol.pyr.znpcsplus.conversion.citizens.model.CitizensTrait;
 | 
					import lol.pyr.znpcsplus.conversion.citizens.model.CitizensTrait;
 | 
				
			||||||
| 
						 | 
					@ -8,6 +7,7 @@ import lol.pyr.znpcsplus.conversion.citizens.model.CitizensTraitsRegistry;
 | 
				
			||||||
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
 | 
					import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
 | 
				
			||||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
 | 
					import lol.pyr.znpcsplus.npc.NpcEntryImpl;
 | 
				
			||||||
import lol.pyr.znpcsplus.npc.NpcImpl;
 | 
					import lol.pyr.znpcsplus.npc.NpcImpl;
 | 
				
			||||||
 | 
					import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
 | 
				
			||||||
import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl;
 | 
					import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl;
 | 
				
			||||||
import lol.pyr.znpcsplus.packets.PacketFactory;
 | 
					import lol.pyr.znpcsplus.packets.PacketFactory;
 | 
				
			||||||
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
 | 
					import lol.pyr.znpcsplus.scheduling.TaskScheduler;
 | 
				
			||||||
| 
						 | 
					@ -39,11 +39,12 @@ public class CitizensImporter implements DataImporter {
 | 
				
			||||||
    private final MojangSkinCache skinCache;
 | 
					    private final MojangSkinCache skinCache;
 | 
				
			||||||
    private final File dataFile;
 | 
					    private final File dataFile;
 | 
				
			||||||
    private final CitizensTraitsRegistry traitsRegistry;
 | 
					    private final CitizensTraitsRegistry traitsRegistry;
 | 
				
			||||||
 | 
					    private final NpcRegistryImpl npcRegistry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public CitizensImporter(ConfigManager configManager, BukkitAudiences adventure, BungeeConnector bungeeConnector,
 | 
					    public CitizensImporter(ConfigManager configManager, BukkitAudiences adventure, BungeeConnector bungeeConnector,
 | 
				
			||||||
                            TaskScheduler taskScheduler, PacketFactory packetFactory, LegacyComponentSerializer textSerializer,
 | 
					                            TaskScheduler taskScheduler, PacketFactory packetFactory, LegacyComponentSerializer textSerializer,
 | 
				
			||||||
                            NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, MojangSkinCache skinCache,
 | 
					                            NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, MojangSkinCache skinCache,
 | 
				
			||||||
                            File dataFile) {
 | 
					                            File dataFile, NpcRegistryImpl npcRegistry) {
 | 
				
			||||||
        this.configManager = configManager;
 | 
					        this.configManager = configManager;
 | 
				
			||||||
        this.adventure = adventure;
 | 
					        this.adventure = adventure;
 | 
				
			||||||
        this.bungeeConnector = bungeeConnector;
 | 
					        this.bungeeConnector = bungeeConnector;
 | 
				
			||||||
| 
						 | 
					@ -55,6 +56,7 @@ public class CitizensImporter implements DataImporter {
 | 
				
			||||||
        this.skinCache = skinCache;
 | 
					        this.skinCache = skinCache;
 | 
				
			||||||
        this.dataFile = dataFile;
 | 
					        this.dataFile = dataFile;
 | 
				
			||||||
        this.traitsRegistry = new CitizensTraitsRegistry(typeRegistry, propertyRegistry, skinCache);
 | 
					        this.traitsRegistry = new CitizensTraitsRegistry(typeRegistry, propertyRegistry, skinCache);
 | 
				
			||||||
 | 
					        this.npcRegistry = npcRegistry;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
| 
						 | 
					@ -96,8 +98,8 @@ public class CitizensImporter implements DataImporter {
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            String id = key.toLowerCase();
 | 
					            String id = key.toLowerCase();
 | 
				
			||||||
            while (NpcApiProvider.get().getNpcRegistry().getById(id) != null) {
 | 
					            while (npcRegistry.getById(id) != null) {
 | 
				
			||||||
                id += "_";
 | 
					                id += "_"; // TODO: make a backup of the old npc instead
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            NpcEntryImpl entry = new NpcEntryImpl(id, npc);
 | 
					            NpcEntryImpl entry = new NpcEntryImpl(id, npc);
 | 
				
			||||||
            entry.enableEverything();
 | 
					            entry.enableEverything();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,9 @@ package lol.pyr.znpcsplus.entity;
 | 
				
			||||||
import com.github.retrooper.packetevents.PacketEvents;
 | 
					import com.github.retrooper.packetevents.PacketEvents;
 | 
				
			||||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
 | 
					import com.github.retrooper.packetevents.manager.server.ServerVersion;
 | 
				
			||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
 | 
					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 com.github.retrooper.packetevents.protocol.player.EquipmentSlot;
 | 
				
			||||||
import lol.pyr.znpcsplus.api.entity.EntityProperty;
 | 
					import lol.pyr.znpcsplus.api.entity.EntityProperty;
 | 
				
			||||||
import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry;
 | 
					import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry;
 | 
				
			||||||
| 
						 | 
					@ -46,6 +49,7 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
 | 
				
			||||||
        registerSerializer(new ColorPropertySerializer());
 | 
					        registerSerializer(new ColorPropertySerializer());
 | 
				
			||||||
        registerSerializer(new Vector3fPropertySerializer());
 | 
					        registerSerializer(new Vector3fPropertySerializer());
 | 
				
			||||||
        registerSerializer(new BlockStatePropertySerializer());
 | 
					        registerSerializer(new BlockStatePropertySerializer());
 | 
				
			||||||
 | 
					        registerSerializer(new IntegerPropertySerializer());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        registerEnumSerializer(NpcPose.class);
 | 
					        registerEnumSerializer(NpcPose.class);
 | 
				
			||||||
        registerEnumSerializer(DyeColor.class);
 | 
					        registerEnumSerializer(DyeColor.class);
 | 
				
			||||||
| 
						 | 
					@ -63,64 +67,36 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
 | 
				
			||||||
        registerEnumSerializer(HorseColor.class);
 | 
					        registerEnumSerializer(HorseColor.class);
 | 
				
			||||||
        registerEnumSerializer(HorseStyle.class);
 | 
					        registerEnumSerializer(HorseStyle.class);
 | 
				
			||||||
        registerEnumSerializer(HorseArmor.class);
 | 
					        registerEnumSerializer(HorseArmor.class);
 | 
				
			||||||
 | 
					        registerEnumSerializer(LlamaVariant.class);
 | 
				
			||||||
 | 
					        registerEnumSerializer(MooshroomVariant.class);
 | 
				
			||||||
 | 
					        registerEnumSerializer(OcelotType.class);
 | 
				
			||||||
 | 
					        registerEnumSerializer(PandaGene.class);
 | 
				
			||||||
 | 
					        registerEnumSerializer(PuffState.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /*
 | 
					        /*
 | 
				
			||||||
        registerType("using_item", false); // TODO: fix it for 1.8 and add new property to use offhand item and riptide animation
 | 
					        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
 | 
					        // End Crystal
 | 
				
			||||||
        registerType("beam_target", null); // TODO: Make a block pos class for this
 | 
					        registerType("beam_target", null); // TODO: Make a block pos class for this
 | 
				
			||||||
        registerType("show_base", true); // TODO
 | 
					        registerType("show_base", true); // TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Creeper
 | 
					 | 
				
			||||||
        registerType("creeper_state", CreeperState.IDLE);
 | 
					 | 
				
			||||||
        registerType("creeper_charged", false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enderman
 | 
					        // Enderman
 | 
				
			||||||
        registerType("enderman_held_block", new BlockState(0)); // TODO: figure out the type on this
 | 
					        registerType("enderman_held_block", new BlockState(0)); // TODO: figure out the type on this
 | 
				
			||||||
        registerType("enderman_screaming", false); // TODO
 | 
					        registerType("enderman_screaming", false); // TODO
 | 
				
			||||||
        registerType("enderman_staring", false); // TODO
 | 
					        registerType("enderman_staring", false); // TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Evoker
 | 
					 | 
				
			||||||
        registerType("evoker_spell", SpellType.NONE);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Frog
 | 
					 | 
				
			||||||
        registerType("frog_variant", FrogVariant.TEMPERATE);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Guardian
 | 
					        // Guardian
 | 
				
			||||||
        registerType("is_elder", false); // TODO: ensure it only works till 1.10. Note: index is wrong on wiki.vg
 | 
					        registerType("is_elder", false); // TODO: ensure it only works till 1.10. Note: index is wrong on wiki.vg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Pufferfish
 | 
					 | 
				
			||||||
        registerType("puff_state", null); // TODO: Make a puff state enum class
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Tropical Fish
 | 
					        // Tropical Fish
 | 
				
			||||||
        registerType("tropical_fish_variant", null); // TODO: Maybe make an enum class for this? its just an int on wiki.vg
 | 
					        registerType("tropical_fish_variant", null); // TODO: Maybe make an enum class for this? its just an int on wiki.vg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Sniffer
 | 
					        // Sniffer
 | 
				
			||||||
        registerType("sniffer_state", null); // TODO: Nothing on wiki.vg, look in mc source
 | 
					        registerType("sniffer_state", null); // TODO: Nothing on wiki.vg, look in mc source
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // LLama
 | 
					 | 
				
			||||||
        registerType("carpet_color", DyeColor.class); // TODO
 | 
					 | 
				
			||||||
        registerType("llama_variant", 0); // TODO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Panda
 | 
					 | 
				
			||||||
        registerType("panda_sneezing", false); // TODO
 | 
					 | 
				
			||||||
        registerType("panda_rolling", false); // TODO
 | 
					 | 
				
			||||||
        registerType("panda_sitting", false); // TODO
 | 
					 | 
				
			||||||
        registerType("panda_on_back", false); // TODO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Pig
 | 
					 | 
				
			||||||
        registerType("pig_saddle", false); // TODO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Rabbit
 | 
					        // Rabbit
 | 
				
			||||||
        registerType("rabbit_type", 0); // TODO: Figure this out
 | 
					        registerType("rabbit_type", 0); // TODO: Figure this out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Polar Bear
 | 
					 | 
				
			||||||
        registerType("polar_bear_standing", false); // TODO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Sheep
 | 
					        // Sheep
 | 
				
			||||||
        registerType("sheep_color", DyeColor.WHITE); // TODO: Figure this out
 | 
					        registerType("sheep_color", DyeColor.WHITE); // TODO: Figure this out
 | 
				
			||||||
        registerType("sheep_sheared", false); // TODO
 | 
					        registerType("sheep_sheared", false); // TODO
 | 
				
			||||||
| 
						 | 
					@ -133,9 +109,6 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
 | 
				
			||||||
        registerType("wolf_collar_color", DyeColor.RED); // TODO
 | 
					        registerType("wolf_collar_color", DyeColor.RED); // TODO
 | 
				
			||||||
        registerType("wolf_angry", false); // TODO
 | 
					        registerType("wolf_angry", false); // TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Parrot
 | 
					 | 
				
			||||||
        registerType("parrot_variant", 0); // TODO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Villager
 | 
					        // Villager
 | 
				
			||||||
        registerType("villager_type", VillagerType.PLAINS);
 | 
					        registerType("villager_type", VillagerType.PLAINS);
 | 
				
			||||||
        registerType("villager_profession", VillagerProfession.NONE);
 | 
					        registerType("villager_profession", VillagerProfession.NONE);
 | 
				
			||||||
| 
						 | 
					@ -149,21 +122,9 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
 | 
				
			||||||
        registerType("shield_height", 0); // TODO: figure this out
 | 
					        registerType("shield_height", 0); // TODO: figure this out
 | 
				
			||||||
        registerType("shulker_color", DyeColor.RED); // TODO
 | 
					        registerType("shulker_color", DyeColor.RED); // TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Piglin
 | 
					 | 
				
			||||||
        registerType("piglin_dancing", false); // TODO
 | 
					 | 
				
			||||||
        registerType("piglin_charging_crossbow", false); // TODO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Vindicator
 | 
					 | 
				
			||||||
        registerType("celebrating", false); // TODO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Wither
 | 
					        // Wither
 | 
				
			||||||
        registerType("invulnerable_time", 0); // TODO
 | 
					        registerType("invulnerable_time", 0); // TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Phantom
 | 
					 | 
				
			||||||
        registerType("phantom_size", 0); // TODO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Slime
 | 
					 | 
				
			||||||
        registerType("slime_size", 0); // TODO
 | 
					 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -271,7 +232,7 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
 | 
				
			||||||
        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) batIndex = 12;
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) batIndex = 12;
 | 
				
			||||||
        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) batIndex = 11;
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) batIndex = 11;
 | 
				
			||||||
        else batIndex = 16;
 | 
					        else batIndex = 16;
 | 
				
			||||||
        register(new BooleanProperty("hanging", batIndex, false, true /* This isnt a mistake */));
 | 
					        register(new BooleanProperty("hanging", batIndex, false, true /* This isn't a mistake */));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Blaze
 | 
					        // Blaze
 | 
				
			||||||
        final int blazeIndex;
 | 
					        final int blazeIndex;
 | 
				
			||||||
| 
						 | 
					@ -303,12 +264,11 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
 | 
				
			||||||
        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) horseIndex = 12;
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) horseIndex = 12;
 | 
				
			||||||
        else horseIndex = 16;
 | 
					        else horseIndex = 16;
 | 
				
			||||||
        int horseEating = ver.isNewerThanOrEquals(ServerVersion.V_1_12) ? 0x10 : 0x20;
 | 
					        int horseEating = ver.isNewerThanOrEquals(ServerVersion.V_1_12) ? 0x10 : 0x20;
 | 
				
			||||||
        boolean v1_8 = ver.isOlderThan(ServerVersion.V_1_9);
 | 
					        register(new BitsetProperty("is_tame", horseIndex, 0x02, false, legacyBooleans));
 | 
				
			||||||
        register(new BitsetProperty("is_tame", horseIndex, 0x02, false, v1_8));
 | 
					        register(new BitsetProperty("is_saddled", horseIndex, 0x04, false, legacyBooleans));
 | 
				
			||||||
        register(new BitsetProperty("is_saddled", horseIndex, 0x04, false, v1_8));
 | 
					        register(new BitsetProperty("is_eating", horseIndex, horseEating, false, legacyBooleans));
 | 
				
			||||||
        register(new BitsetProperty("is_eating", horseIndex, horseEating, false, v1_8));
 | 
					        register(new BitsetProperty("is_rearing", horseIndex, horseEating << 1, false, legacyBooleans));
 | 
				
			||||||
        register(new BitsetProperty("is_rearing", horseIndex, horseEating << 1, false, v1_8));
 | 
					        register(new BitsetProperty("has_mouth_open", horseIndex, horseEating << 2, false, legacyBooleans));
 | 
				
			||||||
        register(new BitsetProperty("has_mouth_open", horseIndex, horseEating << 2, false, v1_8));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Horse
 | 
					        // Horse
 | 
				
			||||||
        if (ver.isNewerThanOrEquals(ServerVersion.V_1_8) && ver.isOlderThan(ServerVersion.V_1_9)) {
 | 
					        if (ver.isNewerThanOrEquals(ServerVersion.V_1_8) && ver.isOlderThan(ServerVersion.V_1_9)) {
 | 
				
			||||||
| 
						 | 
					@ -337,13 +297,100 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Chested Horse
 | 
					        // Chested Horse
 | 
				
			||||||
        if (ver.isOlderThan(ServerVersion.V_1_11)) {
 | 
					        if (ver.isOlderThan(ServerVersion.V_1_11)) {
 | 
				
			||||||
            register(new BitsetProperty("has_chest", horseIndex, 0x08, false, v1_8));
 | 
					            register(new BitsetProperty("has_chest", horseIndex, 0x08, false, legacyBooleans));
 | 
				
			||||||
            linkProperties("is_saddled", "has_chest", "is_eating", "is_rearing", "has_mouth_open");
 | 
					            linkProperties("is_saddled", "has_chest", "is_eating", "is_rearing", "has_mouth_open");
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            register(new BooleanProperty("has_chest", horseVariantIndex, false, legacyBooleans));
 | 
					            register(new BooleanProperty("has_chest", horseVariantIndex, false, legacyBooleans));
 | 
				
			||||||
            linkProperties("is_saddled", "is_eating", "is_rearing", "has_mouth_open");
 | 
					            linkProperties("is_saddled", "is_eating", "is_rearing", "has_mouth_open");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Slime, Magma Cube and Phantom
 | 
				
			||||||
 | 
					        int sizeIndex;
 | 
				
			||||||
 | 
					        if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) sizeIndex = 16;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) sizeIndex = 15;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) sizeIndex = 14;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) sizeIndex = 12;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) sizeIndex = 11;
 | 
				
			||||||
 | 
					        else sizeIndex = 16;
 | 
				
			||||||
 | 
					        register(new IntegerProperty("size", sizeIndex, 1, legacyBooleans));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Ocelot
 | 
				
			||||||
 | 
					        if (ver.isOlderThan(ServerVersion.V_1_14)) {
 | 
				
			||||||
 | 
					            int ocelotIndex;
 | 
				
			||||||
 | 
					            if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) ocelotIndex = 15;
 | 
				
			||||||
 | 
					            else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) ocelotIndex = 14;
 | 
				
			||||||
 | 
					            else ocelotIndex = 18;
 | 
				
			||||||
 | 
					            if (legacyBooleans) register(new EncodedByteProperty<>("ocelot_type", OcelotType.OCELOT, ocelotIndex, obj -> (byte) obj.ordinal()));
 | 
				
			||||||
 | 
					            else register(new EncodedIntegerProperty<>("ocelot_type", OcelotType.OCELOT, ocelotIndex, Enum::ordinal));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Pig
 | 
				
			||||||
 | 
					        int pigIndex;
 | 
				
			||||||
 | 
					        if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) pigIndex = 17;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) pigIndex = 16;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) pigIndex = 15;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) pigIndex = 13;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) pigIndex = 12;
 | 
				
			||||||
 | 
					        else pigIndex = 16;
 | 
				
			||||||
 | 
					        register(new BooleanProperty("pig_saddled", pigIndex, false, legacyBooleans));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!ver.isNewerThanOrEquals(ServerVersion.V_1_10)) return;
 | 
				
			||||||
 | 
					        // Polar Bear
 | 
				
			||||||
 | 
					        int polarBearIndex;
 | 
				
			||||||
 | 
					        if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) polarBearIndex = 17;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) polarBearIndex = 16;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) polarBearIndex = 15;
 | 
				
			||||||
 | 
					        else polarBearIndex = 13;
 | 
				
			||||||
 | 
					        register(new BooleanProperty("polar_bear_standing", polarBearIndex, false, false));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!ver.isNewerThanOrEquals(ServerVersion.V_1_11)) return;
 | 
				
			||||||
 | 
					        // Spellcaster Illager
 | 
				
			||||||
 | 
					        int spellIndex = 12;
 | 
				
			||||||
 | 
					        if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) spellIndex = 17;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) spellIndex = 16;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) spellIndex = 15;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_12)) spellIndex = 13;
 | 
				
			||||||
 | 
					        register(new EncodedByteProperty<>("spell", SpellType.NONE, spellIndex, obj -> (byte) Math.min(obj.ordinal(), ver.isOlderThan(ServerVersion.V_1_13) ? 3 : 5)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Llama
 | 
				
			||||||
 | 
					        int llamaIndex;
 | 
				
			||||||
 | 
					        if (ver.isNewerThanOrEquals(ServerVersion.V_1_18)) llamaIndex = 20;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) llamaIndex = 21;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) llamaIndex = 20;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) llamaIndex = 19;
 | 
				
			||||||
 | 
					        else llamaIndex = 17;
 | 
				
			||||||
 | 
					        register(new EncodedIntegerProperty<DyeColor>("carpet_color", DyeColor.class, llamaIndex++, obj -> obj == null ? -1 : obj.ordinal()));
 | 
				
			||||||
 | 
					        register(new EncodedIntegerProperty<>("llama_variant", LlamaVariant.CREAMY, llamaIndex, Enum::ordinal));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!ver.isNewerThanOrEquals(ServerVersion.V_1_12)) return;
 | 
				
			||||||
 | 
					        // Parrot
 | 
				
			||||||
 | 
					        int parrotIndex;
 | 
				
			||||||
 | 
					        if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) parrotIndex = 19;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) parrotIndex = 18;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) parrotIndex = 17;
 | 
				
			||||||
 | 
					        else parrotIndex = 15;
 | 
				
			||||||
 | 
					        register(new EncodedIntegerProperty<>("parrot_variant", ParrotVariant.RED_BLUE, parrotIndex, Enum::ordinal));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Player
 | 
				
			||||||
 | 
					        NBTProperty.NBTDecoder<ParrotVariant> 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_13)) return;
 | 
				
			||||||
 | 
					        // Pufferfish
 | 
				
			||||||
 | 
					        int pufferfishIndex;
 | 
				
			||||||
 | 
					        if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) pufferfishIndex = 17;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) pufferfishIndex = 16;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) pufferfishIndex = 15;
 | 
				
			||||||
 | 
					        else pufferfishIndex = 13;
 | 
				
			||||||
 | 
					        register(new EncodedIntegerProperty<>("puff_state", PuffState.DEFLATED, pufferfishIndex, Enum::ordinal));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!ver.isNewerThanOrEquals(ServerVersion.V_1_14)) return;
 | 
					        if (!ver.isNewerThanOrEquals(ServerVersion.V_1_14)) return;
 | 
				
			||||||
        // Pose
 | 
					        // Pose
 | 
				
			||||||
        register(new NpcPoseProperty());
 | 
					        register(new NpcPoseProperty());
 | 
				
			||||||
| 
						 | 
					@ -369,6 +416,32 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
 | 
				
			||||||
        register(new BitsetProperty("fox_sleeping", foxIndex, 0x20));
 | 
					        register(new BitsetProperty("fox_sleeping", foxIndex, 0x20));
 | 
				
			||||||
        linkProperties("fox_sitting", "fox_crouching", "fox_sleeping");
 | 
					        linkProperties("fox_sitting", "fox_crouching", "fox_sleeping");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int mooshroomIndex;
 | 
				
			||||||
 | 
					        if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) mooshroomIndex = 17;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) mooshroomIndex = 16;
 | 
				
			||||||
 | 
					        else mooshroomIndex = 15;
 | 
				
			||||||
 | 
					        register(new EncodedStringProperty<>("mooshroom_variant", MooshroomVariant.RED, mooshroomIndex, MooshroomVariant::getVariantName));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Panda
 | 
				
			||||||
 | 
					        int pandaIndex;
 | 
				
			||||||
 | 
					        if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) pandaIndex = 20;
 | 
				
			||||||
 | 
					        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) pandaIndex = 19;
 | 
				
			||||||
 | 
					        else pandaIndex = 18;
 | 
				
			||||||
 | 
					        register(new EncodedByteProperty<>("panda_main_gene", PandaGene.NORMAL, pandaIndex++, obj -> (byte) obj.ordinal()));
 | 
				
			||||||
 | 
					        register(new EncodedByteProperty<>("panda_hidden_gene", PandaGene.NORMAL, pandaIndex++, obj -> (byte) obj.ordinal()));
 | 
				
			||||||
 | 
					        if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) {
 | 
				
			||||||
 | 
					            register(new BitsetProperty("panda_sneezing", pandaIndex, 0x02));
 | 
				
			||||||
 | 
					            register(new BitsetProperty("panda_rolling", pandaIndex, 0x04));
 | 
				
			||||||
 | 
					            register(new BitsetProperty("panda_sitting", pandaIndex, 0x08));
 | 
				
			||||||
 | 
					            register(new BitsetProperty("panda_on_back", pandaIndex, 0x10));
 | 
				
			||||||
 | 
					            linkProperties("panda_sneezing", "panda_rolling", "panda_sitting", "panda_on_back");
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            register(new BitsetProperty("panda_sneezing", pandaIndex, 0x02));
 | 
				
			||||||
 | 
					            register(new BitsetProperty("panda_eating", pandaIndex, 0x04));
 | 
				
			||||||
 | 
					            linkProperties("panda_sneezing", "panda_eating");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!ver.isNewerThanOrEquals(ServerVersion.V_1_15)) return;
 | 
					        if (!ver.isNewerThanOrEquals(ServerVersion.V_1_15)) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(new BitsetProperty("fox_faceplanted", foxIndex, 0x40));
 | 
					        register(new BitsetProperty("fox_faceplanted", foxIndex, 0x40));
 | 
				
			||||||
| 
						 | 
					@ -383,10 +456,26 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!ver.isNewerThanOrEquals(ServerVersion.V_1_16)) return;
 | 
					        if (!ver.isNewerThanOrEquals(ServerVersion.V_1_16)) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Hoglin and Piglin Zombification
 | 
				
			||||||
        final int zombificationIndex;
 | 
					        final int zombificationIndex;
 | 
				
			||||||
        if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) zombificationIndex = 17;
 | 
					        if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) zombificationIndex = 17; // Change piglinIndex and pillagerIndex if you change this
 | 
				
			||||||
        else zombificationIndex = 16;
 | 
					        else zombificationIndex = 16;
 | 
				
			||||||
        register(new BooleanProperty("immune_to_zombification", zombificationIndex, false, legacyBooleans));
 | 
					        register(new BooleanProperty("hoglin_immune_to_zombification", zombificationIndex, false, legacyBooleans));
 | 
				
			||||||
 | 
					        register(new BooleanProperty("piglin_immune_to_zombification", zombificationIndex-1, false, legacyBooleans));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Piglin
 | 
				
			||||||
 | 
					        int piglinIndex = zombificationIndex;
 | 
				
			||||||
 | 
					        register(new BooleanProperty("piglin_baby", piglinIndex++, false, legacyBooleans));
 | 
				
			||||||
 | 
					        register(new BooleanProperty("piglin_charging_crossbow", piglinIndex++, false, legacyBooleans));
 | 
				
			||||||
 | 
					        register(new BooleanProperty("piglin_dancing", piglinIndex, false, legacyBooleans));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Pillager
 | 
				
			||||||
 | 
					        int pillagerIndex = zombificationIndex;
 | 
				
			||||||
 | 
					        register(new BooleanProperty("pillager_charging", pillagerIndex, false, legacyBooleans));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Vindicator
 | 
				
			||||||
 | 
					        int vindicatorIndex = pillagerIndex-1;
 | 
				
			||||||
 | 
					        register(new BooleanProperty("celebrating", vindicatorIndex, false, legacyBooleans));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!ver.isNewerThanOrEquals(ServerVersion.V_1_17)) return;
 | 
					        if (!ver.isNewerThanOrEquals(ServerVersion.V_1_17)) return;
 | 
				
			||||||
        // Axolotl
 | 
					        // Axolotl
 | 
				
			||||||
| 
						 | 
					@ -398,6 +487,9 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
 | 
				
			||||||
        register(new BooleanProperty("has_right_horn", 19, true, legacyBooleans));
 | 
					        register(new BooleanProperty("has_right_horn", 19, true, legacyBooleans));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(new EncodedIntegerProperty<>("shaking", false,7, enabled -> enabled ? 140 : 0));
 | 
					        register(new EncodedIntegerProperty<>("shaking", false,7, enabled -> enabled ? 140 : 0));
 | 
				
			||||||
 | 
					        if (!ver.isNewerThanOrEquals(ServerVersion.V_1_19)) return;
 | 
				
			||||||
 | 
					        // Frog
 | 
				
			||||||
 | 
					        register(new EncodedIntegerProperty<>("frog_variant", FrogVariant.TEMPERATE, 17, Enum::ordinal, EntityDataTypes.FROG_VARIANT));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!ver.isNewerThanOrEquals(ServerVersion.V_1_20)) return;
 | 
					        if (!ver.isNewerThanOrEquals(ServerVersion.V_1_20)) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,11 @@ public class EnumPropertySerializer<T extends Enum<T>> implements PropertySerial
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public T deserialize(String property) {
 | 
					    public T deserialize(String property) {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
            return Enum.valueOf(enumClass, property.toUpperCase());
 | 
					            return Enum.valueOf(enumClass, property.toUpperCase());
 | 
				
			||||||
 | 
					        } catch (IllegalArgumentException e) {
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,48 @@
 | 
				
			||||||
 | 
					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 lol.pyr.znpcsplus.entity.EntityPropertyImpl;
 | 
				
			||||||
 | 
					import lol.pyr.znpcsplus.entity.PacketEntity;
 | 
				
			||||||
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class EncodedStringProperty<T> extends EntityPropertyImpl<T> {
 | 
				
			||||||
 | 
					    private final EntityDataType<String> type;
 | 
				
			||||||
 | 
					    private final EncodedStringProperty.StringDecoder<T> decoder;
 | 
				
			||||||
 | 
					    private final int index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public EncodedStringProperty(String name, T defaultValue, Class<T> clazz, int index, StringDecoder<T> decoder, EntityDataType<String> type) {
 | 
				
			||||||
 | 
					        super(name, defaultValue, clazz);
 | 
				
			||||||
 | 
					        this.decoder = decoder;
 | 
				
			||||||
 | 
					        this.index = index;
 | 
				
			||||||
 | 
					        this.type = type;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @SuppressWarnings("unchecked")
 | 
				
			||||||
 | 
					    public EncodedStringProperty(String name, T defaultValue, int index, StringDecoder<T> decoder) {
 | 
				
			||||||
 | 
					        this(name, defaultValue, (Class<T>) defaultValue.getClass(), index, decoder, EntityDataTypes.STRING);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @SuppressWarnings("unchecked")
 | 
				
			||||||
 | 
					    public EncodedStringProperty(String name, T defaultValue, int index, StringDecoder<T> decoder, EntityDataType<String> type) {
 | 
				
			||||||
 | 
					        this(name, defaultValue, (Class<T>) defaultValue.getClass(), index, decoder, type);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public EncodedStringProperty(String name, Class<T> clazz, int index, StringDecoder<T> decoder) {
 | 
				
			||||||
 | 
					        this(name, null, clazz, index, decoder, EntityDataTypes.STRING);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
 | 
				
			||||||
 | 
					        T value = entity.getProperty(this);
 | 
				
			||||||
 | 
					        if (value == null) return;
 | 
				
			||||||
 | 
					        properties.put(index, newEntityData(index, type, decoder.decode(value)));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public interface StringDecoder<T> {
 | 
				
			||||||
 | 
					        String decode(T obj);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -10,14 +10,22 @@ import java.util.Map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class IntegerProperty extends EntityPropertyImpl<Integer> {
 | 
					public class IntegerProperty extends EntityPropertyImpl<Integer> {
 | 
				
			||||||
    private final int index;
 | 
					    private final int index;
 | 
				
			||||||
 | 
					    private final boolean legacy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected IntegerProperty(String name, int index, Integer defaultValue) {
 | 
					    public IntegerProperty(String name, int index, Integer defaultValue) {
 | 
				
			||||||
 | 
					        this(name, index, defaultValue, false);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public IntegerProperty(String name, int index, Integer defaultValue, boolean legacy) {
 | 
				
			||||||
        super(name, defaultValue, Integer.class);
 | 
					        super(name, defaultValue, Integer.class);
 | 
				
			||||||
        this.index = index;
 | 
					        this.index = index;
 | 
				
			||||||
 | 
					        this.legacy = legacy;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
 | 
					    public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
 | 
				
			||||||
        properties.put(index, newEntityData(index, EntityDataTypes.INT, entity.getProperty(this)));
 | 
					        properties.put(index, legacy ?
 | 
				
			||||||
 | 
					                newEntityData(index, EntityDataTypes.BYTE, (byte) entity.getProperty(this).intValue()) :
 | 
				
			||||||
 | 
					                newEntityData(index, EntityDataTypes.INT, entity.getProperty(this)));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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<T> extends EntityPropertyImpl<T> {
 | 
				
			||||||
 | 
					    private final EntityDataType<NBTCompound> type;
 | 
				
			||||||
 | 
					    private final NBTDecoder<T> decoder;
 | 
				
			||||||
 | 
					    private final int index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public NBTProperty(String name, T defaultValue, Class<T> clazz, int index, NBTDecoder<T> decoder, EntityDataType<NBTCompound> 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<T> decoder) {
 | 
				
			||||||
 | 
					        this(name, defaultValue, (Class<T>) defaultValue.getClass(), index, decoder, EntityDataTypes.NBT);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @SuppressWarnings("unchecked")
 | 
				
			||||||
 | 
					    public NBTProperty(String name, T defaultValue, int index, NBTDecoder<T> decoder, EntityDataType<NBTCompound> type) {
 | 
				
			||||||
 | 
					        this(name, defaultValue, (Class<T>) defaultValue.getClass(), index, decoder, type);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public NBTProperty(String name, Class<T> clazz, int index, NBTDecoder<T> decoder) {
 | 
				
			||||||
 | 
					        this(name, null, clazz, index, decoder, EntityDataTypes.NBT);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
 | 
				
			||||||
 | 
					        T value = entity.getProperty(this);
 | 
				
			||||||
 | 
					        if (value == null) return;
 | 
				
			||||||
 | 
					        properties.put(index, newEntityData(index, type, decoder.decode(value)));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public interface NBTDecoder<T> {
 | 
				
			||||||
 | 
					        NBTCompound decode(T obj);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@ import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
 | 
				
			||||||
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
 | 
					import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
 | 
				
			||||||
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
 | 
					import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
 | 
				
			||||||
import lol.pyr.znpcsplus.entity.PacketEntity;
 | 
					import lol.pyr.znpcsplus.entity.PacketEntity;
 | 
				
			||||||
 | 
					import lol.pyr.znpcsplus.util.PapiUtil;
 | 
				
			||||||
import net.kyori.adventure.text.Component;
 | 
					import net.kyori.adventure.text.Component;
 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +30,7 @@ public class NameProperty extends EntityPropertyImpl<Component> {
 | 
				
			||||||
            String serialized = legacy ?
 | 
					            String serialized = legacy ?
 | 
				
			||||||
                    AdventureSerializer.getLegacyGsonSerializer().serialize(value) :
 | 
					                    AdventureSerializer.getLegacyGsonSerializer().serialize(value) :
 | 
				
			||||||
                    AdventureSerializer.getGsonSerializer().serialize(value);
 | 
					                    AdventureSerializer.getGsonSerializer().serialize(value);
 | 
				
			||||||
 | 
					            serialized = PapiUtil.set(player, serialized);
 | 
				
			||||||
            if (optional) properties.put(2, newEntityData(2, EntityDataTypes.OPTIONAL_COMPONENT, Optional.of(serialized)));
 | 
					            if (optional) properties.put(2, newEntityData(2, EntityDataTypes.OPTIONAL_COMPONENT, Optional.of(serialized)));
 | 
				
			||||||
            else properties.put(2, newEntityData(2, EntityDataTypes.STRING, serialized));
 | 
					            else properties.put(2, newEntityData(2, EntityDataTypes.STRING, serialized));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,29 @@
 | 
				
			||||||
 | 
					package lol.pyr.znpcsplus.entity.properties;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
 | 
				
			||||||
 | 
					import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
 | 
				
			||||||
 | 
					import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
 | 
				
			||||||
 | 
					import lol.pyr.znpcsplus.entity.PacketEntity;
 | 
				
			||||||
 | 
					import lol.pyr.znpcsplus.npc.NpcEntryImpl;
 | 
				
			||||||
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class TargetNpcProperty extends EntityPropertyImpl<NpcEntryImpl> {
 | 
				
			||||||
 | 
					    private final int index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public TargetNpcProperty(String name, int index, NpcEntryImpl defaultValue) {
 | 
				
			||||||
 | 
					        super(name, defaultValue, NpcEntryImpl.class);
 | 
				
			||||||
 | 
					        this.index = index;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
 | 
				
			||||||
 | 
					        NpcEntryImpl value = entity.getProperty(this);
 | 
				
			||||||
 | 
					        if (value == null) return;
 | 
				
			||||||
 | 
					        if (value.getNpc().getEntity().getEntityId() == entity.getEntityId()) return;
 | 
				
			||||||
 | 
					        if (value.getNpc().isVisibleTo(player)) {
 | 
				
			||||||
 | 
					            properties.put(index, newEntityData(index, EntityDataTypes.INT, value.getNpc().getEntity().getEntityId()));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,25 @@
 | 
				
			||||||
 | 
					package lol.pyr.znpcsplus.entity.serializers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import lol.pyr.znpcsplus.entity.PropertySerializer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class IntegerPropertySerializer implements PropertySerializer<Integer> {
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public String serialize(Integer property) {
 | 
				
			||||||
 | 
					        return String.valueOf(property);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public Integer deserialize(String property) {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            return Integer.parseInt(property);
 | 
				
			||||||
 | 
					        } catch (NumberFormatException e) {
 | 
				
			||||||
 | 
					            e.printStackTrace();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public Class<Integer> getTypeClass() {
 | 
				
			||||||
 | 
					        return Integer.class;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					package lol.pyr.znpcsplus.entity.serializers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import lol.pyr.znpcsplus.entity.PropertySerializer;
 | 
				
			||||||
 | 
					import lol.pyr.znpcsplus.npc.NpcEntryImpl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class TargetNpcPropertySerializer implements PropertySerializer<NpcEntryImpl> {
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public String serialize(NpcEntryImpl property) {
 | 
				
			||||||
 | 
					        return property.getId();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public NpcEntryImpl deserialize(String property) {
 | 
				
			||||||
 | 
					        return null; // TODO: find a way to do this
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public Class<NpcEntryImpl> getTypeClass() {
 | 
				
			||||||
 | 
					        return NpcEntryImpl.class;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -110,6 +110,7 @@ public class NpcTypeImpl implements NpcType {
 | 
				
			||||||
            ServerVersion version = PacketEvents.getAPI().getServerManager().getVersion();
 | 
					            ServerVersion version = PacketEvents.getAPI().getServerManager().getVersion();
 | 
				
			||||||
            addProperties("fire", "invisible", "silent", "look",
 | 
					            addProperties("fire", "invisible", "silent", "look",
 | 
				
			||||||
                    "potion_color", "potion_ambient", "dinnerbone");
 | 
					                    "potion_color", "potion_ambient", "dinnerbone");
 | 
				
			||||||
 | 
					            // TODO: make this look nicer after completing the rest of the properties
 | 
				
			||||||
            if (version.isNewerThanOrEquals(ServerVersion.V_1_9)) addProperties("glow");
 | 
					            if (version.isNewerThanOrEquals(ServerVersion.V_1_9)) addProperties("glow");
 | 
				
			||||||
            if (version.isNewerThanOrEquals(ServerVersion.V_1_14)) {
 | 
					            if (version.isNewerThanOrEquals(ServerVersion.V_1_14)) {
 | 
				
			||||||
                addProperties("pose");
 | 
					                addProperties("pose");
 | 
				
			||||||
| 
						 | 
					@ -118,7 +119,7 @@ public class NpcTypeImpl implements NpcType {
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (version.isNewerThanOrEquals(ServerVersion.V_1_17)) addProperties("shaking");
 | 
					            if (version.isNewerThanOrEquals(ServerVersion.V_1_17)) addProperties("shaking");
 | 
				
			||||||
            if (EntityTypes.isTypeInstanceOf(type, EntityTypes.ABSTRACT_AGEABLE)) {
 | 
					            if (EntityTypes.isTypeInstanceOf(type, EntityTypes.ABSTRACT_AGEABLE) || EntityTypes.isTypeInstanceOf(type, EntityTypes.ZOMBIE) || EntityTypes.isTypeInstanceOf(type, EntityTypes.ZOGLIN)) {
 | 
				
			||||||
                addProperties("baby");
 | 
					                addProperties("baby");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (EntityTypes.isTypeInstanceOf(type, EntityTypes.ABSTRACT_HORSE)) {
 | 
					            if (EntityTypes.isTypeInstanceOf(type, EntityTypes.ABSTRACT_HORSE)) {
 | 
				
			||||||
| 
						 | 
					@ -129,6 +130,27 @@ public class NpcTypeImpl implements NpcType {
 | 
				
			||||||
            } else if (version.isOlderThan(ServerVersion.V_1_11) && type.equals(EntityTypes.HORSE)) {
 | 
					            } else if (version.isOlderThan(ServerVersion.V_1_11) && type.equals(EntityTypes.HORSE)) {
 | 
				
			||||||
                addProperties("has_chest");
 | 
					                addProperties("has_chest");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            if (EntityTypes.isTypeInstanceOf(type, EntityTypes.ABSTRACT_EVO_ILLU_ILLAGER)) {
 | 
				
			||||||
 | 
					                addProperties("spell");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (EntityTypes.isTypeInstanceOf(type, EntityTypes.ABSTRACT_PIGLIN)) {
 | 
				
			||||||
 | 
					                addProperties("piglin_immune_to_zombification");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (EntityTypes.isTypeInstanceOf(type, EntityTypes.SLIME) || EntityTypes.isTypeInstanceOf(type, EntityTypes.PHANTOM)) {
 | 
				
			||||||
 | 
					                addProperties("size");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (version.isOlderThan(ServerVersion.V_1_14)) {
 | 
				
			||||||
 | 
					                if (EntityTypes.isTypeInstanceOf(type, EntityTypes.OCELOT)) {
 | 
				
			||||||
 | 
					                    addProperties("ocelot_type");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (EntityTypes.isTypeInstanceOf(type, EntityTypes.PANDA)) {
 | 
				
			||||||
 | 
					                if (version.isNewerThanOrEquals(ServerVersion.V_1_15)) {
 | 
				
			||||||
 | 
					                    addProperties("panda_rolling", "panda_sitting", "panda_on_back");
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    addProperties("panda_eating");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            return new NpcTypeImpl(name, type, hologramOffset, new HashSet<>(allowedProperties), defaultProperties);
 | 
					            return new NpcTypeImpl(name, type, hologramOffset, new HashSet<>(allowedProperties), defaultProperties);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -104,13 +104,15 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry {
 | 
				
			||||||
        register(builder(p, "magma_cube", EntityTypes.MAGMA_CUBE)); // TODO: Hologram offset scaling with size property
 | 
					        register(builder(p, "magma_cube", EntityTypes.MAGMA_CUBE)); // TODO: Hologram offset scaling with size property
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "mooshroom", EntityTypes.MOOSHROOM)
 | 
					        register(builder(p, "mooshroom", EntityTypes.MOOSHROOM)
 | 
				
			||||||
                .setHologramOffset(-0.575));
 | 
					                .setHologramOffset(-0.575)
 | 
				
			||||||
 | 
					                .addProperties("mooshroom_variant"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "ocelot", EntityTypes.OCELOT)
 | 
					        register(builder(p, "ocelot", EntityTypes.OCELOT)
 | 
				
			||||||
                .setHologramOffset(-1.275));
 | 
					                .setHologramOffset(-1.275));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "pig", EntityTypes.PIG)
 | 
					        register(builder(p, "pig", EntityTypes.PIG)
 | 
				
			||||||
                .setHologramOffset(-1.075));
 | 
					                .setHologramOffset(-1.075)
 | 
				
			||||||
 | 
					                .addProperties("pig_saddled"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "rabbit", EntityTypes.RABBIT)
 | 
					        register(builder(p, "rabbit", EntityTypes.RABBIT)
 | 
				
			||||||
                .setHologramOffset(-1.475));
 | 
					                .setHologramOffset(-1.475));
 | 
				
			||||||
| 
						 | 
					@ -173,7 +175,8 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry {
 | 
				
			||||||
        if (!version.isNewerThanOrEquals(ServerVersion.V_1_10)) return;
 | 
					        if (!version.isNewerThanOrEquals(ServerVersion.V_1_10)) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "polar_bear", EntityTypes.POLAR_BEAR)
 | 
					        register(builder(p, "polar_bear", EntityTypes.POLAR_BEAR)
 | 
				
			||||||
                .setHologramOffset(-0.575));
 | 
					                .setHologramOffset(-0.575)
 | 
				
			||||||
 | 
					                .addProperties("polar_bear_standing"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!version.isNewerThanOrEquals(ServerVersion.V_1_11)) return;
 | 
					        if (!version.isNewerThanOrEquals(ServerVersion.V_1_11)) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -202,14 +205,16 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry {
 | 
				
			||||||
                .addProperties("evoker_spell"));
 | 
					                .addProperties("evoker_spell"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "llama", EntityTypes.LLAMA)
 | 
					        register(builder(p, "llama", EntityTypes.LLAMA)
 | 
				
			||||||
                .setHologramOffset(-0.105));
 | 
					                .setHologramOffset(-0.105)
 | 
				
			||||||
 | 
					                .addProperties("carpet_color", "llama_variant"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "vex", EntityTypes.VEX)
 | 
					        register(builder(p, "vex", EntityTypes.VEX)
 | 
				
			||||||
                .setHologramOffset(-1.175)
 | 
					                .setHologramOffset(-1.175)
 | 
				
			||||||
                .addHandProperties());
 | 
					                .addHandProperties());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "vindicator", EntityTypes.VINDICATOR)
 | 
					        register(builder(p, "vindicator", EntityTypes.VINDICATOR)
 | 
				
			||||||
                .setHologramOffset(-0.025));
 | 
					                .setHologramOffset(-0.025)
 | 
				
			||||||
 | 
					                .addProperties("celebrating"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "wither_skeleton", EntityTypes.WITHER_SKELETON)
 | 
					        register(builder(p, "wither_skeleton", EntityTypes.WITHER_SKELETON)
 | 
				
			||||||
                .setHologramOffset(0.425)
 | 
					                .setHologramOffset(0.425)
 | 
				
			||||||
| 
						 | 
					@ -225,7 +230,8 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry {
 | 
				
			||||||
                .setHologramOffset(-0.025));
 | 
					                .setHologramOffset(-0.025));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "parrot", EntityTypes.PARROT)
 | 
					        register(builder(p, "parrot", EntityTypes.PARROT)
 | 
				
			||||||
                .setHologramOffset(-1.075));
 | 
					                .setHologramOffset(-1.075)
 | 
				
			||||||
 | 
					                .addProperties("parrot_variant"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!version.isNewerThanOrEquals(ServerVersion.V_1_13)) return;
 | 
					        if (!version.isNewerThanOrEquals(ServerVersion.V_1_13)) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -244,7 +250,8 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry {
 | 
				
			||||||
                .setHologramOffset(-1.475));
 | 
					                .setHologramOffset(-1.475));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "pufferfish", EntityTypes.PUFFERFISH)
 | 
					        register(builder(p, "pufferfish", EntityTypes.PUFFERFISH)
 | 
				
			||||||
                .setHologramOffset(-1.625));
 | 
					                .setHologramOffset(-1.625)
 | 
				
			||||||
 | 
					                .addProperties("puff_state"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "salmon", EntityTypes.SALMON)
 | 
					        register(builder(p, "salmon", EntityTypes.SALMON)
 | 
				
			||||||
                .setHologramOffset(-1.575));
 | 
					                .setHologramOffset(-1.575));
 | 
				
			||||||
| 
						 | 
					@ -266,17 +273,20 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry {
 | 
				
			||||||
                .addProperties("hand", "fox_variant", "fox_sitting", "fox_crouching", "fox_sleeping", "fox_faceplanted"));
 | 
					                .addProperties("hand", "fox_variant", "fox_sitting", "fox_crouching", "fox_sleeping", "fox_faceplanted"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "panda", EntityTypes.PANDA)
 | 
					        register(builder(p, "panda", EntityTypes.PANDA)
 | 
				
			||||||
                .setHologramOffset(-0.725));
 | 
					                .setHologramOffset(-0.725)
 | 
				
			||||||
 | 
					                .addProperties("panda_main_gene", "panda_hidden_gene", "panda_sneezing"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "pillager", EntityTypes.PILLAGER)
 | 
					        register(builder(p, "pillager", EntityTypes.PILLAGER)
 | 
				
			||||||
                .setHologramOffset(-0.025)
 | 
					                .setHologramOffset(-0.025)
 | 
				
			||||||
                .addHandProperties());
 | 
					                .addHandProperties()
 | 
				
			||||||
 | 
					                .addProperties("pillager_charging"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "ravager", EntityTypes.RAVAGER)
 | 
					        register(builder(p, "ravager", EntityTypes.RAVAGER)
 | 
				
			||||||
                .setHologramOffset(0.225));
 | 
					                .setHologramOffset(0.225));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "trader_llama", EntityTypes.TRADER_LLAMA)
 | 
					        register(builder(p, "trader_llama", EntityTypes.TRADER_LLAMA)
 | 
				
			||||||
                .setHologramOffset(-0.105));
 | 
					                .setHologramOffset(-0.105)
 | 
				
			||||||
 | 
					                .addProperties("llama_variant"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "wandering_trader", EntityTypes.WANDERING_TRADER)
 | 
					        register(builder(p, "wandering_trader", EntityTypes.WANDERING_TRADER)
 | 
				
			||||||
                .setHologramOffset(-0.025)
 | 
					                .setHologramOffset(-0.025)
 | 
				
			||||||
| 
						 | 
					@ -292,11 +302,12 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "hoglin", EntityTypes.HOGLIN)
 | 
					        register(builder(p, "hoglin", EntityTypes.HOGLIN)
 | 
				
			||||||
                .setHologramOffset(-0.575)
 | 
					                .setHologramOffset(-0.575)
 | 
				
			||||||
                .addProperties("immune_to_zombification"));
 | 
					                .addProperties("hoglin_immune_to_zombification"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "piglin", EntityTypes.PIGLIN)
 | 
					        register(builder(p, "piglin", EntityTypes.PIGLIN)
 | 
				
			||||||
                .setHologramOffset(-1.0)
 | 
					                .setHologramOffset(-1.0)
 | 
				
			||||||
                .addEquipmentProperties());
 | 
					                .addEquipmentProperties()
 | 
				
			||||||
 | 
					                .addProperties("piglin_baby", "piglin_charging_crossbow", "piglin_dancing"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "piglin_brute", EntityTypes.PIGLIN_BRUTE)
 | 
					        register(builder(p, "piglin_brute", EntityTypes.PIGLIN_BRUTE)
 | 
				
			||||||
                .setHologramOffset(-0.025)
 | 
					                .setHologramOffset(-0.025)
 | 
				
			||||||
| 
						 | 
					@ -329,7 +340,7 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "frog", EntityTypes.FROG)
 | 
					        register(builder(p, "frog", EntityTypes.FROG)
 | 
				
			||||||
                .setHologramOffset(-1.475)
 | 
					                .setHologramOffset(-1.475)
 | 
				
			||||||
                .addProperties("frog_variant"));
 | 
					                .addProperties("frog_variant", "frog_target_npc"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        register(builder(p, "tadpole", EntityTypes.TADPOLE)
 | 
					        register(builder(p, "tadpole", EntityTypes.TADPOLE)
 | 
				
			||||||
                .setHologramOffset(-1.675));
 | 
					                .setHologramOffset(-1.675));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,7 +70,12 @@ public class YamlStorage implements NpcStorage {
 | 
				
			||||||
                        Bukkit.getLogger().log(Level.WARNING, "Unknown serializer for property '" + key + "' for npc '" + config.getString("id") + "'. skipping ...");
 | 
					                        Bukkit.getLogger().log(Level.WARNING, "Unknown serializer for property '" + key + "' for npc '" + config.getString("id") + "'. skipping ...");
 | 
				
			||||||
                        continue;
 | 
					                        continue;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    npc.UNSAFE_setProperty(property, serializer.deserialize(properties.getString(key)));
 | 
					                    Object value = serializer.deserialize(properties.getString(key));
 | 
				
			||||||
 | 
					                    if (value == null) {
 | 
				
			||||||
 | 
					                        Bukkit.getLogger().log(Level.WARNING, "Failed to deserialize property '" + key + "' for npc '" + config.getString("id") + "'. Resetting to default ...");
 | 
				
			||||||
 | 
					                        value = property.getDefaultValue();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    npc.UNSAFE_setProperty(property, value);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            HologramImpl hologram = npc.getHologram();
 | 
					            HologramImpl hologram = npc.getHologram();
 | 
				
			||||||
| 
						 | 
					@ -108,6 +113,10 @@ public class YamlStorage implements NpcStorage {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (EntityProperty<?> property : npc.getAppliedProperties()) {
 | 
					            for (EntityProperty<?> property : npc.getAppliedProperties()) {
 | 
				
			||||||
                PropertySerializer<?> serializer = propertyRegistry.getSerializer(((EntityPropertyImpl<?>) property).getType());
 | 
					                PropertySerializer<?> serializer = propertyRegistry.getSerializer(((EntityPropertyImpl<?>) property).getType());
 | 
				
			||||||
 | 
					                if (serializer == null) {
 | 
				
			||||||
 | 
					                    Bukkit.getLogger().log(Level.WARNING, "Unknown serializer for property '" + property.getName() + "' for npc '" + entry.getId() + "'. skipping ...");
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                config.set("properties." + property.getName(), serializer.UNSAFE_serialize(npc.getProperty(property)));
 | 
					                config.set("properties." + property.getName(), serializer.UNSAFE_serialize(npc.getProperty(property)));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue