Merge branch 'modular-property-system' into 2.X
# Conflicts: # plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java # plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/CitizensImporter.java # plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java # plugin/src/main/java/lol/pyr/znpcsplus/storage/yaml/YamlStorage.java # plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java
This commit is contained in:
commit
f30bb1a6df
109 changed files with 2559 additions and 1866 deletions
|
@ -3,10 +3,6 @@ plugins {
|
||||||
id "maven-publish"
|
id "maven-publish"
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compileOnly "org.spigotmc:spigot-api:1.19.4-R0.1-SNAPSHOT"
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
publications {
|
publications {
|
||||||
mavenJava(MavenPublication) {
|
mavenJava(MavenPublication) {
|
||||||
|
|
|
@ -3,4 +3,5 @@ package lol.pyr.znpcsplus.api.entity;
|
||||||
public interface EntityProperty<T> {
|
public interface EntityProperty<T> {
|
||||||
T getDefaultValue();
|
T getDefaultValue();
|
||||||
String getName();
|
String getName();
|
||||||
|
boolean isPlayerModifiable();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package lol.pyr.znpcsplus.api.entity;
|
package lol.pyr.znpcsplus.api.entity;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public interface PropertyHolder {
|
public interface PropertyHolder {
|
||||||
<T> T getProperty(EntityProperty<T> key);
|
<T> T getProperty(EntityProperty<T> key);
|
||||||
boolean hasProperty(EntityProperty<?> key);
|
boolean hasProperty(EntityProperty<?> key);
|
||||||
<T> void setProperty(EntityProperty<T> key, T value);
|
<T> void setProperty(EntityProperty<T> key, T value);
|
||||||
|
Set<EntityProperty<?>> getAppliedProperties();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
package lol.pyr.znpcsplus.api.skin;
|
package lol.pyr.znpcsplus.api.skin;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
public interface SkinDescriptorFactory {
|
public interface SkinDescriptorFactory {
|
||||||
SkinDescriptor createMirrorDescriptor();
|
SkinDescriptor createMirrorDescriptor();
|
||||||
SkinDescriptor createRefreshingDescriptor(String playerName);
|
SkinDescriptor createRefreshingDescriptor(String playerName);
|
||||||
SkinDescriptor createStaticDescriptor(String playerName);
|
SkinDescriptor createStaticDescriptor(String playerName);
|
||||||
SkinDescriptor createStaticDescriptor(String texture, String signature);
|
SkinDescriptor createStaticDescriptor(String texture, String signature);
|
||||||
|
SkinDescriptor createUrlDescriptor(String url, String variant);
|
||||||
|
SkinDescriptor createUrlDescriptor(URL url, String variant);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package lol.pyr.znpcsplus.util;
|
||||||
|
|
||||||
|
public enum AxolotlVariant {
|
||||||
|
LUCY,
|
||||||
|
WILD,
|
||||||
|
GOLD,
|
||||||
|
CYAN,
|
||||||
|
BLUE
|
||||||
|
}
|
|
@ -1,25 +1,15 @@
|
||||||
package lol.pyr.znpcsplus.util;
|
package lol.pyr.znpcsplus.util;
|
||||||
|
|
||||||
public enum CatVariant {
|
public enum CatVariant {
|
||||||
TABBY(0),
|
TABBY,
|
||||||
BLACK(1),
|
BLACK,
|
||||||
RED(2),
|
RED,
|
||||||
SIAMESE(3),
|
SIAMESE,
|
||||||
BRITISH_SHORTHAIR(4),
|
BRITISH_SHORTHAIR,
|
||||||
CALICO(5),
|
CALICO,
|
||||||
PERSIAN(6),
|
PERSIAN,
|
||||||
RAGDOLL(7),
|
RAGDOLL,
|
||||||
WHITE(8),
|
WHITE,
|
||||||
JELLIE(9),
|
JELLIE,
|
||||||
ALL_BLACK(10);
|
ALL_BLACK
|
||||||
|
|
||||||
private final int id;
|
|
||||||
|
|
||||||
CatVariant(int id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
8
api/src/main/java/lol/pyr/znpcsplus/util/HorseArmor.java
Normal file
8
api/src/main/java/lol/pyr/znpcsplus/util/HorseArmor.java
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
package lol.pyr.znpcsplus.util;
|
||||||
|
|
||||||
|
public enum HorseArmor {
|
||||||
|
NONE,
|
||||||
|
IRON,
|
||||||
|
GOLD,
|
||||||
|
DIAMOND
|
||||||
|
}
|
11
api/src/main/java/lol/pyr/znpcsplus/util/HorseColor.java
Normal file
11
api/src/main/java/lol/pyr/znpcsplus/util/HorseColor.java
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package lol.pyr.znpcsplus.util;
|
||||||
|
|
||||||
|
public enum HorseColor {
|
||||||
|
WHITE,
|
||||||
|
CREAMY,
|
||||||
|
CHESTNUT,
|
||||||
|
BROWN,
|
||||||
|
BLACK,
|
||||||
|
GRAY,
|
||||||
|
DARK_BROWN
|
||||||
|
}
|
9
api/src/main/java/lol/pyr/znpcsplus/util/HorseStyle.java
Normal file
9
api/src/main/java/lol/pyr/znpcsplus/util/HorseStyle.java
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package lol.pyr.znpcsplus.util;
|
||||||
|
|
||||||
|
public enum HorseStyle {
|
||||||
|
NONE,
|
||||||
|
WHITE,
|
||||||
|
WHITEFIELD,
|
||||||
|
WHITE_DOTS,
|
||||||
|
BLACK_DOTS
|
||||||
|
}
|
9
api/src/main/java/lol/pyr/znpcsplus/util/HorseType.java
Normal file
9
api/src/main/java/lol/pyr/znpcsplus/util/HorseType.java
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package lol.pyr.znpcsplus.util;
|
||||||
|
|
||||||
|
public enum HorseType {
|
||||||
|
HORSE,
|
||||||
|
DONKEY,
|
||||||
|
MULE,
|
||||||
|
ZOMBIE,
|
||||||
|
SKELETON
|
||||||
|
}
|
|
@ -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,
|
||||||
|
}
|
|
@ -2,28 +2,28 @@ package lol.pyr.znpcsplus.util;
|
||||||
|
|
||||||
public enum VillagerProfession {
|
public enum VillagerProfession {
|
||||||
NONE(0),
|
NONE(0),
|
||||||
ARMORER(3),
|
ARMORER(1),
|
||||||
BUTCHER(4),
|
BUTCHER(2),
|
||||||
CARTOGRAPHER(1),
|
CARTOGRAPHER(3),
|
||||||
CLERIC(2),
|
CLERIC(4),
|
||||||
FARMER(0),
|
FARMER(5),
|
||||||
FISHERMAN(0),
|
FISHERMAN(6),
|
||||||
FLETCHER(0),
|
FLETCHER(7),
|
||||||
LEATHER_WORKER(4),
|
LEATHER_WORKER(8),
|
||||||
LIBRARIAN(1),
|
LIBRARIAN(9),
|
||||||
MASON(-1),
|
MASON(10),
|
||||||
NITWIT(5),
|
NITWIT(11),
|
||||||
SHEPHERD(0),
|
SHEPHERD(12),
|
||||||
TOOL_SMITH(3),
|
TOOL_SMITH(13),
|
||||||
WEAPON_SMITH(3);
|
WEAPON_SMITH(14);
|
||||||
|
|
||||||
private final int legacyId;
|
private final int id;
|
||||||
|
|
||||||
VillagerProfession(int legacyId) {
|
VillagerProfession(int id) {
|
||||||
this.legacyId = legacyId;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLegacyId() {
|
public int getId() {
|
||||||
return legacyId;
|
return id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,20 @@
|
||||||
package lol.pyr.znpcsplus.util;
|
package lol.pyr.znpcsplus.util;
|
||||||
|
|
||||||
public enum VillagerType {
|
public enum VillagerType {
|
||||||
DESERT,
|
DESERT(0),
|
||||||
JUNGLE,
|
JUNGLE(1),
|
||||||
PLAINS,
|
PLAINS(2),
|
||||||
SAVANNA,
|
SAVANNA(3),
|
||||||
SNOW,
|
SNOW(4),
|
||||||
SWAMP,
|
SWAMP(5),
|
||||||
TAIGA
|
TAIGA(6);
|
||||||
|
private final int id;
|
||||||
|
|
||||||
|
VillagerType(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,10 @@ subprojects {
|
||||||
toolchain.languageVersion.set(JavaLanguageVersion.of(8))
|
toolchain.languageVersion.set(JavaLanguageVersion.of(8))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly "org.spigotmc:spigot-api:1.8.8-R0.1-SNAPSHOT"
|
||||||
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven {
|
maven {
|
||||||
|
|
|
@ -16,8 +16,6 @@ processResources {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly "org.spigotmc:spigot-api:1.8.8-R0.1-SNAPSHOT"
|
|
||||||
|
|
||||||
compileOnly "me.clip:placeholderapi:2.11.3" // Placeholder support
|
compileOnly "me.clip:placeholderapi:2.11.3" // Placeholder support
|
||||||
implementation "com.google.code.gson:gson:2.10.1" // JSON parsing
|
implementation "com.google.code.gson:gson:2.10.1" // JSON parsing
|
||||||
implementation "org.bstats:bstats-bukkit:3.0.2" // Plugin stats
|
implementation "org.bstats:bstats-bukkit:3.0.2" // Plugin stats
|
||||||
|
|
|
@ -28,9 +28,11 @@ import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
|
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
|
||||||
import lol.pyr.znpcsplus.interaction.ActionRegistry;
|
import lol.pyr.znpcsplus.interaction.ActionRegistry;
|
||||||
import lol.pyr.znpcsplus.interaction.InteractionPacketListener;
|
import lol.pyr.znpcsplus.interaction.InteractionPacketListener;
|
||||||
import lol.pyr.znpcsplus.metadata.*;
|
|
||||||
import lol.pyr.znpcsplus.npc.*;
|
import lol.pyr.znpcsplus.npc.*;
|
||||||
import lol.pyr.znpcsplus.packets.*;
|
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||||
|
import lol.pyr.znpcsplus.packets.V1_17PacketFactory;
|
||||||
|
import lol.pyr.znpcsplus.packets.V1_19PacketFactory;
|
||||||
|
import lol.pyr.znpcsplus.packets.V1_8PacketFactory;
|
||||||
import lol.pyr.znpcsplus.parsers.*;
|
import lol.pyr.znpcsplus.parsers.*;
|
||||||
import lol.pyr.znpcsplus.scheduling.FoliaScheduler;
|
import lol.pyr.znpcsplus.scheduling.FoliaScheduler;
|
||||||
import lol.pyr.znpcsplus.scheduling.SpigotScheduler;
|
import lol.pyr.znpcsplus.scheduling.SpigotScheduler;
|
||||||
|
@ -126,8 +128,8 @@ public class ZNpcsPlus extends JavaPlugin {
|
||||||
ConfigManager configManager = new ConfigManager(getDataFolder());
|
ConfigManager configManager = new ConfigManager(getDataFolder());
|
||||||
MojangSkinCache skinCache = new MojangSkinCache(configManager);
|
MojangSkinCache skinCache = new MojangSkinCache(configManager);
|
||||||
EntityPropertyRegistryImpl propertyRegistry = new EntityPropertyRegistryImpl(skinCache);
|
EntityPropertyRegistryImpl propertyRegistry = new EntityPropertyRegistryImpl(skinCache);
|
||||||
MetadataFactory metadataFactory = setupMetadataFactory();
|
PacketFactory packetFactory = setupPacketFactory(scheduler, propertyRegistry);
|
||||||
PacketFactory packetFactory = setupPacketFactory(scheduler, metadataFactory, propertyRegistry);
|
propertyRegistry.registerTypes(packetFactory);
|
||||||
|
|
||||||
ActionRegistry actionRegistry = new ActionRegistry();
|
ActionRegistry actionRegistry = new ActionRegistry();
|
||||||
NpcTypeRegistryImpl typeRegistry = new NpcTypeRegistryImpl();
|
NpcTypeRegistryImpl typeRegistry = new NpcTypeRegistryImpl();
|
||||||
|
@ -140,7 +142,7 @@ public class ZNpcsPlus extends JavaPlugin {
|
||||||
|
|
||||||
DataImporterRegistry importerRegistry = new DataImporterRegistry(configManager, adventure,
|
DataImporterRegistry importerRegistry = new DataImporterRegistry(configManager, adventure,
|
||||||
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...");
|
||||||
|
|
||||||
|
@ -197,10 +199,9 @@ public class ZNpcsPlus extends JavaPlugin {
|
||||||
NpcEntryImpl entry = npcRegistry.create("debug_npc_" + i, world, type, new NpcLocation(i * 3, 200, 0, 0, 0));
|
NpcEntryImpl entry = npcRegistry.create("debug_npc_" + i, world, type, new NpcLocation(i * 3, 200, 0, 0, 0));
|
||||||
entry.setProcessed(true);
|
entry.setProcessed(true);
|
||||||
NpcImpl npc = entry.getNpc();
|
NpcImpl npc = entry.getNpc();
|
||||||
npc.getHologram().addLineComponent(Component.text("Hello, World!", TextColor.color(255, 0, 0)));
|
npc.getHologram().addTextLineComponent(Component.text("Hello, World!", TextColor.color(255, 0, 0)));
|
||||||
npc.getHologram().addLineComponent(Component.text("Hello, World!", TextColor.color(0, 255, 0)));
|
npc.getHologram().addTextLineComponent(Component.text("Hello, World!", TextColor.color(0, 255, 0)));
|
||||||
npc.getHologram().addLineComponent(Component.text("Hello, World!", TextColor.color(0, 0, 255)));
|
npc.getHologram().addTextLineComponent(Component.text("Hello, World!", TextColor.color(0, 0, 255)));
|
||||||
npc.setProperty(propertyRegistry.getByName("look", Boolean.class), true);
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,18 +211,15 @@ public class ZNpcsPlus extends JavaPlugin {
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
NpcApiProvider.unregister();
|
NpcApiProvider.unregister();
|
||||||
for (Runnable runnable : shutdownTasks) runnable.run();
|
for (Runnable runnable : shutdownTasks) runnable.run();
|
||||||
|
shutdownTasks.clear();
|
||||||
PacketEvents.getAPI().terminate();
|
PacketEvents.getAPI().terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private PacketFactory setupPacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory, EntityPropertyRegistryImpl propertyRegistry) {
|
private PacketFactory setupPacketFactory(TaskScheduler scheduler, EntityPropertyRegistryImpl propertyRegistry) {
|
||||||
HashMap<ServerVersion, LazyLoader<? extends PacketFactory>> versions = new HashMap<>();
|
HashMap<ServerVersion, LazyLoader<? extends PacketFactory>> versions = new HashMap<>();
|
||||||
versions.put(ServerVersion.V_1_8, LazyLoader.of(() -> new V1_8PacketFactory(scheduler, metadataFactory, packetEvents, propertyRegistry, textSerializer)));
|
versions.put(ServerVersion.V_1_8, LazyLoader.of(() -> new V1_8PacketFactory(scheduler, packetEvents, propertyRegistry, textSerializer)));
|
||||||
versions.put(ServerVersion.V_1_9, LazyLoader.of(() -> new V1_9PacketFactory(scheduler, metadataFactory, packetEvents, propertyRegistry, textSerializer)));
|
versions.put(ServerVersion.V_1_17, LazyLoader.of(() -> new V1_17PacketFactory(scheduler, packetEvents, propertyRegistry, textSerializer)));
|
||||||
versions.put(ServerVersion.V_1_10, LazyLoader.of(() -> new V1_10PacketFactory(scheduler, metadataFactory, packetEvents, propertyRegistry, textSerializer)));
|
versions.put(ServerVersion.V_1_19, LazyLoader.of(() -> new V1_19PacketFactory(scheduler, packetEvents, propertyRegistry, textSerializer)));
|
||||||
versions.put(ServerVersion.V_1_14, LazyLoader.of(() -> new V1_14PacketFactory(scheduler, metadataFactory, packetEvents, propertyRegistry, textSerializer)));
|
|
||||||
versions.put(ServerVersion.V_1_16, LazyLoader.of(() -> new V1_16PacketFactory(scheduler, metadataFactory, packetEvents, propertyRegistry, textSerializer)));
|
|
||||||
versions.put(ServerVersion.V_1_17, LazyLoader.of(() -> new V1_17PacketFactory(scheduler, metadataFactory, packetEvents, propertyRegistry, textSerializer)));
|
|
||||||
versions.put(ServerVersion.V_1_19, LazyLoader.of(() -> new V1_19PacketFactory(scheduler, metadataFactory, packetEvents, propertyRegistry, textSerializer)));
|
|
||||||
|
|
||||||
ServerVersion version = packetEvents.getServerManager().getVersion();
|
ServerVersion version = packetEvents.getServerManager().getVersion();
|
||||||
if (versions.containsKey(version)) return versions.get(version).get();
|
if (versions.containsKey(version)) return versions.get(version).get();
|
||||||
|
@ -233,31 +231,6 @@ public class ZNpcsPlus extends JavaPlugin {
|
||||||
throw new RuntimeException("Unsupported version!");
|
throw new RuntimeException("Unsupported version!");
|
||||||
}
|
}
|
||||||
|
|
||||||
private MetadataFactory setupMetadataFactory() {
|
|
||||||
HashMap<ServerVersion, LazyLoader<? extends MetadataFactory>> versions = new HashMap<>();
|
|
||||||
versions.put(ServerVersion.V_1_8, LazyLoader.of(V1_8MetadataFactory::new));
|
|
||||||
versions.put(ServerVersion.V_1_9, LazyLoader.of(V1_9MetadataFactory::new));
|
|
||||||
versions.put(ServerVersion.V_1_10, LazyLoader.of(V1_10MetadataFactory::new));
|
|
||||||
versions.put(ServerVersion.V_1_11, LazyLoader.of(V1_11MetadataFactory::new));
|
|
||||||
versions.put(ServerVersion.V_1_12, LazyLoader.of(V1_12MetadataFactory::new));
|
|
||||||
versions.put(ServerVersion.V_1_13, LazyLoader.of(V1_13MetadataFactory::new));
|
|
||||||
versions.put(ServerVersion.V_1_14, LazyLoader.of(V1_14MetadataFactory::new));
|
|
||||||
versions.put(ServerVersion.V_1_15, LazyLoader.of(V1_15MetadataFactory::new));
|
|
||||||
versions.put(ServerVersion.V_1_16, LazyLoader.of(V1_16MetadataFactory::new));
|
|
||||||
versions.put(ServerVersion.V_1_17, LazyLoader.of(V1_17MetadataFactory::new));
|
|
||||||
versions.put(ServerVersion.V_1_19, LazyLoader.of(V1_19MetadataFactory::new));
|
|
||||||
|
|
||||||
ServerVersion version = packetEvents.getServerManager().getVersion();
|
|
||||||
if (versions.containsKey(version)) return versions.get(version).get();
|
|
||||||
for (ServerVersion v : ServerVersion.reversedValues()) {
|
|
||||||
if (v.isNewerThan(version)) continue;
|
|
||||||
if (!versions.containsKey(v)) continue;
|
|
||||||
return versions.get(v).get();
|
|
||||||
}
|
|
||||||
throw new RuntimeException("Unsupported version!");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void registerCommands(NpcRegistryImpl npcRegistry, MojangSkinCache skinCache, BukkitAudiences adventure,
|
private void registerCommands(NpcRegistryImpl npcRegistry, MojangSkinCache skinCache, BukkitAudiences adventure,
|
||||||
ActionRegistry actionRegistry, NpcTypeRegistryImpl typeRegistry,
|
ActionRegistry actionRegistry, NpcTypeRegistryImpl typeRegistry,
|
||||||
EntityPropertyRegistryImpl propertyRegistry, DataImporterRegistry importerRegistry,
|
EntityPropertyRegistryImpl propertyRegistry, DataImporterRegistry importerRegistry,
|
||||||
|
@ -277,6 +250,7 @@ public class ZNpcsPlus extends JavaPlugin {
|
||||||
manager.registerParser(Color.class, new ColorParser(incorrectUsageMessage));
|
manager.registerParser(Color.class, new ColorParser(incorrectUsageMessage));
|
||||||
manager.registerParser(Vector3f.class, new Vector3fParser(incorrectUsageMessage));
|
manager.registerParser(Vector3f.class, new Vector3fParser(incorrectUsageMessage));
|
||||||
|
|
||||||
|
// TODO: Need to find a better way to do this
|
||||||
registerEnumParser(manager, NpcPose.class, incorrectUsageMessage);
|
registerEnumParser(manager, NpcPose.class, incorrectUsageMessage);
|
||||||
registerEnumParser(manager, DyeColor.class, incorrectUsageMessage);
|
registerEnumParser(manager, DyeColor.class, incorrectUsageMessage);
|
||||||
registerEnumParser(manager, CatVariant.class, incorrectUsageMessage);
|
registerEnumParser(manager, CatVariant.class, incorrectUsageMessage);
|
||||||
|
@ -288,6 +262,16 @@ public class ZNpcsPlus extends JavaPlugin {
|
||||||
registerEnumParser(manager, VillagerType.class, incorrectUsageMessage);
|
registerEnumParser(manager, VillagerType.class, incorrectUsageMessage);
|
||||||
registerEnumParser(manager, VillagerProfession.class, incorrectUsageMessage);
|
registerEnumParser(manager, VillagerProfession.class, incorrectUsageMessage);
|
||||||
registerEnumParser(manager, VillagerLevel.class, incorrectUsageMessage);
|
registerEnumParser(manager, VillagerLevel.class, incorrectUsageMessage);
|
||||||
|
registerEnumParser(manager, AxolotlVariant.class, incorrectUsageMessage);
|
||||||
|
registerEnumParser(manager, HorseType.class, incorrectUsageMessage);
|
||||||
|
registerEnumParser(manager, HorseStyle.class, incorrectUsageMessage);
|
||||||
|
registerEnumParser(manager, HorseColor.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("center", new CenterCommand(npcRegistry))
|
.addSubcommand("center", new CenterCommand(npcRegistry))
|
||||||
|
@ -309,11 +293,14 @@ public class ZNpcsPlus extends JavaPlugin {
|
||||||
.addSubcommand("reload", new LoadAllCommand(npcRegistry))
|
.addSubcommand("reload", new LoadAllCommand(npcRegistry))
|
||||||
.addSubcommand("import", new ImportCommand(npcRegistry, importerRegistry)))
|
.addSubcommand("import", new ImportCommand(npcRegistry, importerRegistry)))
|
||||||
.addSubcommand("holo", new MultiCommand(loadHelpMessage("holo"))
|
.addSubcommand("holo", new MultiCommand(loadHelpMessage("holo"))
|
||||||
.addSubcommand("add", new HoloAddCommand(npcRegistry, textSerializer))
|
.addSubcommand("add", new HoloAddCommand(npcRegistry))
|
||||||
|
.addSubcommand("additem", new HoloAddItemCommand(npcRegistry))
|
||||||
.addSubcommand("delete", new HoloDeleteCommand(npcRegistry))
|
.addSubcommand("delete", new HoloDeleteCommand(npcRegistry))
|
||||||
.addSubcommand("info", new HoloInfoCommand(npcRegistry))
|
.addSubcommand("info", new HoloInfoCommand(npcRegistry))
|
||||||
.addSubcommand("insert", new HoloInsertCommand(npcRegistry, textSerializer))
|
.addSubcommand("insert", new HoloInsertCommand(npcRegistry))
|
||||||
.addSubcommand("set", new HoloSetCommand(npcRegistry, textSerializer))
|
.addSubcommand("insertitem", new HoloInsertItemCommand(npcRegistry))
|
||||||
|
.addSubcommand("set", new HoloSetCommand(npcRegistry))
|
||||||
|
.addSubcommand("setitem", new HoloSetItemCommand(npcRegistry))
|
||||||
.addSubcommand("offset", new HoloOffsetCommand(npcRegistry))
|
.addSubcommand("offset", new HoloOffsetCommand(npcRegistry))
|
||||||
.addSubcommand("refreshdelay", new HoloRefreshDelayCommand(npcRegistry)))
|
.addSubcommand("refreshdelay", new HoloRefreshDelayCommand(npcRegistry)))
|
||||||
.addSubcommand("action", new MultiCommand(loadHelpMessage("action"))
|
.addSubcommand("action", new MultiCommand(loadHelpMessage("action"))
|
||||||
|
|
|
@ -17,6 +17,8 @@ import lol.pyr.znpcsplus.skin.descriptor.PrefetchedDescriptor;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -44,9 +46,7 @@ public class SkinCommand implements CommandHandler {
|
||||||
npc.setProperty(propertyRegistry.getByName("skin", SkinDescriptor.class), new MirrorDescriptor(skinCache));
|
npc.setProperty(propertyRegistry.getByName("skin", SkinDescriptor.class), new MirrorDescriptor(skinCache));
|
||||||
npc.respawn();
|
npc.respawn();
|
||||||
context.halt(Component.text("The NPC's skin will now mirror the player that it's being displayed to", NamedTextColor.GREEN));
|
context.halt(Component.text("The NPC's skin will now mirror the player that it's being displayed to", NamedTextColor.GREEN));
|
||||||
}
|
} else if (type.equalsIgnoreCase("static")) {
|
||||||
|
|
||||||
if (type.equalsIgnoreCase("static")) {
|
|
||||||
context.ensureArgsNotEmpty();
|
context.ensureArgsNotEmpty();
|
||||||
String name = context.dumpAllArgs();
|
String name = context.dumpAllArgs();
|
||||||
context.send(Component.text("Fetching skin \"" + name + "\"...", NamedTextColor.GREEN));
|
context.send(Component.text("Fetching skin \"" + name + "\"...", NamedTextColor.GREEN));
|
||||||
|
@ -57,26 +57,51 @@ public class SkinCommand implements CommandHandler {
|
||||||
}
|
}
|
||||||
npc.setProperty(propertyRegistry.getByName("skin", SkinDescriptor.class), skin);
|
npc.setProperty(propertyRegistry.getByName("skin", SkinDescriptor.class), skin);
|
||||||
npc.respawn();
|
npc.respawn();
|
||||||
context.send(Component.text("The NPC's skin has been set to \"" + name + "\""));
|
context.send(Component.text("The NPC's skin has been set to \"" + name + "\"", NamedTextColor.GREEN));
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
} else if (type.equalsIgnoreCase("dynamic")) {
|
||||||
|
|
||||||
if (type.equalsIgnoreCase("dynamic")) {
|
|
||||||
context.ensureArgsNotEmpty();
|
context.ensureArgsNotEmpty();
|
||||||
String name = context.dumpAllArgs();
|
String name = context.dumpAllArgs();
|
||||||
npc.setProperty(propertyRegistry.getByName("skin", SkinDescriptor.class), new FetchingDescriptor(skinCache, name));
|
npc.setProperty(propertyRegistry.getByName("skin", SkinDescriptor.class), new FetchingDescriptor(skinCache, name));
|
||||||
npc.respawn();
|
npc.respawn();
|
||||||
context.halt(Component.text("The NPC's skin will now be resolved per-player from \"" + name + "\""));
|
context.halt(Component.text("The NPC's skin will now be resolved per-player from \"" + name + "\""));
|
||||||
|
} else if (type.equalsIgnoreCase("url")) {
|
||||||
|
context.ensureArgsNotEmpty();
|
||||||
|
String variant = context.popString().toLowerCase();
|
||||||
|
if (!variant.equalsIgnoreCase("slim") && !variant.equalsIgnoreCase("classic")) {
|
||||||
|
context.send(Component.text("Invalid skin variant! Please use one of the following: slim, classic", NamedTextColor.RED));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
context.send(Component.text("Unknown skin type! Please use one of the following: mirror, static, dynamic"));
|
String urlString = context.dumpAllArgs();
|
||||||
|
try {
|
||||||
|
URL url = new URL(urlString);
|
||||||
|
context.send(Component.text("Fetching skin from url \"" + urlString + "\"...", NamedTextColor.GREEN));
|
||||||
|
PrefetchedDescriptor.fromUrl(skinCache, url , variant).thenAccept(skin -> {
|
||||||
|
if (skin.getSkin() == null) {
|
||||||
|
context.send(Component.text("Failed to fetch skin, are you sure the url is valid?", NamedTextColor.RED));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
npc.setProperty(propertyRegistry.getByName("skin", SkinDescriptor.class), skin);
|
||||||
|
npc.respawn();
|
||||||
|
context.send(Component.text("The NPC's skin has been set.", NamedTextColor.GREEN));
|
||||||
|
});
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
context.send(Component.text("Invalid url!", NamedTextColor.RED));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
context.send(Component.text("Unknown skin type! Please use one of the following: mirror, static, dynamic, url"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
||||||
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
|
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
|
||||||
if (context.argSize() == 2) return context.suggestLiteral("mirror", "static", "dynamic");
|
if (context.argSize() == 2) return context.suggestLiteral("mirror", "static", "dynamic", "url");
|
||||||
if (context.matchSuggestion("*", "static")) return context.suggestPlayers();
|
if (context.matchSuggestion("*", "static")) return context.suggestPlayers();
|
||||||
|
if (context.argSize() == 3 && context.matchSuggestion("*", "url")) {
|
||||||
|
return context.suggestLiteral("slim", "classic");
|
||||||
|
}
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,22 +4,20 @@ import lol.pyr.director.adventure.command.CommandContext;
|
||||||
import lol.pyr.director.adventure.command.CommandHandler;
|
import lol.pyr.director.adventure.command.CommandHandler;
|
||||||
import lol.pyr.director.common.command.CommandExecutionException;
|
import lol.pyr.director.common.command.CommandExecutionException;
|
||||||
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
||||||
|
import lol.pyr.znpcsplus.hologram.HologramItem;
|
||||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class HoloAddCommand implements CommandHandler {
|
public class HoloAddCommand implements CommandHandler {
|
||||||
private final NpcRegistryImpl registry;
|
private final NpcRegistryImpl registry;
|
||||||
private final LegacyComponentSerializer textSerializer;
|
|
||||||
|
|
||||||
public HoloAddCommand(NpcRegistryImpl registry, LegacyComponentSerializer textSerializer) {
|
public HoloAddCommand(NpcRegistryImpl registry) {
|
||||||
this.registry = registry;
|
this.registry = registry;
|
||||||
this.textSerializer = textSerializer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -27,7 +25,13 @@ public class HoloAddCommand implements CommandHandler {
|
||||||
context.setUsage(context.getLabel() + " holo add <id> <text>");
|
context.setUsage(context.getLabel() + " holo add <id> <text>");
|
||||||
HologramImpl hologram = context.parse(NpcEntryImpl.class).getNpc().getHologram();
|
HologramImpl hologram = context.parse(NpcEntryImpl.class).getNpc().getHologram();
|
||||||
context.ensureArgsNotEmpty();
|
context.ensureArgsNotEmpty();
|
||||||
hologram.addLineComponent(textSerializer.deserialize(context.dumpAllArgs()));
|
String in = context.dumpAllArgs();
|
||||||
|
if (in.toLowerCase().startsWith("item:")) {
|
||||||
|
if (!HologramItem.ensureValidItemInput(in.substring(5))) {
|
||||||
|
context.halt(Component.text("The item input is invalid!", NamedTextColor.RED));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hologram.addLine(in);
|
||||||
context.send(Component.text("NPC line added!", NamedTextColor.GREEN));
|
context.send(Component.text("NPC line added!", NamedTextColor.GREEN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package lol.pyr.znpcsplus.commands.hologram;
|
||||||
|
|
||||||
|
import lol.pyr.director.adventure.command.CommandContext;
|
||||||
|
import lol.pyr.director.adventure.command.CommandHandler;
|
||||||
|
import lol.pyr.director.common.command.CommandExecutionException;
|
||||||
|
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
||||||
|
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||||
|
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class HoloAddItemCommand implements CommandHandler {
|
||||||
|
private final NpcRegistryImpl registry;
|
||||||
|
|
||||||
|
public HoloAddItemCommand(NpcRegistryImpl registry) {
|
||||||
|
this.registry = registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
|
context.setUsage(context.getLabel() + " holo additem <id>");
|
||||||
|
Player player = context.ensureSenderIsPlayer();
|
||||||
|
org.bukkit.inventory.ItemStack itemStack = player.getInventory().getItemInHand();
|
||||||
|
if (itemStack == null) context.halt(Component.text("You must be holding an item!", NamedTextColor.RED));
|
||||||
|
HologramImpl hologram = context.parse(NpcEntryImpl.class).getNpc().getHologram();
|
||||||
|
hologram.addItemLineStack(itemStack);
|
||||||
|
context.send(Component.text("NPC item line added!", NamedTextColor.GREEN));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
||||||
|
if (context.argSize() == 1) return context.suggestCollection(registry.getModifiableIds());
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ import lol.pyr.director.adventure.command.CommandContext;
|
||||||
import lol.pyr.director.adventure.command.CommandHandler;
|
import lol.pyr.director.adventure.command.CommandHandler;
|
||||||
import lol.pyr.director.common.command.CommandExecutionException;
|
import lol.pyr.director.common.command.CommandExecutionException;
|
||||||
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
||||||
import lol.pyr.znpcsplus.hologram.HologramLine;
|
|
||||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
@ -26,7 +25,11 @@ public class HoloInfoCommand implements CommandHandler {
|
||||||
NpcEntryImpl entry = context.parse(NpcEntryImpl.class);
|
NpcEntryImpl entry = context.parse(NpcEntryImpl.class);
|
||||||
HologramImpl hologram = entry.getNpc().getHologram();
|
HologramImpl hologram = entry.getNpc().getHologram();
|
||||||
Component component = Component.text("NPC Hologram Info of ID " + entry.getId() + ":", NamedTextColor.GREEN).appendNewline();
|
Component component = Component.text("NPC Hologram Info of ID " + entry.getId() + ":", NamedTextColor.GREEN).appendNewline();
|
||||||
for (HologramLine line : hologram.getLines()) component = component.append(line.getText()).appendNewline();
|
for (int i = 0; i < hologram.getLines().size(); i++) {
|
||||||
|
component = component.append(Component.text(i + ") ", NamedTextColor.GREEN))
|
||||||
|
.append(Component.text(hologram.getLine(i), NamedTextColor.WHITE))
|
||||||
|
.appendNewline();
|
||||||
|
}
|
||||||
context.send(component);
|
context.send(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,11 @@ import lol.pyr.director.adventure.command.CommandContext;
|
||||||
import lol.pyr.director.adventure.command.CommandHandler;
|
import lol.pyr.director.adventure.command.CommandHandler;
|
||||||
import lol.pyr.director.common.command.CommandExecutionException;
|
import lol.pyr.director.common.command.CommandExecutionException;
|
||||||
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
||||||
|
import lol.pyr.znpcsplus.hologram.HologramItem;
|
||||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -16,11 +16,9 @@ import java.util.stream.Stream;
|
||||||
|
|
||||||
public class HoloInsertCommand implements CommandHandler {
|
public class HoloInsertCommand implements CommandHandler {
|
||||||
private final NpcRegistryImpl npcRegistry;
|
private final NpcRegistryImpl npcRegistry;
|
||||||
private final LegacyComponentSerializer componentSerializer;
|
|
||||||
|
|
||||||
public HoloInsertCommand(NpcRegistryImpl npcRegistry, LegacyComponentSerializer componentSerializer) {
|
public HoloInsertCommand(NpcRegistryImpl npcRegistry) {
|
||||||
this.npcRegistry = npcRegistry;
|
this.npcRegistry = npcRegistry;
|
||||||
this.componentSerializer = componentSerializer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -30,7 +28,13 @@ public class HoloInsertCommand implements CommandHandler {
|
||||||
int line = context.parse(Integer.class);
|
int line = context.parse(Integer.class);
|
||||||
if (line < 0 || line >= hologram.getLines().size()) context.halt(Component.text("Invalid line number!", NamedTextColor.RED));
|
if (line < 0 || line >= hologram.getLines().size()) context.halt(Component.text("Invalid line number!", NamedTextColor.RED));
|
||||||
context.ensureArgsNotEmpty();
|
context.ensureArgsNotEmpty();
|
||||||
hologram.insertLineComponent(line, componentSerializer.deserialize(context.dumpAllArgs()));
|
String in = context.dumpAllArgs();
|
||||||
|
if (in.toLowerCase().startsWith("item:")) {
|
||||||
|
if (!HologramItem.ensureValidItemInput(in.substring(5))) {
|
||||||
|
context.halt(Component.text("The item input is invalid!", NamedTextColor.RED));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hologram.insertLine(line, in);
|
||||||
context.send(Component.text("NPC line inserted!", NamedTextColor.GREEN));
|
context.send(Component.text("NPC line inserted!", NamedTextColor.GREEN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
package lol.pyr.znpcsplus.commands.hologram;
|
||||||
|
|
||||||
|
import lol.pyr.director.adventure.command.CommandContext;
|
||||||
|
import lol.pyr.director.adventure.command.CommandHandler;
|
||||||
|
import lol.pyr.director.common.command.CommandExecutionException;
|
||||||
|
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
||||||
|
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||||
|
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class HoloInsertItemCommand implements CommandHandler {
|
||||||
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
|
||||||
|
public HoloInsertItemCommand(NpcRegistryImpl npcRegistry) {
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
|
context.setUsage(context.getLabel() + " holo insertitem <id> <line>");
|
||||||
|
HologramImpl hologram = context.parse(NpcEntryImpl.class).getNpc().getHologram();
|
||||||
|
int line = context.parse(Integer.class);
|
||||||
|
if (line < 0 || line >= hologram.getLines().size()) context.halt(Component.text("Invalid line number!", NamedTextColor.RED));
|
||||||
|
Player player = context.ensureSenderIsPlayer();
|
||||||
|
org.bukkit.inventory.ItemStack itemStack = player.getInventory().getItemInHand();
|
||||||
|
if (itemStack == null) context.halt(Component.text("You must be holding an item!", NamedTextColor.RED));
|
||||||
|
hologram.insertItemLineStack(line, itemStack);
|
||||||
|
context.send(Component.text("NPC item line inserted!", NamedTextColor.GREEN));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
||||||
|
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
|
||||||
|
if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1)
|
||||||
|
.limit(context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram().getLines().size())
|
||||||
|
.map(String::valueOf));
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,6 @@ import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -16,11 +15,9 @@ import java.util.stream.Stream;
|
||||||
|
|
||||||
public class HoloSetCommand implements CommandHandler {
|
public class HoloSetCommand implements CommandHandler {
|
||||||
private final NpcRegistryImpl npcRegistry;
|
private final NpcRegistryImpl npcRegistry;
|
||||||
private final LegacyComponentSerializer componentSerializer;
|
|
||||||
|
|
||||||
public HoloSetCommand(NpcRegistryImpl npcRegistry, LegacyComponentSerializer componentSerializer) {
|
public HoloSetCommand(NpcRegistryImpl npcRegistry) {
|
||||||
this.npcRegistry = npcRegistry;
|
this.npcRegistry = npcRegistry;
|
||||||
this.componentSerializer = componentSerializer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -31,7 +28,7 @@ public class HoloSetCommand implements CommandHandler {
|
||||||
if (line < 0 || line >= hologram.getLines().size()) context.halt(Component.text("Invalid line number!", NamedTextColor.RED));
|
if (line < 0 || line >= hologram.getLines().size()) context.halt(Component.text("Invalid line number!", NamedTextColor.RED));
|
||||||
context.ensureArgsNotEmpty();
|
context.ensureArgsNotEmpty();
|
||||||
hologram.removeLine(line);
|
hologram.removeLine(line);
|
||||||
hologram.insertLineComponent(line, componentSerializer.deserialize(context.dumpAllArgs()));
|
hologram.insertLine(line, context.dumpAllArgs());
|
||||||
context.send(Component.text("NPC line set!", NamedTextColor.GREEN));
|
context.send(Component.text("NPC line set!", NamedTextColor.GREEN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,8 +39,7 @@ public class HoloSetCommand implements CommandHandler {
|
||||||
HologramImpl hologram = context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram();
|
HologramImpl hologram = context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram();
|
||||||
if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1)
|
if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1)
|
||||||
.limit(hologram.getLines().size()).map(String::valueOf));
|
.limit(hologram.getLines().size()).map(String::valueOf));
|
||||||
if (context.argSize() == 3) return context.suggestLiteral(componentSerializer.serialize(
|
if (context.argSize() == 3) return context.suggestLiteral(hologram.getLine(context.suggestionParse(1, Integer.class)));
|
||||||
hologram.getLineComponent(context.suggestionParse(1, Integer.class))));
|
|
||||||
}
|
}
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
package lol.pyr.znpcsplus.commands.hologram;
|
||||||
|
|
||||||
|
import lol.pyr.director.adventure.command.CommandContext;
|
||||||
|
import lol.pyr.director.adventure.command.CommandHandler;
|
||||||
|
import lol.pyr.director.common.command.CommandExecutionException;
|
||||||
|
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
||||||
|
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||||
|
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class HoloSetItemCommand implements CommandHandler {
|
||||||
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
|
||||||
|
public HoloSetItemCommand(NpcRegistryImpl npcRegistry) {
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
|
context.setUsage(context.getLabel() + " holo setitem <id> <line>");
|
||||||
|
HologramImpl hologram = context.parse(NpcEntryImpl.class).getNpc().getHologram();
|
||||||
|
int line = context.parse(Integer.class);
|
||||||
|
if (line < 0 || line >= hologram.getLines().size()) context.halt(Component.text("Invalid line number!", NamedTextColor.RED));
|
||||||
|
Player player = context.ensureSenderIsPlayer();
|
||||||
|
org.bukkit.inventory.ItemStack itemStack = player.getInventory().getItemInHand();
|
||||||
|
if (itemStack == null) context.halt(Component.text("You must be holding an item!", NamedTextColor.RED));
|
||||||
|
hologram.removeLine(line);
|
||||||
|
hologram.insertItemLineStack(line, itemStack);
|
||||||
|
context.send(Component.text("NPC item line set!", NamedTextColor.GREEN));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
||||||
|
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
|
||||||
|
if (context.argSize() >= 2) {
|
||||||
|
HologramImpl hologram = context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram();
|
||||||
|
if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1)
|
||||||
|
.limit(hologram.getLines().size()).map(String::valueOf));
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,7 +28,8 @@ public class PropertyRemoveCommand implements CommandHandler {
|
||||||
NpcImpl npc = entry.getNpc();
|
NpcImpl npc = entry.getNpc();
|
||||||
EntityPropertyImpl<?> property = context.parse(EntityPropertyImpl.class);
|
EntityPropertyImpl<?> property = context.parse(EntityPropertyImpl.class);
|
||||||
if (!npc.hasProperty(property)) context.halt(Component.text("This npc doesn't have the " + property.getName() + " property set", NamedTextColor.RED));
|
if (!npc.hasProperty(property)) context.halt(Component.text("This npc doesn't have the " + property.getName() + " property set", NamedTextColor.RED));
|
||||||
npc.removeProperty(property);
|
if (!property.isPlayerModifiable()) context.halt(Component.text("This property is not modifiable by players", NamedTextColor.RED));
|
||||||
|
npc.setProperty(property, null);
|
||||||
context.send(Component.text("Removed property " + property.getName() + " from NPC " + entry.getId(), NamedTextColor.GREEN));
|
context.send(Component.text("Removed property " + property.getName() + " from NPC " + entry.getId(), NamedTextColor.GREEN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ public class PropertyRemoveCommand implements CommandHandler {
|
||||||
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
||||||
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
|
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.getModifiableIds());
|
||||||
if (context.argSize() == 2) return context.suggestStream(context.suggestionParse(0, NpcEntryImpl.class)
|
if (context.argSize() == 2) return context.suggestStream(context.suggestionParse(0, NpcEntryImpl.class)
|
||||||
.getNpc().getAppliedProperties().stream().map(EntityProperty::getName));
|
.getNpc().getAppliedProperties().stream().filter(EntityProperty::isPlayerModifiable).map(EntityProperty::getName));
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
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;
|
||||||
|
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||||
import lol.pyr.director.adventure.command.CommandContext;
|
import lol.pyr.director.adventure.command.CommandContext;
|
||||||
import lol.pyr.director.adventure.command.CommandHandler;
|
import lol.pyr.director.adventure.command.CommandHandler;
|
||||||
import lol.pyr.director.common.command.CommandExecutionException;
|
import lol.pyr.director.common.command.CommandExecutionException;
|
||||||
|
@ -15,9 +18,9 @@ import lol.pyr.znpcsplus.util.*;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import org.bukkit.Color;
|
import org.bukkit.Color;
|
||||||
import org.bukkit.DyeColor;
|
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -42,12 +45,12 @@ public class PropertySetCommand implements CommandHandler {
|
||||||
Object value;
|
Object value;
|
||||||
String valueName;
|
String valueName;
|
||||||
if (type == ItemStack.class) {
|
if (type == ItemStack.class) {
|
||||||
ItemStack bukkitStack = context.ensureSenderIsPlayer().getInventory().getItemInHand();
|
org.bukkit.inventory.ItemStack bukkitStack = context.ensureSenderIsPlayer().getInventory().getItemInHand();
|
||||||
if (bukkitStack.getAmount() == 0) {
|
if (bukkitStack.getAmount() == 0) {
|
||||||
value = null;
|
value = null;
|
||||||
valueName = "EMPTY";
|
valueName = "EMPTY";
|
||||||
} else {
|
} else {
|
||||||
value = bukkitStack;
|
value = SpigotConversionUtil.fromBukkitItemStack(bukkitStack);
|
||||||
valueName = bukkitStack.toString();
|
valueName = bukkitStack.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -117,19 +138,16 @@ public class PropertySetCommand implements CommandHandler {
|
||||||
if (context.argSize() == 3) {
|
if (context.argSize() == 3) {
|
||||||
if (type == Boolean.class) return context.suggestLiteral("true", "false");
|
if (type == Boolean.class) return context.suggestLiteral("true", "false");
|
||||||
if (type == NamedTextColor.class) return context.suggestCollection(NamedTextColor.NAMES.keys());
|
if (type == NamedTextColor.class) return context.suggestCollection(NamedTextColor.NAMES.keys());
|
||||||
if (type == NpcPose.class) return context.suggestEnum(NpcPose.values());
|
|
||||||
if (type == Color.class) return context.suggestLiteral("0x0F00FF", "#FFFFFF");
|
if (type == Color.class) return context.suggestLiteral("0x0F00FF", "#FFFFFF");
|
||||||
if (type == DyeColor.class) return context.suggestEnum(DyeColor.values());
|
|
||||||
if (type == CatVariant.class) return context.suggestEnum(CatVariant.values());
|
|
||||||
if (type == CreeperState.class) return context.suggestEnum(CreeperState.values());
|
|
||||||
if (type == ParrotVariant.class) return context.suggestEnum(ParrotVariant.values());
|
|
||||||
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 context.suggestEnum(SpellType.values());
|
if (type == SpellType.class) return PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_13) ?
|
||||||
if (type == FoxVariant.class) return context.suggestEnum(FoxVariant.values());
|
context.suggestEnum(Arrays.stream(SpellType.values()).filter(spellType -> spellType.ordinal() <= 3).toArray(SpellType[]::new)) :
|
||||||
if (type == FrogVariant.class) return context.suggestEnum(FrogVariant.values());
|
context.suggestEnum(SpellType.values());
|
||||||
if (type == VillagerType.class) return context.suggestEnum(VillagerType.values());
|
|
||||||
if (type == VillagerProfession.class) return context.suggestEnum(VillagerProfession.values());
|
// Suggest enum values directly
|
||||||
if (type == VillagerLevel.class) return context.suggestEnum(VillagerLevel.values());
|
if (type.isEnum()) {
|
||||||
|
return context.suggestEnum((Enum<?>[]) type.getEnumConstants());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (context.argSize() == 4) {
|
else if (context.argSize() == 4) {
|
||||||
if (type == BlockState.class) {
|
if (type == BlockState.class) {
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package lol.pyr.znpcsplus.conversion;
|
package lol.pyr.znpcsplus.conversion;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.config.ConfigManager;
|
import lol.pyr.znpcsplus.config.ConfigManager;
|
||||||
|
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;
|
||||||
|
@ -23,14 +25,14 @@ public class DataImporterRegistry {
|
||||||
public DataImporterRegistry(ConfigManager configManager, BukkitAudiences adventure,
|
public DataImporterRegistry(ConfigManager configManager, BukkitAudiences adventure,
|
||||||
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, taskScheduler,
|
register("znpcs", LazyLoader.of(() -> new ZNpcImporter(configManager, adventure, 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, taskScheduler,
|
register("znpcsplus_legacy", LazyLoader.of(() -> new ZNpcImporter(configManager, adventure, 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, 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) {
|
||||||
|
|
|
@ -2,19 +2,28 @@ package lol.pyr.znpcsplus.conversion.citizens;
|
||||||
|
|
||||||
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.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.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;
|
||||||
import lol.pyr.znpcsplus.skin.cache.MojangSkinCache;
|
import lol.pyr.znpcsplus.skin.cache.MojangSkinCache;
|
||||||
|
import lol.pyr.znpcsplus.util.NpcLocation;
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
@SuppressWarnings("FieldCanBeLocal")
|
@SuppressWarnings("FieldCanBeLocal")
|
||||||
public class CitizensImporter implements DataImporter {
|
public class CitizensImporter implements DataImporter {
|
||||||
|
@ -27,11 +36,13 @@ public class CitizensImporter implements DataImporter {
|
||||||
private final EntityPropertyRegistryImpl propertyRegistry;
|
private final EntityPropertyRegistryImpl propertyRegistry;
|
||||||
private final MojangSkinCache skinCache;
|
private final MojangSkinCache skinCache;
|
||||||
private final File dataFile;
|
private final File dataFile;
|
||||||
|
private final CitizensTraitsRegistry traitsRegistry;
|
||||||
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
|
||||||
public CitizensImporter(ConfigManager configManager, BukkitAudiences adventure,
|
public CitizensImporter(ConfigManager configManager, BukkitAudiences adventure,
|
||||||
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.scheduler = taskScheduler;
|
this.scheduler = taskScheduler;
|
||||||
|
@ -41,14 +52,58 @@ public class CitizensImporter implements DataImporter {
|
||||||
this.propertyRegistry = propertyRegistry;
|
this.propertyRegistry = propertyRegistry;
|
||||||
this.skinCache = skinCache;
|
this.skinCache = skinCache;
|
||||||
this.dataFile = dataFile;
|
this.dataFile = dataFile;
|
||||||
|
this.traitsRegistry = new CitizensTraitsRegistry(typeRegistry, propertyRegistry, skinCache);
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<NpcEntryImpl> importData() {
|
public Collection<NpcEntryImpl> importData() {
|
||||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(dataFile);
|
YamlConfiguration config = YamlConfiguration.loadConfiguration(dataFile);
|
||||||
// TODO
|
ConfigurationSection npcsSection = config.getConfigurationSection("npc");
|
||||||
|
if (npcsSection == null) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
ArrayList<NpcEntryImpl> entries = new ArrayList<>();
|
||||||
|
npcsSection.getKeys(false).forEach(key -> {
|
||||||
|
ConfigurationSection npcSection = npcsSection.getConfigurationSection(key);
|
||||||
|
if (npcSection == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String name = npcSection.getString("name", "Citizens NPC");
|
||||||
|
UUID uuid;
|
||||||
|
try {
|
||||||
|
uuid = UUID.fromString(npcSection.getString("uuid"));
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
uuid = UUID.randomUUID();
|
||||||
|
}
|
||||||
|
String world = npcSection.getString("traits.location.world");
|
||||||
|
if (world == null) {
|
||||||
|
world = Bukkit.getWorlds().get(0).getName();
|
||||||
|
}
|
||||||
|
NpcImpl npc = new NpcImpl(uuid, propertyRegistry, configManager, packetFactory, textSerializer, world, typeRegistry.getByName("armor_stand"), new NpcLocation(0, 0, 0, 0, 0));
|
||||||
|
npc.getType().applyDefaultProperties(npc);
|
||||||
|
|
||||||
|
npc.getHologram().addTextLineComponent(textSerializer.deserialize(name));
|
||||||
|
ConfigurationSection traits = npcSection.getConfigurationSection("traits");
|
||||||
|
if (traits != null) {
|
||||||
|
for (String traitName : traits.getKeys(false)) {
|
||||||
|
Object trait = traits.get(traitName);
|
||||||
|
CitizensTrait citizensTrait = traitsRegistry.getByName(traitName);
|
||||||
|
if (citizensTrait != null) {
|
||||||
|
npc = citizensTrait.apply(npc, trait);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String id = key.toLowerCase();
|
||||||
|
while (npcRegistry.getById(id) != null) {
|
||||||
|
id += "_"; // TODO: make a backup of the old npc instead
|
||||||
|
}
|
||||||
|
NpcEntryImpl entry = new NpcEntryImpl(id, npc);
|
||||||
|
entry.enableEverything();
|
||||||
|
entries.add(entry);
|
||||||
|
});
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package lol.pyr.znpcsplus.conversion.citizens.model;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public abstract class CitizensTrait {
|
||||||
|
private final String identifier;
|
||||||
|
|
||||||
|
public CitizensTrait(String identifier) {
|
||||||
|
this.identifier = identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIdentifier() {
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract @NotNull NpcImpl apply(NpcImpl npc, Object value);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package lol.pyr.znpcsplus.conversion.citizens.model;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry;
|
||||||
|
import lol.pyr.znpcsplus.api.npc.NpcTypeRegistry;
|
||||||
|
import lol.pyr.znpcsplus.conversion.citizens.model.traits.*;
|
||||||
|
import lol.pyr.znpcsplus.skin.cache.MojangSkinCache;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class CitizensTraitsRegistry {
|
||||||
|
private final HashMap<String, CitizensTrait> traitMap = new HashMap<>();
|
||||||
|
|
||||||
|
public CitizensTraitsRegistry(NpcTypeRegistry typeRegistry, EntityPropertyRegistry propertyRegistry, MojangSkinCache skinCache) {
|
||||||
|
register(new LocationTrait());
|
||||||
|
register(new TypeTrait(typeRegistry));
|
||||||
|
register(new ProfessionTrait(propertyRegistry));
|
||||||
|
register(new VillagerTrait(propertyRegistry));
|
||||||
|
register(new SkinTrait(propertyRegistry));
|
||||||
|
register(new MirrorTrait(propertyRegistry, skinCache));
|
||||||
|
register(new SkinLayersTrait(propertyRegistry));
|
||||||
|
register(new LookTrait(propertyRegistry));
|
||||||
|
}
|
||||||
|
|
||||||
|
public CitizensTrait getByName(String name) {
|
||||||
|
return traitMap.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register(CitizensTrait trait) {
|
||||||
|
traitMap.put(trait.getIdentifier(), trait);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package lol.pyr.znpcsplus.conversion.citizens.model;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public abstract class SectionCitizensTrait extends CitizensTrait {
|
||||||
|
public SectionCitizensTrait(String identifier) {
|
||||||
|
super(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull NpcImpl apply(NpcImpl npc, Object value) {
|
||||||
|
if (!(value instanceof ConfigurationSection)) return npc;
|
||||||
|
return apply(npc, (ConfigurationSection) value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract @NotNull NpcImpl apply(NpcImpl npc, ConfigurationSection section);
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package lol.pyr.znpcsplus.conversion.citizens.model;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public abstract class StringCitizensTrait extends CitizensTrait {
|
||||||
|
public StringCitizensTrait(String identifier) {
|
||||||
|
super(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull NpcImpl apply(NpcImpl npc, Object value) {
|
||||||
|
if (!(value instanceof String)) return npc;
|
||||||
|
return apply(npc, (String) value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract @NotNull NpcImpl apply(NpcImpl npc, String string);
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package lol.pyr.znpcsplus.conversion.citizens.model.traits;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.conversion.citizens.model.SectionCitizensTrait;
|
||||||
|
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||||
|
import lol.pyr.znpcsplus.util.NpcLocation;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class LocationTrait extends SectionCitizensTrait {
|
||||||
|
public LocationTrait() {
|
||||||
|
super("location");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull NpcImpl apply(NpcImpl npc, ConfigurationSection section) {
|
||||||
|
double x = Double.parseDouble(section.getString("x"));
|
||||||
|
double y = Double.parseDouble(section.getString("y"));
|
||||||
|
double z = Double.parseDouble(section.getString("z"));
|
||||||
|
float yaw = Float.parseFloat(section.getString("yaw"));
|
||||||
|
float pitch = Float.parseFloat(section.getString("pitch"));
|
||||||
|
NpcLocation location = new NpcLocation(x, y, z, yaw, pitch);
|
||||||
|
npc.setLocation(location);
|
||||||
|
return npc;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package lol.pyr.znpcsplus.conversion.citizens.model.traits;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry;
|
||||||
|
import lol.pyr.znpcsplus.conversion.citizens.model.SectionCitizensTrait;
|
||||||
|
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class LookTrait extends SectionCitizensTrait {
|
||||||
|
private final EntityPropertyRegistry registry;
|
||||||
|
|
||||||
|
public LookTrait(EntityPropertyRegistry registry) {
|
||||||
|
super("lookclose");
|
||||||
|
this.registry = registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull NpcImpl apply(NpcImpl npc, ConfigurationSection section) {
|
||||||
|
if (section.getBoolean("enabled")) npc.setProperty(registry.getByName("look", Boolean.class), true);
|
||||||
|
return npc;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package lol.pyr.znpcsplus.conversion.citizens.model.traits;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry;
|
||||||
|
import lol.pyr.znpcsplus.api.skin.SkinDescriptor;
|
||||||
|
import lol.pyr.znpcsplus.conversion.citizens.model.SectionCitizensTrait;
|
||||||
|
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||||
|
import lol.pyr.znpcsplus.skin.cache.MojangSkinCache;
|
||||||
|
import lol.pyr.znpcsplus.skin.descriptor.MirrorDescriptor;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class MirrorTrait extends SectionCitizensTrait {
|
||||||
|
private final EntityPropertyRegistry registry;
|
||||||
|
private final MojangSkinCache skinCache;
|
||||||
|
|
||||||
|
public MirrorTrait(EntityPropertyRegistry registry, MojangSkinCache skinCache) {
|
||||||
|
super("mirrortrait");
|
||||||
|
this.registry = registry;
|
||||||
|
this.skinCache = skinCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull NpcImpl apply(NpcImpl npc, ConfigurationSection section) {
|
||||||
|
if (section.getBoolean("enabled")) npc.setProperty(registry.getByName("skin", SkinDescriptor.class), new MirrorDescriptor(skinCache));
|
||||||
|
return npc;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package lol.pyr.znpcsplus.conversion.citizens.model.traits;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry;
|
||||||
|
import lol.pyr.znpcsplus.conversion.citizens.model.StringCitizensTrait;
|
||||||
|
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||||
|
import lol.pyr.znpcsplus.util.VillagerProfession;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class ProfessionTrait extends StringCitizensTrait {
|
||||||
|
private final EntityPropertyRegistry registry;
|
||||||
|
|
||||||
|
public ProfessionTrait(EntityPropertyRegistry registry) {
|
||||||
|
super("profession");
|
||||||
|
this.registry = registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull NpcImpl apply(NpcImpl npc, String string) {
|
||||||
|
VillagerProfession profession;
|
||||||
|
try {
|
||||||
|
profession = VillagerProfession.valueOf(string.toUpperCase());
|
||||||
|
} catch (IllegalArgumentException ignored) {
|
||||||
|
profession = VillagerProfession.NONE;
|
||||||
|
}
|
||||||
|
npc.setProperty(registry.getByName("villager_profession", VillagerProfession.class), profession);
|
||||||
|
return npc;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package lol.pyr.znpcsplus.conversion.citizens.model.traits;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry;
|
||||||
|
import lol.pyr.znpcsplus.conversion.citizens.model.SectionCitizensTrait;
|
||||||
|
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SkinLayersTrait extends SectionCitizensTrait {
|
||||||
|
private final EntityPropertyRegistry registry;
|
||||||
|
private final Map<String, String> skinLayers;
|
||||||
|
|
||||||
|
public SkinLayersTrait(EntityPropertyRegistry registry) {
|
||||||
|
super("skinlayers");
|
||||||
|
this.registry = registry;
|
||||||
|
this.skinLayers = new HashMap<>();
|
||||||
|
this.skinLayers.put("cape", "skin_cape");
|
||||||
|
this.skinLayers.put("hat", "skin_hat");
|
||||||
|
this.skinLayers.put("jacket", "skin_jacket");
|
||||||
|
this.skinLayers.put("left_sleeve", "skin_left_sleeve");
|
||||||
|
this.skinLayers.put("left_pants", "skin_left_leg");
|
||||||
|
this.skinLayers.put("right_sleeve", "skin_right_sleeve");
|
||||||
|
this.skinLayers.put("right_pants", "skin_right_leg");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull NpcImpl apply(NpcImpl npc, ConfigurationSection section) {
|
||||||
|
for (Map.Entry<String, String> entry : this.skinLayers.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
String property = entry.getValue();
|
||||||
|
if (section.contains(key)) npc.setProperty(registry.getByName(property, Boolean.class), section.getBoolean(key));
|
||||||
|
}
|
||||||
|
return npc;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package lol.pyr.znpcsplus.conversion.citizens.model.traits;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry;
|
||||||
|
import lol.pyr.znpcsplus.api.skin.SkinDescriptor;
|
||||||
|
import lol.pyr.znpcsplus.conversion.citizens.model.SectionCitizensTrait;
|
||||||
|
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||||
|
import lol.pyr.znpcsplus.skin.Skin;
|
||||||
|
import lol.pyr.znpcsplus.skin.descriptor.PrefetchedDescriptor;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class SkinTrait extends SectionCitizensTrait {
|
||||||
|
private final EntityPropertyRegistry registry;
|
||||||
|
|
||||||
|
public SkinTrait(EntityPropertyRegistry registry) {
|
||||||
|
super("skintrait");
|
||||||
|
this.registry = registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull NpcImpl apply(NpcImpl npc, ConfigurationSection section) {
|
||||||
|
String texture = section.getString("textureRaw");
|
||||||
|
String signature = section.getString("signature");
|
||||||
|
if (texture != null && signature != null) npc.setProperty(registry.getByName("skin", SkinDescriptor.class), new PrefetchedDescriptor(new Skin(texture, signature)));
|
||||||
|
return npc;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package lol.pyr.znpcsplus.conversion.citizens.model.traits;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.api.npc.NpcTypeRegistry;
|
||||||
|
import lol.pyr.znpcsplus.conversion.citizens.model.StringCitizensTrait;
|
||||||
|
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||||
|
import lol.pyr.znpcsplus.npc.NpcTypeImpl;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class TypeTrait extends StringCitizensTrait {
|
||||||
|
private final NpcTypeRegistry registry;
|
||||||
|
|
||||||
|
public TypeTrait(NpcTypeRegistry registry) {
|
||||||
|
super("type");
|
||||||
|
this.registry = registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull NpcImpl apply(NpcImpl npc, String string) {
|
||||||
|
NpcTypeImpl type = warpNpcType(string);
|
||||||
|
if (type == null) return npc;
|
||||||
|
npc.setType(type);
|
||||||
|
return npc;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NpcTypeImpl warpNpcType(String name) {
|
||||||
|
name = name.toLowerCase();
|
||||||
|
// if (name.equals("player")) name = "human";
|
||||||
|
// else if (name.equals("zombievillager")) name = "zombie_villager";
|
||||||
|
return (NpcTypeImpl) registry.getByName(name);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package lol.pyr.znpcsplus.conversion.citizens.model.traits;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry;
|
||||||
|
import lol.pyr.znpcsplus.conversion.citizens.model.SectionCitizensTrait;
|
||||||
|
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||||
|
import lol.pyr.znpcsplus.util.VillagerLevel;
|
||||||
|
import lol.pyr.znpcsplus.util.VillagerType;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class VillagerTrait extends SectionCitizensTrait {
|
||||||
|
private final EntityPropertyRegistry registry;
|
||||||
|
|
||||||
|
public VillagerTrait(EntityPropertyRegistry registry) {
|
||||||
|
super("villagertrait");
|
||||||
|
this.registry = registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull NpcImpl apply(NpcImpl npc, ConfigurationSection section) {
|
||||||
|
int level = section.getInt("level");
|
||||||
|
String type = section.getString("type", "plains");
|
||||||
|
VillagerLevel villagerLevel;
|
||||||
|
try {
|
||||||
|
villagerLevel = VillagerLevel.values()[level];
|
||||||
|
} catch (ArrayIndexOutOfBoundsException ignored) {
|
||||||
|
villagerLevel = VillagerLevel.STONE;
|
||||||
|
}
|
||||||
|
VillagerType villagerType;
|
||||||
|
try {
|
||||||
|
villagerType = VillagerType.valueOf(type.toUpperCase());
|
||||||
|
} catch (IllegalArgumentException ignored) {
|
||||||
|
villagerType = VillagerType.PLAINS;
|
||||||
|
}
|
||||||
|
npc.setProperty(registry.getByName("villager_level", VillagerLevel.class), villagerLevel);
|
||||||
|
npc.setProperty(registry.getByName("villager_type", VillagerType.class), villagerType);
|
||||||
|
return npc;
|
||||||
|
}
|
||||||
|
}
|
|
@ -98,13 +98,14 @@ public class ZNpcImporter implements DataImporter {
|
||||||
ZNpcsLocation oldLoc = model.getLocation();
|
ZNpcsLocation oldLoc = model.getLocation();
|
||||||
NpcLocation location = new NpcLocation(oldLoc.getX(), oldLoc.getY(), oldLoc.getZ(), oldLoc.getYaw(), oldLoc.getPitch());
|
NpcLocation location = new NpcLocation(oldLoc.getX(), oldLoc.getY(), oldLoc.getZ(), oldLoc.getYaw(), oldLoc.getPitch());
|
||||||
UUID uuid = model.getUuid() == null ? UUID.randomUUID() : model.getUuid();
|
UUID uuid = model.getUuid() == null ? UUID.randomUUID() : model.getUuid();
|
||||||
NpcImpl npc = new NpcImpl(uuid, configManager, packetFactory, textSerializer, oldLoc.getWorld(), typeRegistry.getByName(type), location);
|
NpcImpl npc = new NpcImpl(uuid, propertyRegistry, configManager, packetFactory, textSerializer, oldLoc.getWorld(), typeRegistry.getByName(type), location);
|
||||||
|
npc.getType().applyDefaultProperties(npc);
|
||||||
|
|
||||||
HologramImpl hologram = npc.getHologram();
|
HologramImpl hologram = npc.getHologram();
|
||||||
hologram.setOffset(model.getHologramHeight());
|
hologram.setOffset(model.getHologramHeight());
|
||||||
for (String raw : model.getHologramLines()) {
|
for (String raw : model.getHologramLines()) {
|
||||||
Component line = textSerializer.deserialize(raw);
|
Component line = textSerializer.deserialize(raw);
|
||||||
hologram.addLineComponent(line);
|
hologram.addTextLineComponent(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ZNpcsAction action : model.getClickActions()) {
|
for (ZNpcsAction action : model.getClickActions()) {
|
||||||
|
|
|
@ -1,19 +1,23 @@
|
||||||
package lol.pyr.znpcsplus.entity;
|
package lol.pyr.znpcsplus.entity;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataType;
|
||||||
import lol.pyr.znpcsplus.api.entity.EntityProperty;
|
import lol.pyr.znpcsplus.api.entity.EntityProperty;
|
||||||
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public class EntityPropertyImpl<T> implements EntityProperty<T> {
|
import java.util.*;
|
||||||
|
|
||||||
|
public abstract class EntityPropertyImpl<T> implements EntityProperty<T> {
|
||||||
private final String name;
|
private final String name;
|
||||||
private final T defaultValue;
|
private final T defaultValue;
|
||||||
private final Class<T> clazz;
|
private final Class<T> clazz;
|
||||||
private final PropertySerializer<T> serializer;
|
private final Set<EntityPropertyImpl<?>> dependencies = new HashSet<>();
|
||||||
|
private boolean playerModifiable = true;
|
||||||
|
|
||||||
protected EntityPropertyImpl(String name, T defaultValue, Class<T> clazz, PropertySerializer<T> serializer) {
|
protected EntityPropertyImpl(String name, T defaultValue, Class<T> clazz) {
|
||||||
this.name = name.toLowerCase();
|
this.name = name.toLowerCase();
|
||||||
this.defaultValue = defaultValue;
|
this.defaultValue = defaultValue;
|
||||||
this.clazz = clazz;
|
this.clazz = clazz;
|
||||||
this.serializer = serializer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -21,24 +25,38 @@ public class EntityPropertyImpl<T> implements EntityProperty<T> {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String serialize(PropertyHolder holder) {
|
|
||||||
return serialize(holder.getProperty(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String serialize(T value) {
|
|
||||||
return serializer.serialize(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public T deserialize(String str) {
|
|
||||||
return serializer.deserialize(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T getDefaultValue() {
|
public T getDefaultValue() {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPlayerModifiable() {
|
||||||
|
return playerModifiable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlayerModifiable(boolean playerModifiable) {
|
||||||
|
this.playerModifiable = playerModifiable;
|
||||||
|
}
|
||||||
|
|
||||||
public Class<T> getType() {
|
public Class<T> getType() {
|
||||||
return clazz;
|
return clazz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addDependency(EntityPropertyImpl<?> property) {
|
||||||
|
dependencies.add(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static <V> EntityData newEntityData(int index, EntityDataType<V> type, V value) {
|
||||||
|
return new EntityData(index, type, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EntityData> applyStandalone(Player player, PacketEntity packetEntity, boolean isSpawned) {
|
||||||
|
Map<Integer, EntityData> map = new HashMap<>();
|
||||||
|
apply(player, packetEntity, isSpawned, map);
|
||||||
|
for (EntityPropertyImpl<?> property : dependencies) property.apply(player, packetEntity, isSpawned, map);
|
||||||
|
return new ArrayList<>(map.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties);
|
||||||
}
|
}
|
|
@ -1,23 +1,43 @@
|
||||||
package lol.pyr.znpcsplus.entity;
|
package lol.pyr.znpcsplus.entity;
|
||||||
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
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.EntityProperty;
|
||||||
import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry;
|
import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry;
|
||||||
import lol.pyr.znpcsplus.api.skin.SkinDescriptor;
|
import lol.pyr.znpcsplus.api.skin.SkinDescriptor;
|
||||||
|
import lol.pyr.znpcsplus.entity.properties.*;
|
||||||
|
import lol.pyr.znpcsplus.entity.properties.villager.VillagerLevelProperty;
|
||||||
|
import lol.pyr.znpcsplus.entity.properties.villager.VillagerProfessionProperty;
|
||||||
|
import lol.pyr.znpcsplus.entity.properties.villager.VillagerTypeProperty;
|
||||||
import lol.pyr.znpcsplus.entity.serializers.*;
|
import lol.pyr.znpcsplus.entity.serializers.*;
|
||||||
|
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||||
import lol.pyr.znpcsplus.skin.cache.MojangSkinCache;
|
import lol.pyr.znpcsplus.skin.cache.MojangSkinCache;
|
||||||
import lol.pyr.znpcsplus.util.*;
|
import lol.pyr.znpcsplus.util.*;
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import org.bukkit.Color;
|
import org.bukkit.Color;
|
||||||
import org.bukkit.DyeColor;
|
import org.bukkit.DyeColor;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1.8 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=7415">...</a>
|
||||||
|
* 1.9 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=7968">...</a>
|
||||||
|
* 1.10 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=8241">...</a>
|
||||||
|
* 1.11 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=8534">...</a>
|
||||||
|
* 1.12 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=14048">...</a>
|
||||||
|
* 1.13 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=14800">...</a>
|
||||||
|
* 1.14 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=15240">...</a>
|
||||||
|
* 1.15 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=15991">...</a>
|
||||||
|
* 1.16 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=16539">...</a>
|
||||||
|
* 1.17 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=17521">...</a>
|
||||||
|
* 1.18-1.19 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=18191">...</a>
|
||||||
|
* 1.20 <a href="https://wiki.vg/index.php?title=Entity_metadata">...</a>
|
||||||
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
|
public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
|
||||||
private final Map<Class<?>, PropertySerializer<?>> serializerMap = new HashMap<>();
|
private final Map<Class<?>, PropertySerializer<?>> serializerMap = new HashMap<>();
|
||||||
|
@ -32,6 +52,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);
|
||||||
|
@ -44,140 +65,41 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
|
||||||
registerEnumSerializer(VillagerType.class);
|
registerEnumSerializer(VillagerType.class);
|
||||||
registerEnumSerializer(VillagerProfession.class);
|
registerEnumSerializer(VillagerProfession.class);
|
||||||
registerEnumSerializer(VillagerLevel.class);
|
registerEnumSerializer(VillagerLevel.class);
|
||||||
|
registerEnumSerializer(AxolotlVariant.class);
|
||||||
|
registerEnumSerializer(HorseType.class);
|
||||||
|
registerEnumSerializer(HorseColor.class);
|
||||||
|
registerEnumSerializer(HorseStyle.class);
|
||||||
|
registerEnumSerializer(HorseArmor.class);
|
||||||
|
registerEnumSerializer(LlamaVariant.class);
|
||||||
|
registerEnumSerializer(MooshroomVariant.class);
|
||||||
|
registerEnumSerializer(OcelotType.class);
|
||||||
|
registerEnumSerializer(PandaGene.class);
|
||||||
|
registerEnumSerializer(PuffState.class);
|
||||||
|
|
||||||
registerType("glow", NamedTextColor.class);
|
/*
|
||||||
registerType("fire", false);
|
|
||||||
registerType("invisible", false);
|
|
||||||
registerType("silent", false);
|
|
||||||
registerType("skin", SkinDescriptor.class);
|
|
||||||
registerType("name", Component.class);
|
|
||||||
registerType("look", false);
|
|
||||||
registerType("dinnerbone", false);
|
|
||||||
|
|
||||||
registerType("helmet", ItemStack.class);
|
|
||||||
registerType("chestplate", ItemStack.class);
|
|
||||||
registerType("leggings", ItemStack.class);
|
|
||||||
registerType("boots", ItemStack.class);
|
|
||||||
registerType("hand", ItemStack.class);
|
|
||||||
registerType("offhand", ItemStack.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
|
||||||
registerType("potion_color", Color.BLACK);
|
|
||||||
registerType("potion_ambient", false);
|
|
||||||
registerType("shaking", false);
|
|
||||||
registerType("baby", false); // TODO
|
|
||||||
registerType("pose", NpcPose.STANDING);
|
|
||||||
|
|
||||||
// Player
|
|
||||||
registerType("skin_cape", true);
|
|
||||||
registerType("skin_jacket", true);
|
|
||||||
registerType("skin_left_sleeve", true);
|
|
||||||
registerType("skin_right_sleeve", true);
|
|
||||||
registerType("skin_left_leg", true);
|
|
||||||
registerType("skin_right_leg", true);
|
|
||||||
registerType("skin_hat", true);
|
|
||||||
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
|
||||||
|
|
||||||
// Armor Stand
|
|
||||||
registerType("small", false);
|
|
||||||
registerType("arms", false);
|
|
||||||
registerType("base_plate", true);
|
|
||||||
|
|
||||||
registerType("head_rotation", Vector3f.zero());
|
|
||||||
registerType("body_rotation", Vector3f.zero());
|
|
||||||
registerType("left_arm_rotation", new Vector3f(-10, 0, -10));
|
|
||||||
registerType("right_arm_rotation", new Vector3f(-15, 0, 10));
|
|
||||||
registerType("left_leg_rotation", new Vector3f(-1 , 0, -1));
|
|
||||||
registerType("right_leg_rotation", new Vector3f(1, 0, 1));
|
|
||||||
|
|
||||||
// Axolotl
|
|
||||||
registerType("axolotl_variant", 0);
|
|
||||||
registerType("playing_dead", false); // TODO fix disabling
|
|
||||||
|
|
||||||
// Bat
|
|
||||||
registerType("hanging", false);
|
|
||||||
|
|
||||||
// Bee
|
|
||||||
registerType("angry", false);
|
|
||||||
registerType("has_nectar", false);
|
|
||||||
|
|
||||||
// Blaze
|
|
||||||
registerType("blaze_on_fire", false);
|
|
||||||
|
|
||||||
// Cat
|
|
||||||
registerType("cat_variant", CatVariant.BLACK);
|
|
||||||
registerType("cat_lying", false);
|
|
||||||
registerType("cat_collar_color", DyeColor.RED);
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// Fox
|
|
||||||
registerType("fox_variant", FoxVariant.RED);
|
|
||||||
registerType("fox_sitting", false);
|
|
||||||
registerType("fox_crouching", false);
|
|
||||||
registerType("fox_sleeping", false);
|
|
||||||
registerType("fox_faceplanted", false);
|
|
||||||
|
|
||||||
// Frog
|
|
||||||
registerType("frog_variant", FrogVariant.TEMPERATE);
|
|
||||||
|
|
||||||
// Ghast
|
|
||||||
registerType("attacking", false);
|
|
||||||
|
|
||||||
// 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
|
||||||
|
|
||||||
// Piglin / Hoglin
|
|
||||||
registerType("immune_to_zombification", true);
|
|
||||||
|
|
||||||
// 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
|
||||||
|
|
||||||
// Horse
|
|
||||||
registerType("horse_style", 0); // TODO: Figure this out
|
|
||||||
registerType("horse_chest", false); // TODO
|
|
||||||
registerType("horse_saddle", false); // TODO
|
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -190,14 +112,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
|
|
||||||
registerType("villager_type", VillagerType.PLAINS);
|
|
||||||
registerType("villager_profession", VillagerProfession.NONE);
|
|
||||||
registerType("villager_level", VillagerLevel.STONE);
|
|
||||||
|
|
||||||
// Show Golem
|
// Show Golem
|
||||||
registerType("pumpkin", true); // TODO
|
registerType("pumpkin", true); // TODO
|
||||||
|
|
||||||
|
@ -206,25 +120,391 @@ 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
|
|
||||||
|
|
||||||
// Goat
|
|
||||||
registerType("has_left_horn", true);
|
|
||||||
registerType("has_right_horn", true);
|
|
||||||
|
|
||||||
// Vindicator
|
|
||||||
registerType("celebrating", false); // TODO
|
|
||||||
|
|
||||||
// Wither
|
// Wither
|
||||||
registerType("invulnerable_time", 0); // TODO
|
registerType("invulnerable_time", 0); // TODO
|
||||||
|
|
||||||
// Phantom
|
*/
|
||||||
registerType("phantom_size", 0); // TODO
|
}
|
||||||
|
|
||||||
// Slime
|
public void registerTypes(PacketFactory packetFactory) {
|
||||||
registerType("slime_size", 0); // TODO
|
ServerVersion ver = PacketEvents.getAPI().getServerManager().getVersion();
|
||||||
|
boolean legacyBooleans = ver.isOlderThan(ServerVersion.V_1_9);
|
||||||
|
boolean legacyNames = ver.isOlderThan(ServerVersion.V_1_9);
|
||||||
|
boolean optionalComponents = ver.isNewerThanOrEquals(ServerVersion.V_1_13);
|
||||||
|
|
||||||
|
register(new EquipmentProperty(packetFactory, "helmet", EquipmentSlot.HELMET));
|
||||||
|
register(new EquipmentProperty(packetFactory, "chestplate", EquipmentSlot.CHEST_PLATE));
|
||||||
|
register(new EquipmentProperty(packetFactory, "leggings", EquipmentSlot.LEGGINGS));
|
||||||
|
register(new EquipmentProperty(packetFactory, "boots", EquipmentSlot.BOOTS));
|
||||||
|
register(new EquipmentProperty(packetFactory, "hand", EquipmentSlot.MAIN_HAND));
|
||||||
|
register(new EquipmentProperty(packetFactory, "offhand", EquipmentSlot.OFF_HAND));
|
||||||
|
|
||||||
|
register(new NameProperty(legacyNames, optionalComponents));
|
||||||
|
register(new DinnerboneProperty(legacyNames, optionalComponents));
|
||||||
|
|
||||||
|
register(new DummyProperty<>("look", false));
|
||||||
|
register(new GlowProperty(packetFactory));
|
||||||
|
register(new BitsetProperty("fire", 0, 0x01));
|
||||||
|
register(new BitsetProperty("invisible", 0, 0x20));
|
||||||
|
register(new HologramItemProperty());
|
||||||
|
linkProperties("glow", "fire", "invisible");
|
||||||
|
register(new BooleanProperty("silent", 4, false, legacyBooleans));
|
||||||
|
|
||||||
|
final int tamedIndex;
|
||||||
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) tamedIndex = 17;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) tamedIndex = 16;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) tamedIndex = 15;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) tamedIndex = 13;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) tamedIndex = 12;
|
||||||
|
else tamedIndex = 16;
|
||||||
|
register(new BitsetProperty("tamed", tamedIndex, 0x04));
|
||||||
|
|
||||||
|
int potionIndex;
|
||||||
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) potionIndex = 10;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) potionIndex = 9;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) potionIndex = 8;
|
||||||
|
else potionIndex = 7;
|
||||||
|
register(new EncodedIntegerProperty<>("potion_color", Color.class, potionIndex++, Color::asRGB));
|
||||||
|
register(new BooleanProperty("potion_ambient", potionIndex, false, legacyBooleans));
|
||||||
|
|
||||||
|
int babyIndex;
|
||||||
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) babyIndex = 16;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) babyIndex = 15;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) babyIndex = 14;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) babyIndex = 12;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) babyIndex = 11;
|
||||||
|
else babyIndex = 12;
|
||||||
|
register(new BooleanProperty("baby", babyIndex, false, legacyBooleans));
|
||||||
|
|
||||||
|
// Player
|
||||||
|
register(new DummyProperty<>("skin", SkinDescriptor.class, false));
|
||||||
|
final int skinLayersIndex;
|
||||||
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) skinLayersIndex = 17;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_16)) skinLayersIndex = 16;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) skinLayersIndex = 15;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) skinLayersIndex = 13;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) skinLayersIndex = 12;
|
||||||
|
else skinLayersIndex = 10;
|
||||||
|
register(new BitsetProperty("skin_cape", skinLayersIndex, 0x01));
|
||||||
|
register(new BitsetProperty("skin_jacket", skinLayersIndex, 0x02));
|
||||||
|
register(new BitsetProperty("skin_left_sleeve", skinLayersIndex, 0x04));
|
||||||
|
register(new BitsetProperty("skin_right_sleeve", skinLayersIndex, 0x08));
|
||||||
|
register(new BitsetProperty("skin_left_leg", skinLayersIndex, 0x10));
|
||||||
|
register(new BitsetProperty("skin_right_leg", skinLayersIndex, 0x20));
|
||||||
|
register(new BitsetProperty("skin_hat", skinLayersIndex, 0x40));
|
||||||
|
linkProperties("skin_cape", "skin_jacket", "skin_left_sleeve", "skin_right_sleeve", "skin_left_leg", "skin_right_leg", "skin_hat");
|
||||||
|
|
||||||
|
// Armor Stand
|
||||||
|
int armorStandIndex;
|
||||||
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) armorStandIndex = 15;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) armorStandIndex = 14;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) armorStandIndex = 13;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) armorStandIndex = 11;
|
||||||
|
else armorStandIndex = 10;
|
||||||
|
register(new BitsetProperty("small", armorStandIndex, 0x01));
|
||||||
|
register(new BitsetProperty("arms", armorStandIndex, 0x04));
|
||||||
|
register(new BitsetProperty("base_plate", armorStandIndex++, 0x08, true));
|
||||||
|
linkProperties("small", "arms", "base_plate");
|
||||||
|
register(new RotationProperty("head_rotation", armorStandIndex++, Vector3f.zero()));
|
||||||
|
register(new RotationProperty("body_rotation", armorStandIndex++, Vector3f.zero()));
|
||||||
|
register(new RotationProperty("left_arm_rotation", armorStandIndex++, new Vector3f(-10, 0, -10)));
|
||||||
|
register(new RotationProperty("right_arm_rotation", armorStandIndex++, new Vector3f(-15, 0, 10)));
|
||||||
|
register(new RotationProperty("left_leg_rotation", armorStandIndex++, new Vector3f(-1, 0, -1)));
|
||||||
|
register(new RotationProperty("right_leg_rotation", armorStandIndex, new Vector3f(1, 0, 1)));
|
||||||
|
|
||||||
|
// Ghast
|
||||||
|
final int ghastAttackingIndex;
|
||||||
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) ghastAttackingIndex = 16;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) ghastAttackingIndex = 15;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) ghastAttackingIndex = 14;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) ghastAttackingIndex = 12;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) ghastAttackingIndex = 11;
|
||||||
|
else ghastAttackingIndex = 16;
|
||||||
|
register(new BooleanProperty("attacking", ghastAttackingIndex, false, legacyBooleans));
|
||||||
|
|
||||||
|
// Bat
|
||||||
|
final int batIndex;
|
||||||
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) batIndex = 16;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) batIndex = 15;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) batIndex = 14;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) batIndex = 12;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) batIndex = 11;
|
||||||
|
else batIndex = 16;
|
||||||
|
register(new BooleanProperty("hanging", batIndex, false, true /* This isn't a mistake */));
|
||||||
|
|
||||||
|
// Blaze
|
||||||
|
final int blazeIndex;
|
||||||
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) blazeIndex = 16;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) blazeIndex = 15;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) blazeIndex = 14;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) blazeIndex = 12;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) blazeIndex = 11;
|
||||||
|
else blazeIndex = 16;
|
||||||
|
register(new BitsetProperty("blaze_on_fire", blazeIndex, 0x01));
|
||||||
|
|
||||||
|
// Creeper
|
||||||
|
int creeperIndex;
|
||||||
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) creeperIndex = 16;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) creeperIndex = 15;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) creeperIndex = 14;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) creeperIndex = 12;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) creeperIndex = 11;
|
||||||
|
else creeperIndex= 16;
|
||||||
|
register(new EncodedIntegerProperty<>("creeper_state", CreeperState.IDLE, creeperIndex++, CreeperState::getState));
|
||||||
|
register(new BooleanProperty("creeper_charged", creeperIndex, false, legacyBooleans));
|
||||||
|
|
||||||
|
// Abstract Horse
|
||||||
|
int horseIndex;
|
||||||
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) horseIndex = 17;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) horseIndex = 16;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) horseIndex = 15;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) horseIndex = 13;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) horseIndex = 12;
|
||||||
|
else horseIndex = 16;
|
||||||
|
int horseEating = ver.isNewerThanOrEquals(ServerVersion.V_1_12) ? 0x10 : 0x20;
|
||||||
|
register(new BitsetProperty("is_tame", horseIndex, 0x02, false, legacyBooleans));
|
||||||
|
register(new BitsetProperty("is_saddled", horseIndex, 0x04, false, legacyBooleans));
|
||||||
|
register(new BitsetProperty("is_eating", horseIndex, horseEating, false, legacyBooleans));
|
||||||
|
register(new BitsetProperty("is_rearing", horseIndex, horseEating << 1, false, legacyBooleans));
|
||||||
|
register(new BitsetProperty("has_mouth_open", horseIndex, horseEating << 2, false, legacyBooleans));
|
||||||
|
|
||||||
|
// Horse
|
||||||
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_8) && ver.isOlderThan(ServerVersion.V_1_9)) {
|
||||||
|
register(new EncodedByteProperty<>("horse_type", HorseType.HORSE, 19, obj -> (byte) obj.ordinal()));
|
||||||
|
} else if (ver.isOlderThan(ServerVersion.V_1_11)) {
|
||||||
|
int horseTypeIndex = 14;
|
||||||
|
if (ver.isOlderThan(ServerVersion.V_1_10)) horseTypeIndex = 13;
|
||||||
|
register(new EncodedIntegerProperty<>("horse_type", HorseType.HORSE, horseTypeIndex, Enum::ordinal));
|
||||||
|
}
|
||||||
|
int horseVariantIndex;
|
||||||
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_18)) horseVariantIndex = 18;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) horseVariantIndex = 19;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) horseVariantIndex = 18;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) horseVariantIndex = 17;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) horseVariantIndex = 15;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) horseVariantIndex = 14;
|
||||||
|
else horseVariantIndex = 20;
|
||||||
|
register(new HorseStyleProperty(horseVariantIndex));
|
||||||
|
register(new HorseColorProperty(horseVariantIndex));
|
||||||
|
linkProperties("horse_style", "horse_color");
|
||||||
|
|
||||||
|
// Use chesteplate property for 1.14 and above
|
||||||
|
if (ver.isOlderThan(ServerVersion.V_1_14)) {
|
||||||
|
register(new EncodedIntegerProperty<>("horse_armor", HorseArmor.NONE, horseVariantIndex + 2, Enum::ordinal));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chested Horse
|
||||||
|
if (ver.isOlderThan(ServerVersion.V_1_11)) {
|
||||||
|
register(new BitsetProperty("has_chest", horseIndex, 0x08, false, legacyBooleans));
|
||||||
|
linkProperties("is_saddled", "has_chest", "is_eating", "is_rearing", "has_mouth_open");
|
||||||
|
} else {
|
||||||
|
register(new BooleanProperty("has_chest", horseVariantIndex, false, legacyBooleans));
|
||||||
|
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;
|
||||||
|
// Pose
|
||||||
|
register(new NpcPoseProperty());
|
||||||
|
|
||||||
|
// Villager
|
||||||
|
final int villagerIndex;
|
||||||
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) villagerIndex = 18;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) villagerIndex = 17;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_14)) villagerIndex = 16;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) villagerIndex = 13;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) villagerIndex = 12;
|
||||||
|
else villagerIndex = 16;
|
||||||
|
register(new VillagerTypeProperty("villager_type", villagerIndex, VillagerType.PLAINS));
|
||||||
|
register(new VillagerProfessionProperty("villager_profession", villagerIndex, VillagerProfession.NONE));
|
||||||
|
register(new VillagerLevelProperty("villager_level", villagerIndex, VillagerLevel.STONE));
|
||||||
|
linkProperties("villager_type", "villager_profession", "villager_level");
|
||||||
|
|
||||||
|
// Cat
|
||||||
|
int catIndex;
|
||||||
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) catIndex = 19;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) catIndex = 18;
|
||||||
|
else catIndex = 17;
|
||||||
|
register(new EncodedIntegerProperty<>("cat_variant", CatVariant.BLACK, catIndex++, Enum::ordinal, EntityDataTypes.CAT_VARIANT));
|
||||||
|
register(new BooleanProperty("cat_laying", catIndex++, false, legacyBooleans));
|
||||||
|
register(new BooleanProperty("cat_relaxed", catIndex++, false, legacyBooleans));
|
||||||
|
register(new EncodedIntegerProperty<>("cat_collar", DyeColor.RED, catIndex, Enum::ordinal));
|
||||||
|
|
||||||
|
// Fox
|
||||||
|
int foxIndex;
|
||||||
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) foxIndex = 17;
|
||||||
|
else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) foxIndex = 16;
|
||||||
|
else foxIndex = 15;
|
||||||
|
register(new EncodedIntegerProperty<>("fox_variant", FoxVariant.RED, foxIndex++, Enum::ordinal));
|
||||||
|
register(new BitsetProperty("fox_sitting", foxIndex, 0x01));
|
||||||
|
register(new BitsetProperty("fox_crouching", foxIndex, 0x04));
|
||||||
|
register(new BitsetProperty("fox_sleeping", foxIndex, 0x20));
|
||||||
|
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;
|
||||||
|
|
||||||
|
register(new BitsetProperty("fox_faceplanted", foxIndex, 0x40));
|
||||||
|
linkProperties("fox_sitting", "fox_crouching", "fox_sleeping", "fox_faceplanted");
|
||||||
|
|
||||||
|
// Bee
|
||||||
|
int beeIndex;
|
||||||
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) beeIndex = 17;
|
||||||
|
else beeIndex = 18;
|
||||||
|
register(new BitsetProperty("has_nectar", beeIndex++, 0x08));
|
||||||
|
register(new EncodedIntegerProperty<>("angry", false, beeIndex, enabled -> enabled ? 1 : 0));
|
||||||
|
|
||||||
|
if (!ver.isNewerThanOrEquals(ServerVersion.V_1_16)) return;
|
||||||
|
|
||||||
|
// Hoglin and Piglin Zombification
|
||||||
|
final int zombificationIndex;
|
||||||
|
if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) zombificationIndex = 17; // Change piglinIndex and pillagerIndex if you change this
|
||||||
|
else zombificationIndex = 16;
|
||||||
|
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
|
||||||
|
register(new BooleanProperty("pillager_charging", zombificationIndex, false, legacyBooleans));
|
||||||
|
|
||||||
|
// Vindicator
|
||||||
|
int vindicatorIndex = zombificationIndex -1;
|
||||||
|
register(new BooleanProperty("celebrating", vindicatorIndex, false, legacyBooleans));
|
||||||
|
|
||||||
|
if (!ver.isNewerThanOrEquals(ServerVersion.V_1_17)) return;
|
||||||
|
// Axolotl
|
||||||
|
register(new EncodedIntegerProperty<>("axolotl_variant", AxolotlVariant.LUCY, 17, Enum::ordinal));
|
||||||
|
register(new BooleanProperty("playing_dead", 18, false, legacyBooleans));
|
||||||
|
|
||||||
|
// Goat
|
||||||
|
register(new BooleanProperty("has_left_horn", 18, true, legacyBooleans));
|
||||||
|
register(new BooleanProperty("has_right_horn", 19, true, legacyBooleans));
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
// Camel
|
||||||
|
register(new BooleanProperty("bashing", 18, false, legacyBooleans));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerSerializer(PropertySerializer<?> serializer) {
|
private void registerSerializer(PropertySerializer<?> serializer) {
|
||||||
|
@ -235,18 +515,27 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
|
||||||
serializerMap.put(clazz, new EnumPropertySerializer<>(clazz));
|
serializerMap.put(clazz, new EnumPropertySerializer<>(clazz));
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> void registerType(String name, Class<T> type) {
|
private <T> void register(EntityPropertyImpl<?> property) {
|
||||||
registerType(name, null, type);
|
if (byName.containsKey(property.getName()))
|
||||||
|
throw new IllegalArgumentException("Duplicate property name: " + property.getName());
|
||||||
|
byName.put(property.getName(), property);
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> void registerType(String name, T defaultValue) {
|
private void linkProperties(String... names) {
|
||||||
registerType(name, defaultValue, (Class<T>) defaultValue.getClass());
|
linkProperties(Arrays.stream(names)
|
||||||
|
.map(this::getByName)
|
||||||
|
.collect(Collectors.toSet()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> void registerType(String name, T defaultValue, Class<T> clazz) {
|
private void linkProperties(Collection<EntityPropertyImpl<?>> properties) {
|
||||||
if (clazz == null) return;
|
for (EntityPropertyImpl<?> property : properties) for (EntityPropertyImpl<?> dependency : properties) {
|
||||||
EntityPropertyImpl<T> property = new EntityPropertyImpl<>(name, defaultValue, clazz, (PropertySerializer<T>) serializerMap.get(clazz));
|
if (property.equals(dependency)) continue;
|
||||||
byName.put(name.toLowerCase(), property);
|
property.addDependency(dependency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public <V> PropertySerializer<V> getSerializer(Class<V> type) {
|
||||||
|
return (PropertySerializer<V>) serializerMap.get(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -4,6 +4,7 @@ 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.type.EntityType;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||||
|
import lol.pyr.znpcsplus.api.entity.EntityProperty;
|
||||||
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
||||||
import lol.pyr.znpcsplus.packets.PacketFactory;
|
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||||
import lol.pyr.znpcsplus.reflection.Reflections;
|
import lol.pyr.znpcsplus.reflection.Reflections;
|
||||||
|
@ -11,9 +12,10 @@ import lol.pyr.znpcsplus.util.NpcLocation;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class PacketEntity {
|
public class PacketEntity implements PropertyHolder {
|
||||||
private final PacketFactory packetFactory;
|
private final PacketFactory packetFactory;
|
||||||
|
|
||||||
private final PropertyHolder properties;
|
private final PropertyHolder properties;
|
||||||
|
@ -66,11 +68,6 @@ public class PacketEntity {
|
||||||
packetFactory.sendAllMetadata(player, this, properties);
|
packetFactory.sendAllMetadata(player, this, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remakeTeam(Player player) {
|
|
||||||
packetFactory.removeTeam(player, this);
|
|
||||||
packetFactory.createTeam(player, this, properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int reserveEntityID() {
|
private static int reserveEntityID() {
|
||||||
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_14)) {
|
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_14)) {
|
||||||
return Reflections.ATOMIC_ENTITY_ID_FIELD.get().incrementAndGet();
|
return Reflections.ATOMIC_ENTITY_ID_FIELD.get().incrementAndGet();
|
||||||
|
@ -80,4 +77,24 @@ public class PacketEntity {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T getProperty(EntityProperty<T> key) {
|
||||||
|
return properties.getProperty(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasProperty(EntityProperty<?> key) {
|
||||||
|
return properties.hasProperty(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> void setProperty(EntityProperty<T> key, T value) {
|
||||||
|
properties.setProperty(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<EntityProperty<?>> getAppliedProperties() {
|
||||||
|
return properties.getAppliedProperties();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,4 +4,9 @@ public interface PropertySerializer<T> {
|
||||||
String serialize(T property);
|
String serialize(T property);
|
||||||
T deserialize(String property);
|
T deserialize(String property);
|
||||||
Class<T> getTypeClass();
|
Class<T> getTypeClass();
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
default String UNSAFE_serialize(Object property) {
|
||||||
|
return serialize((T) property);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
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 org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class BitsetProperty extends EntityPropertyImpl<Boolean> {
|
||||||
|
private final int index;
|
||||||
|
private final int bitmask;
|
||||||
|
private final boolean inverted;
|
||||||
|
private boolean integer = false;
|
||||||
|
|
||||||
|
public BitsetProperty(String name, int index, int bitmask, boolean inverted, boolean integer) {
|
||||||
|
this(name, index, bitmask, inverted);
|
||||||
|
this.integer = integer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitsetProperty(String name, int index, int bitmask, boolean inverted) {
|
||||||
|
super(name, inverted, Boolean.class);
|
||||||
|
this.index = index;
|
||||||
|
this.bitmask = bitmask;
|
||||||
|
this.inverted = inverted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitsetProperty(String name, int index, int bitmask) {
|
||||||
|
this(name, index, bitmask, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
|
||||||
|
EntityData oldData = properties.get(index);
|
||||||
|
boolean enabled = entity.getProperty(this);
|
||||||
|
if (inverted) enabled = !enabled;
|
||||||
|
properties.put(index,
|
||||||
|
integer ? newEntityData(index, EntityDataTypes.INT, (oldData == null ? 0 : (int) oldData.getValue()) | (enabled ? bitmask : 0)) :
|
||||||
|
newEntityData(index, EntityDataTypes.BYTE, (byte) ((oldData == null ? 0 : (byte) oldData.getValue()) | (enabled ? bitmask : 0))));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
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 org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class BooleanProperty extends EntityPropertyImpl<Boolean> {
|
||||||
|
private final int index;
|
||||||
|
private final boolean legacy;
|
||||||
|
private final boolean inverted;
|
||||||
|
|
||||||
|
public BooleanProperty(String name, int index, boolean defaultValue, boolean legacy) {
|
||||||
|
this(name, index, defaultValue, legacy, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanProperty(String name, int index, boolean defaultValue, boolean legacy, boolean inverted) {
|
||||||
|
super(name, defaultValue, Boolean.class);
|
||||||
|
this.index = index;
|
||||||
|
this.legacy = legacy;
|
||||||
|
this.inverted = inverted;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
|
||||||
|
boolean enabled = entity.getProperty(this);
|
||||||
|
if (inverted) enabled = !enabled;
|
||||||
|
if (legacy) properties.put(index, newEntityData(index, EntityDataTypes.BYTE, (byte) (enabled ? 1 : 0)));
|
||||||
|
else properties.put(index, newEntityData(index, EntityDataTypes.BOOLEAN, enabled));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
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.util.adventure.AdventureSerializer;
|
||||||
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class DinnerboneProperty extends EntityPropertyImpl<Boolean> {
|
||||||
|
private final Object serialized;
|
||||||
|
private final EntityDataType<?> type;
|
||||||
|
|
||||||
|
public DinnerboneProperty(boolean legacy, boolean optional) {
|
||||||
|
super("dinnerbone", false, Boolean.class);
|
||||||
|
Component name = Component.text("Dinnerbone");
|
||||||
|
String serialized = legacy ?
|
||||||
|
AdventureSerializer.getLegacyGsonSerializer().serialize(name) :
|
||||||
|
AdventureSerializer.getGsonSerializer().serialize(name);
|
||||||
|
this.serialized = optional ? Optional.of(serialized) : serialized;
|
||||||
|
this.type = optional ? EntityDataTypes.OPTIONAL_COMPONENT : EntityDataTypes.STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
|
||||||
|
properties.put(2, new EntityData(2, type, entity.getProperty(this) ? serialized : null));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package lol.pyr.znpcsplus.entity.properties;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||||
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class DummyProperty<T> extends EntityPropertyImpl<T> {
|
||||||
|
public DummyProperty(String name, T defaultValue) {
|
||||||
|
this(name, defaultValue, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DummyProperty(String name, Class<T> clazz) {
|
||||||
|
this(name, clazz, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public DummyProperty(String name, T defaultValue, boolean playerModifiable) {
|
||||||
|
super(name, defaultValue, (Class<T>) defaultValue.getClass());
|
||||||
|
setPlayerModifiable(playerModifiable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DummyProperty(String name, Class<T> clazz, boolean playerModifiable) {
|
||||||
|
super(name, null, clazz);
|
||||||
|
setPlayerModifiable(playerModifiable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 EncodedByteProperty<T> extends EntityPropertyImpl<T> {
|
||||||
|
private final EntityDataType<Byte> type;
|
||||||
|
private final ByteDecoder<T> decoder;
|
||||||
|
private final int index;
|
||||||
|
|
||||||
|
protected EncodedByteProperty(String name, T defaultValue, Class<T> clazz, int index, ByteDecoder<T> decoder, EntityDataType<Byte> type) {
|
||||||
|
super(name, defaultValue, clazz);
|
||||||
|
this.decoder = decoder;
|
||||||
|
this.index = index;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public EncodedByteProperty(String name, T defaultValue, int index, ByteDecoder<T> decoder) {
|
||||||
|
this(name, defaultValue, (Class<T>) defaultValue.getClass(), index, decoder, EntityDataTypes.BYTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public EncodedByteProperty(String name, T defaultValue, int index, ByteDecoder<T> decoder, EntityDataType<Byte> type) {
|
||||||
|
this(name, defaultValue, (Class<T>) defaultValue.getClass(), index, decoder, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EncodedByteProperty(String name, Class<T> clazz, int index, ByteDecoder<T> decoder) {
|
||||||
|
this(name, null, clazz, index, decoder, EntityDataTypes.BYTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 ByteDecoder<T> {
|
||||||
|
byte decode(T obj);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 EncodedIntegerProperty<T> extends EntityPropertyImpl<T> {
|
||||||
|
private final EntityDataType<Integer> type;
|
||||||
|
private final IntegerDecoder<T> decoder;
|
||||||
|
private final int index;
|
||||||
|
|
||||||
|
protected EncodedIntegerProperty(String name, T defaultValue, Class<T> clazz, int index, IntegerDecoder<T> decoder, EntityDataType<Integer> type) {
|
||||||
|
super(name, defaultValue, clazz);
|
||||||
|
this.decoder = decoder;
|
||||||
|
this.index = index;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public EncodedIntegerProperty(String name, T defaultValue, int index, IntegerDecoder<T> decoder) {
|
||||||
|
this(name, defaultValue, (Class<T>) defaultValue.getClass(), index, decoder, EntityDataTypes.INT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public EncodedIntegerProperty(String name, T defaultValue, int index, IntegerDecoder<T> decoder, EntityDataType<Integer> type) {
|
||||||
|
this(name, defaultValue, (Class<T>) defaultValue.getClass(), index, decoder, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EncodedIntegerProperty(String name, Class<T> clazz, int index, IntegerDecoder<T> decoder) {
|
||||||
|
this(name, null, clazz, index, decoder, EntityDataTypes.INT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 IntegerDecoder<T> {
|
||||||
|
int decode(T obj);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package lol.pyr.znpcsplus.entity.properties;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||||
|
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||||
|
import com.github.retrooper.packetevents.protocol.player.Equipment;
|
||||||
|
import com.github.retrooper.packetevents.protocol.player.EquipmentSlot;
|
||||||
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
|
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class EquipmentProperty extends EntityPropertyImpl<ItemStack> {
|
||||||
|
private final PacketFactory packetFactory;
|
||||||
|
private final EquipmentSlot slot;
|
||||||
|
|
||||||
|
public EquipmentProperty(PacketFactory packetFactory, String name, EquipmentSlot slot) {
|
||||||
|
super(name, null, ItemStack.class);
|
||||||
|
this.packetFactory = packetFactory;
|
||||||
|
this.slot = slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
|
||||||
|
packetFactory.sendEquipment(player, entity, new Equipment(slot, entity.getProperty(this)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
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.packets.PacketFactory;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class GlowProperty extends EntityPropertyImpl<NamedTextColor> {
|
||||||
|
private final PacketFactory packetFactory;
|
||||||
|
|
||||||
|
public GlowProperty(PacketFactory packetFactory) {
|
||||||
|
super("glow", null, NamedTextColor.class);
|
||||||
|
this.packetFactory = packetFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
|
||||||
|
NamedTextColor value = entity.getProperty(this);
|
||||||
|
EntityData oldData = properties.get(0);
|
||||||
|
byte oldValue = oldData == null ? 0 : (byte) oldData.getValue();
|
||||||
|
properties.put(0, newEntityData(0, EntityDataTypes.BYTE, (byte) (oldValue | (value == null ? 0 : 0x40))));
|
||||||
|
if (isSpawned) packetFactory.removeTeam(player, entity);
|
||||||
|
packetFactory.createTeam(player, entity, value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
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 com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||||
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class HologramItemProperty extends EntityPropertyImpl<ItemStack> {
|
||||||
|
|
||||||
|
public HologramItemProperty() {
|
||||||
|
super("holo_item", null, ItemStack.class);
|
||||||
|
setPlayerModifiable(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
|
||||||
|
properties.put(8, newEntityData(8, EntityDataTypes.ITEMSTACK, entity.getProperty(this)));
|
||||||
|
properties.put(5, newEntityData(5, EntityDataTypes.BOOLEAN, true));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
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.util.HorseColor;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class HorseColorProperty extends EntityPropertyImpl<HorseColor> {
|
||||||
|
private final int index;
|
||||||
|
|
||||||
|
public HorseColorProperty(int index) {
|
||||||
|
super("horse_color", HorseColor.WHITE, HorseColor.class);
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
|
||||||
|
EntityData oldData = properties.get(index);
|
||||||
|
HorseColor value = entity.getProperty(this);
|
||||||
|
properties.put(index, newEntityData(index, EntityDataTypes.INT, value.ordinal() | (oldData == null ? 0 : ((int) oldData.getValue() & 0xFF00))));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
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.util.HorseStyle;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class HorseStyleProperty extends EntityPropertyImpl<HorseStyle> {
|
||||||
|
private final int index;
|
||||||
|
|
||||||
|
public HorseStyleProperty(int index) {
|
||||||
|
super("horse_style", HorseStyle.NONE, HorseStyle.class);
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
|
||||||
|
EntityData oldData = properties.get(index);
|
||||||
|
HorseStyle value = entity.getProperty(this);
|
||||||
|
properties.put(index, newEntityData(index, EntityDataTypes.INT, (oldData == null ? 0 : ((int) oldData.getValue() & 0x00FF)) | (value.ordinal() << 8)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
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 org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class IntegerProperty extends EntityPropertyImpl<Integer> {
|
||||||
|
private final int index;
|
||||||
|
private final boolean legacy;
|
||||||
|
|
||||||
|
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);
|
||||||
|
this.index = index;
|
||||||
|
this.legacy = legacy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
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 com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
|
||||||
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
|
import lol.pyr.znpcsplus.util.PapiUtil;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class NameProperty extends EntityPropertyImpl<Component> {
|
||||||
|
private final boolean legacy;
|
||||||
|
private final boolean optional;
|
||||||
|
|
||||||
|
public NameProperty(boolean legacy, boolean optional) {
|
||||||
|
super("name", null, Component.class);
|
||||||
|
|
||||||
|
this.legacy = legacy;
|
||||||
|
this.optional = optional;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
|
||||||
|
Component value = entity.getProperty(this);
|
||||||
|
if (value != null) {
|
||||||
|
String serialized = legacy ?
|
||||||
|
AdventureSerializer.getLegacyGsonSerializer().serialize(value) :
|
||||||
|
AdventureSerializer.getGsonSerializer().serialize(value);
|
||||||
|
serialized = PapiUtil.set(player, serialized);
|
||||||
|
if (optional) properties.put(2, newEntityData(2, EntityDataTypes.OPTIONAL_COMPONENT, Optional.of(serialized)));
|
||||||
|
else properties.put(2, newEntityData(2, EntityDataTypes.STRING, serialized));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (legacy) properties.put(3, newEntityData(3, EntityDataTypes.BYTE, (byte) (value != null ? 1 : 0)));
|
||||||
|
else properties.put(3, newEntityData(3, EntityDataTypes.BOOLEAN, value != null));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
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 com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
|
||||||
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
|
import lol.pyr.znpcsplus.util.NpcPose;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class NpcPoseProperty extends EntityPropertyImpl<NpcPose> {
|
||||||
|
|
||||||
|
public NpcPoseProperty() {
|
||||||
|
super("pose", NpcPose.STANDING, NpcPose.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
|
||||||
|
properties.put(6, newEntityData(6, EntityDataTypes.ENTITY_POSE, EntityPose.valueOf(entity.getProperty(this).name())));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
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.util.Vector3f;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class RotationProperty extends EntityPropertyImpl<Vector3f> {
|
||||||
|
private final int index;
|
||||||
|
|
||||||
|
public RotationProperty(String name, int index, Vector3f defaultValue) {
|
||||||
|
super(name, defaultValue, Vector3f.class);
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
|
||||||
|
Vector3f vec = entity.getProperty(this);
|
||||||
|
properties.put(index, newEntityData(index, EntityDataTypes.ROTATION, new com.github.retrooper.packetevents.util.Vector3f(vec.getX(), vec.getY(), vec.getZ())));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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,31 @@
|
||||||
|
package lol.pyr.znpcsplus.entity.properties.villager;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.villager.VillagerData;
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.villager.profession.VillagerProfessions;
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.villager.type.VillagerTypes;
|
||||||
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public abstract class VillagerDataProperty<T> extends EntityPropertyImpl<T> {
|
||||||
|
private final int index;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public VillagerDataProperty(String name, int index, T def) {
|
||||||
|
super(name, def, (Class<T>) def.getClass());
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
|
||||||
|
EntityData oldData = properties.get(index);
|
||||||
|
VillagerData old = oldData == null ? new VillagerData(VillagerTypes.PLAINS, VillagerProfessions.NONE, 1) : (VillagerData) oldData.getValue();
|
||||||
|
properties.put(index, newEntityData(index, EntityDataTypes.VILLAGER_DATA, apply(old, entity.getProperty(this))));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract VillagerData apply(VillagerData data, T value);
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package lol.pyr.znpcsplus.entity.properties.villager;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.villager.VillagerData;
|
||||||
|
import lol.pyr.znpcsplus.util.VillagerLevel;
|
||||||
|
|
||||||
|
public class VillagerLevelProperty extends VillagerDataProperty<VillagerLevel> {
|
||||||
|
public VillagerLevelProperty(String name, int index, VillagerLevel def) {
|
||||||
|
super(name, index, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected VillagerData apply(VillagerData data, VillagerLevel value) {
|
||||||
|
data.setLevel(value.ordinal() + 1);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package lol.pyr.znpcsplus.entity.properties.villager;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.villager.VillagerData;
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.villager.profession.VillagerProfessions;
|
||||||
|
import lol.pyr.znpcsplus.util.VillagerProfession;
|
||||||
|
|
||||||
|
public class VillagerProfessionProperty extends VillagerDataProperty<VillagerProfession> {
|
||||||
|
public VillagerProfessionProperty(String name, int index, VillagerProfession def) {
|
||||||
|
super(name, index, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected VillagerData apply(VillagerData data, VillagerProfession value) {
|
||||||
|
data.setProfession(VillagerProfessions.getById(value.getId()));
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package lol.pyr.znpcsplus.entity.properties.villager;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.villager.VillagerData;
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.villager.type.VillagerTypes;
|
||||||
|
import lol.pyr.znpcsplus.util.VillagerType;
|
||||||
|
|
||||||
|
public class VillagerTypeProperty extends VillagerDataProperty<VillagerType> {
|
||||||
|
public VillagerTypeProperty(String name, int index, VillagerType def) {
|
||||||
|
super(name, index, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected VillagerData apply(VillagerData data, VillagerType value) {
|
||||||
|
data.setType(VillagerTypes.getById(value.getId()));
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,18 +1,19 @@
|
||||||
package lol.pyr.znpcsplus.entity.serializers;
|
package lol.pyr.znpcsplus.entity.serializers;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||||
|
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||||
import lol.pyr.znpcsplus.entity.PropertySerializer;
|
import lol.pyr.znpcsplus.entity.PropertySerializer;
|
||||||
import lol.pyr.znpcsplus.util.ItemSerializationUtil;
|
import lol.pyr.znpcsplus.util.ItemSerializationUtil;
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
public class ItemStackPropertySerializer implements PropertySerializer<ItemStack> {
|
public class ItemStackPropertySerializer implements PropertySerializer<ItemStack> {
|
||||||
@Override
|
@Override
|
||||||
public String serialize(ItemStack property) {
|
public String serialize(ItemStack property) {
|
||||||
return ItemSerializationUtil.itemToB64(property);
|
return ItemSerializationUtil.itemToB64(SpigotConversionUtil.toBukkitItemStack(property));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack deserialize(String property) {
|
public ItemStack deserialize(String property) {
|
||||||
return ItemSerializationUtil.itemFromB64(property);
|
return SpigotConversionUtil.fromBukkitItemStack(ItemSerializationUtil.itemFromB64(property));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,13 @@
|
||||||
package lol.pyr.znpcsplus.hologram;
|
package lol.pyr.znpcsplus.hologram;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||||
|
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||||
import lol.pyr.znpcsplus.api.hologram.Hologram;
|
import lol.pyr.znpcsplus.api.hologram.Hologram;
|
||||||
import lol.pyr.znpcsplus.config.ConfigManager;
|
import lol.pyr.znpcsplus.config.ConfigManager;
|
||||||
|
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
|
||||||
import lol.pyr.znpcsplus.packets.PacketFactory;
|
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||||
import lol.pyr.znpcsplus.util.Viewable;
|
|
||||||
import lol.pyr.znpcsplus.util.NpcLocation;
|
import lol.pyr.znpcsplus.util.NpcLocation;
|
||||||
|
import lol.pyr.znpcsplus.util.Viewable;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
@ -17,46 +20,75 @@ public class HologramImpl extends Viewable implements Hologram {
|
||||||
private final ConfigManager configManager;
|
private final ConfigManager configManager;
|
||||||
private final PacketFactory packetFactory;
|
private final PacketFactory packetFactory;
|
||||||
private final LegacyComponentSerializer textSerializer;
|
private final LegacyComponentSerializer textSerializer;
|
||||||
|
private final EntityPropertyRegistryImpl propertyRegistry;
|
||||||
|
|
||||||
private double offset = 0.0;
|
private double offset = 0.0;
|
||||||
private long refreshDelay = -1;
|
private long refreshDelay = -1;
|
||||||
private long lastRefresh = System.currentTimeMillis();
|
private long lastRefresh = System.currentTimeMillis();
|
||||||
private NpcLocation location;
|
private NpcLocation location;
|
||||||
private final List<HologramLine> lines = new ArrayList<>();
|
private final List<HologramLine<?>> lines = new ArrayList<>();
|
||||||
|
|
||||||
public HologramImpl(ConfigManager configManager, PacketFactory packetFactory, LegacyComponentSerializer textSerializer, NpcLocation location) {
|
public HologramImpl(EntityPropertyRegistryImpl propertyRegistry, ConfigManager configManager, PacketFactory packetFactory, LegacyComponentSerializer textSerializer, NpcLocation location) {
|
||||||
|
this.propertyRegistry = propertyRegistry;
|
||||||
this.configManager = configManager;
|
this.configManager = configManager;
|
||||||
this.packetFactory = packetFactory;
|
this.packetFactory = packetFactory;
|
||||||
this.textSerializer = textSerializer;
|
this.textSerializer = textSerializer;
|
||||||
this.location = location;
|
this.location = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addLineComponent(Component line) {
|
public void addTextLineComponent(Component line) {
|
||||||
HologramLine newLine = new HologramLine(packetFactory, null, line);
|
HologramText newLine = new HologramText(propertyRegistry, packetFactory, null, line);
|
||||||
|
lines.add(newLine);
|
||||||
|
relocateLines(newLine);
|
||||||
|
for (Player viewer : getViewers()) newLine.show(viewer.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTextLine(String line) {
|
||||||
|
addTextLineComponent(textSerializer.deserialize(line));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addItemLineStack(org.bukkit.inventory.ItemStack item) {
|
||||||
|
addItemLinePEStack(SpigotConversionUtil.fromBukkitItemStack(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addItemLine(String serializedItem) {
|
||||||
|
addItemLinePEStack(HologramItem.deserialize(serializedItem));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addItemLinePEStack(ItemStack item) {
|
||||||
|
HologramItem newLine = new HologramItem(propertyRegistry, packetFactory, null, item);
|
||||||
lines.add(newLine);
|
lines.add(newLine);
|
||||||
relocateLines(newLine);
|
relocateLines(newLine);
|
||||||
for (Player viewer : getViewers()) newLine.show(viewer.getPlayer());
|
for (Player viewer : getViewers()) newLine.show(viewer.getPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addLine(String line) {
|
public void addLine(String line) {
|
||||||
addLineComponent(textSerializer.deserialize(line));
|
if (line.toLowerCase().startsWith("item:")) {
|
||||||
|
addItemLine(line.substring(5));
|
||||||
|
} else {
|
||||||
|
addTextLine(line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Component getLineComponent(int index) {
|
public Component getLineTextComponent(int index) {
|
||||||
return lines.get(index).getText();
|
return ((HologramText) lines.get(index)).getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLine(int index) {
|
public String getLine(int index) {
|
||||||
return textSerializer.serialize(getLineComponent(index));
|
if (lines.get(index) instanceof HologramItem) {
|
||||||
|
return ((HologramItem) lines.get(index)).serialize();
|
||||||
|
} else {
|
||||||
|
return textSerializer.serialize(getLineTextComponent(index));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeLine(int index) {
|
public void removeLine(int index) {
|
||||||
HologramLine line = lines.remove(index);
|
HologramLine<?> line = lines.remove(index);
|
||||||
for (Player viewer : getViewers()) line.hide(viewer);
|
for (Player viewer : getViewers()) line.hide(viewer);
|
||||||
relocateLines();
|
relocateLines();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<HologramLine> getLines() {
|
public List<HologramLine<?>> getLines() {
|
||||||
return Collections.unmodifiableList(lines);
|
return Collections.unmodifiableList(lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,25 +97,48 @@ public class HologramImpl extends Viewable implements Hologram {
|
||||||
lines.clear();
|
lines.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insertLineComponent(int index, Component line) {
|
public void insertTextLineComponent(int index, Component line) {
|
||||||
HologramLine newLine = new HologramLine(packetFactory, null, line);
|
HologramText newLine = new HologramText(propertyRegistry, packetFactory, null, line);
|
||||||
lines.add(index, newLine);
|
lines.add(index, newLine);
|
||||||
relocateLines(newLine);
|
relocateLines(newLine);
|
||||||
for (Player viewer : getViewers()) newLine.show(viewer.getPlayer());
|
for (Player viewer : getViewers()) newLine.show(viewer.getPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void insertTextLine(int index, String line) {
|
||||||
|
insertTextLineComponent(index, textSerializer.deserialize(line));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void insertItemLineStack(int index, org.bukkit.inventory.ItemStack item) {
|
||||||
|
insertItemLinePEStack(index, SpigotConversionUtil.fromBukkitItemStack(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void insertItemLinePEStack(int index, ItemStack item) {
|
||||||
|
HologramItem newLine = new HologramItem(propertyRegistry, packetFactory, null, item);
|
||||||
|
lines.add(index, newLine);
|
||||||
|
relocateLines(newLine);
|
||||||
|
for (Player viewer : getViewers()) newLine.show(viewer.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void insertItemLine(int index, String item) {
|
||||||
|
insertItemLinePEStack(index, HologramItem.deserialize(item));
|
||||||
|
}
|
||||||
|
|
||||||
public void insertLine(int index, String line) {
|
public void insertLine(int index, String line) {
|
||||||
insertLineComponent(index, textSerializer.deserialize(line));
|
if (line.toLowerCase().startsWith("item:")) {
|
||||||
|
insertItemLine(index, line.substring(5));
|
||||||
|
} else {
|
||||||
|
insertTextLine(index, line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void UNSAFE_show(Player player) {
|
protected void UNSAFE_show(Player player) {
|
||||||
for (HologramLine line : lines) line.show(player);
|
for (HologramLine<?> line : lines) line.show(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void UNSAFE_hide(Player player) {
|
protected void UNSAFE_hide(Player player) {
|
||||||
for (HologramLine line : lines) line.hide(player);
|
for (HologramLine<?> line : lines) line.hide(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getRefreshDelay() {
|
public long getRefreshDelay() {
|
||||||
|
@ -100,7 +155,7 @@ public class HologramImpl extends Viewable implements Hologram {
|
||||||
|
|
||||||
public void refresh() {
|
public void refresh() {
|
||||||
lastRefresh = System.currentTimeMillis();
|
lastRefresh = System.currentTimeMillis();
|
||||||
for (HologramLine line : lines) for (Player viewer : getViewers()) line.refreshMeta(viewer);
|
for (HologramLine<?> line : lines) for (Player viewer : getViewers()) line.refreshMeta(viewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLocation(NpcLocation location) {
|
public void setLocation(NpcLocation location) {
|
||||||
|
@ -112,10 +167,10 @@ public class HologramImpl extends Viewable implements Hologram {
|
||||||
relocateLines(null);
|
relocateLines(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void relocateLines(HologramLine newLine) {
|
private void relocateLines(HologramLine<?> newLine) {
|
||||||
final double lineSpacing = configManager.getConfig().lineSpacing();
|
final double lineSpacing = configManager.getConfig().lineSpacing();
|
||||||
double height = location.getY() + (lines.size() - 1) * lineSpacing + getOffset();
|
double height = location.getY() + (lines.size() - 1) * lineSpacing + getOffset();
|
||||||
for (HologramLine line : lines) {
|
for (HologramLine<?> line : lines) {
|
||||||
line.setLocation(location.withY(height), line == newLine ? Collections.emptySet() : getViewers());
|
line.setLocation(location.withY(height), line == newLine ? Collections.emptySet() : getViewers());
|
||||||
height -= lineSpacing;
|
height -= lineSpacing;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
package lol.pyr.znpcsplus.hologram;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||||
|
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||||
|
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
|
||||||
|
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||||
|
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||||
|
import com.github.retrooper.packetevents.protocol.nbt.NBTInt;
|
||||||
|
import com.github.retrooper.packetevents.protocol.nbt.NBTNumber;
|
||||||
|
import com.github.retrooper.packetevents.protocol.nbt.codec.NBTCodec;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import com.google.gson.JsonSyntaxException;
|
||||||
|
import lol.pyr.znpcsplus.api.entity.EntityProperty;
|
||||||
|
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
|
||||||
|
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||||
|
import lol.pyr.znpcsplus.util.NpcLocation;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public class HologramItem extends HologramLine<ItemStack> {
|
||||||
|
public HologramItem(EntityPropertyRegistryImpl propertyRegistry, PacketFactory packetFactory, NpcLocation location, ItemStack item) {
|
||||||
|
super(item, packetFactory, EntityTypes.ITEM, location);
|
||||||
|
addProperty(propertyRegistry.getByName("holo_item"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public <T> T getProperty(EntityProperty<T> key) {
|
||||||
|
if (key.getName().equalsIgnoreCase("holo_item")) return (T) getValue();
|
||||||
|
return super.getProperty(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLocation(NpcLocation location, Collection<Player> viewers) {
|
||||||
|
super.setLocation(location.withY(location.getY() + 2.05), viewers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean ensureValidItemInput(String in) {
|
||||||
|
if (in == null || in.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int indexOfNbt = in.indexOf("{");
|
||||||
|
if (indexOfNbt != -1) {
|
||||||
|
String typeName = in.substring(0, indexOfNbt);
|
||||||
|
ItemType type = ItemTypes.getByName("minecraft:" + typeName.toLowerCase());
|
||||||
|
if (type == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String nbtString = in.substring(indexOfNbt);
|
||||||
|
return ensureValidNbt(nbtString);
|
||||||
|
} else {
|
||||||
|
ItemType type = ItemTypes.getByName("minecraft:" + in.toLowerCase());
|
||||||
|
return type != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean ensureValidNbt(String nbtString) {
|
||||||
|
JsonElement nbtJson;
|
||||||
|
try {
|
||||||
|
nbtJson = JsonParser.parseString(nbtString);
|
||||||
|
} catch (JsonSyntaxException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
NBTCodec.jsonToNBT(nbtJson);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemStack deserialize(String serializedItem) {
|
||||||
|
int indexOfNbt = serializedItem.indexOf("{");
|
||||||
|
String typeName = serializedItem;
|
||||||
|
int amount = 1;
|
||||||
|
NBTCompound nbt = new NBTCompound();
|
||||||
|
if (indexOfNbt != -1) {
|
||||||
|
typeName = serializedItem.substring(0, indexOfNbt);
|
||||||
|
String nbtString = serializedItem.substring(indexOfNbt);
|
||||||
|
JsonElement nbtJson = null;
|
||||||
|
try {
|
||||||
|
nbtJson = JsonParser.parseString(nbtString);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
if (nbtJson != null) {
|
||||||
|
nbt = (NBTCompound) NBTCodec.jsonToNBT(nbtJson);
|
||||||
|
NBTNumber nbtAmount = nbt.getNumberTagOrNull("Count");
|
||||||
|
if (nbtAmount != null) {
|
||||||
|
nbt.removeTag("Count");
|
||||||
|
amount = nbtAmount.getAsInt();
|
||||||
|
if (amount <= 0) amount = 1;
|
||||||
|
if (amount > 127) amount = 127;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ItemType type = ItemTypes.getByName("minecraft:" + typeName.toLowerCase());
|
||||||
|
if (type == null) type = ItemTypes.STONE;
|
||||||
|
return ItemStack.builder().type(type).amount(amount).nbt(nbt).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String serialize() {
|
||||||
|
NBTCompound nbt = getValue().getNBT();
|
||||||
|
if (nbt == null) nbt = new NBTCompound();
|
||||||
|
if (getValue().getAmount() > 1) nbt.setTag("Count", new NBTInt(getValue().getAmount()));
|
||||||
|
if (nbt.isEmpty()) return "item:" + getValue().getType().getName().toString().replace("minecraft:", "");
|
||||||
|
return "item:" + getValue().getType().getName().toString().replace("minecraft:", "") + NBTCodec.nbtToJson(nbt, true);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,64 +1,77 @@
|
||||||
package lol.pyr.znpcsplus.hologram;
|
package lol.pyr.znpcsplus.hologram;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||||
import lol.pyr.znpcsplus.api.entity.EntityProperty;
|
import lol.pyr.znpcsplus.api.entity.EntityProperty;
|
||||||
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
||||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
import lol.pyr.znpcsplus.packets.PacketFactory;
|
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||||
import lol.pyr.znpcsplus.util.NpcLocation;
|
import lol.pyr.znpcsplus.util.NpcLocation;
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class HologramLine implements PropertyHolder {
|
public class HologramLine<M> implements PropertyHolder {
|
||||||
private Component text;
|
private M value;
|
||||||
private final PacketEntity armorStand;
|
private final PacketEntity entity;
|
||||||
|
private final Set<EntityProperty<?>> properties;
|
||||||
|
|
||||||
public HologramLine(PacketFactory packetFactory, NpcLocation location, Component text) {
|
public HologramLine(M value, PacketFactory packetFactory, EntityType type, NpcLocation location) {
|
||||||
this.text = text;
|
this.value = value;
|
||||||
armorStand = new PacketEntity(packetFactory, this, EntityTypes.ARMOR_STAND, location);
|
this.entity = new PacketEntity(packetFactory, this, type, location);
|
||||||
|
this.properties = new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Component getText() {
|
public M getValue() {
|
||||||
return text;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setText(Component text) {
|
public void setValue(M value) {
|
||||||
this.text = text;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshMeta(Player player) {
|
public void refreshMeta(Player player) {
|
||||||
armorStand.refreshMeta(player);
|
entity.refreshMeta(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void show(Player player) {
|
protected void show(Player player) {
|
||||||
armorStand.spawn(player);
|
entity.spawn(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void hide(Player player) {
|
protected void hide(Player player) {
|
||||||
armorStand.despawn(player);
|
entity.despawn(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLocation(NpcLocation location, Collection<Player> viewers) {
|
public void setLocation(NpcLocation location, Collection<Player> viewers) {
|
||||||
armorStand.setLocation(location, viewers);
|
entity.setLocation(location, viewers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEntityId() {
|
||||||
|
return entity.getEntityId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> void addProperty(EntityProperty<T> property) {
|
||||||
|
properties.add(property);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T getProperty(EntityProperty<T> key) {
|
public <T> T getProperty(EntityProperty<T> key) {
|
||||||
if (key.getName().equalsIgnoreCase("invisible")) return (T) Boolean.TRUE;
|
|
||||||
if (key.getName().equalsIgnoreCase("name")) return (T) text;
|
|
||||||
return key.getDefaultValue();
|
return key.getDefaultValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasProperty(EntityProperty<?> key) {
|
public boolean hasProperty(EntityProperty<?> key) {
|
||||||
return key.getName().equalsIgnoreCase("name") || key.getName().equalsIgnoreCase("invisible");
|
return properties.contains(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> void setProperty(EntityProperty<T> key, T value) {
|
public <T> void setProperty(EntityProperty<T> key, T value) {
|
||||||
throw new UnsupportedOperationException("Can't set properties on a hologram");
|
throw new UnsupportedOperationException("Can't set properties on a hologram line");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<EntityProperty<?>> getAppliedProperties() {
|
||||||
|
return properties;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package lol.pyr.znpcsplus.hologram;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||||
|
import lol.pyr.znpcsplus.api.entity.EntityProperty;
|
||||||
|
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
|
||||||
|
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||||
|
import lol.pyr.znpcsplus.util.NpcLocation;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
|
||||||
|
public class HologramText extends HologramLine<Component> {
|
||||||
|
|
||||||
|
public HologramText(EntityPropertyRegistryImpl propertyRegistry, PacketFactory packetFactory, NpcLocation location, Component text) {
|
||||||
|
super(text, packetFactory, EntityTypes.ARMOR_STAND, location);
|
||||||
|
addProperty(propertyRegistry.getByName("name"));
|
||||||
|
addProperty(propertyRegistry.getByName("invisible"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public <T> T getProperty(EntityProperty<T> key) {
|
||||||
|
if (key.getName().equalsIgnoreCase("invisible")) return (T) Boolean.TRUE;
|
||||||
|
if (key.getName().equalsIgnoreCase("name")) return (T) getValue();
|
||||||
|
return super.getProperty(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasProperty(EntityProperty<?> key) {
|
||||||
|
return key.getName().equalsIgnoreCase("name") || key.getName().equalsIgnoreCase("invisible");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,102 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.metadata;
|
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
|
|
||||||
import lol.pyr.znpcsplus.util.*;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import org.bukkit.DyeColor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1.8 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=7415">...</a>
|
|
||||||
* 1.9 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=7968">...</a>
|
|
||||||
* 1.10 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=8241">...</a>
|
|
||||||
* 1.11 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=8534">...</a>
|
|
||||||
* 1.12 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=14048">...</a>
|
|
||||||
* 1.13 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=14800">...</a>
|
|
||||||
* 1.14 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=15240">...</a>
|
|
||||||
* 1.15 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=15991">...</a>
|
|
||||||
* 1.16 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=16539">...</a>
|
|
||||||
* 1.17 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=17521">...</a>
|
|
||||||
* 1.18-1.19 <a href="https://wiki.vg/index.php?title=Entity_metadata&oldid=18191">...</a>
|
|
||||||
* 1.20 <a href="https://wiki.vg/index.php?title=Entity_metadata">...</a>
|
|
||||||
*/
|
|
||||||
public interface MetadataFactory {
|
|
||||||
EntityData effects(boolean onFire, boolean glowing, boolean invisible, boolean usingElytra, boolean usingItemLegacy);
|
|
||||||
EntityData silent(boolean enabled);
|
|
||||||
EntityData name(Component name);
|
|
||||||
EntityData nameShown();
|
|
||||||
EntityData noGravity();
|
|
||||||
EntityData pose(EntityPose pose);
|
|
||||||
EntityData shaking(boolean enabled);
|
|
||||||
EntityData usingItem(boolean enabled, boolean offhand, boolean riptide);
|
|
||||||
EntityData potionColor(int color);
|
|
||||||
EntityData potionAmbient(boolean ambient);
|
|
||||||
|
|
||||||
// Player
|
|
||||||
EntityData skinLayers(boolean cape, boolean jacket, boolean leftSleeve, boolean rightSleeve, boolean leftLeg, boolean rightLeg, boolean hat);
|
|
||||||
EntityData shoulderEntityLeft(ParrotVariant variant);
|
|
||||||
EntityData shoulderEntityRight(ParrotVariant variant);
|
|
||||||
|
|
||||||
// Armor Stand
|
|
||||||
EntityData armorStandProperties(boolean small, boolean arms, boolean noBasePlate);
|
|
||||||
EntityData armorStandHeadRotation(Vector3f headRotation);
|
|
||||||
EntityData armorStandBodyRotation(Vector3f bodyRotation);
|
|
||||||
EntityData armorStandLeftArmRotation(Vector3f leftArmRotation);
|
|
||||||
EntityData armorStandRightArmRotation(Vector3f rightArmRotation);
|
|
||||||
EntityData armorStandLeftLegRotation(Vector3f leftLegRotation);
|
|
||||||
EntityData armorStandRightLegRotation(Vector3f rightLegRotation);
|
|
||||||
|
|
||||||
// Axolotl
|
|
||||||
EntityData axolotlVariant(int variant);
|
|
||||||
EntityData playingDead(boolean playingDead);
|
|
||||||
|
|
||||||
// Bat
|
|
||||||
EntityData batHanging(boolean hanging);
|
|
||||||
|
|
||||||
// Bee
|
|
||||||
EntityData beeAngry(boolean angry);
|
|
||||||
EntityData beeHasNectar(boolean hasNectar);
|
|
||||||
|
|
||||||
// Blaze
|
|
||||||
EntityData blazeOnFire(boolean onFire);
|
|
||||||
|
|
||||||
// Cat
|
|
||||||
EntityData catVariant(CatVariant variant);
|
|
||||||
EntityData catLying(boolean lying);
|
|
||||||
EntityData catTamed(boolean tamed);
|
|
||||||
EntityData catCollarColor(DyeColor collarColor);
|
|
||||||
|
|
||||||
// Creeper
|
|
||||||
EntityData creeperState(CreeperState state);
|
|
||||||
EntityData creeperCharged(boolean charged);
|
|
||||||
|
|
||||||
// Enderman
|
|
||||||
EntityData endermanHeldBlock(int heldBlock);
|
|
||||||
EntityData endermanScreaming(boolean screaming);
|
|
||||||
EntityData endermanStaring(boolean staring);
|
|
||||||
|
|
||||||
// Evoker
|
|
||||||
EntityData evokerSpell(int spell);
|
|
||||||
|
|
||||||
// Fox
|
|
||||||
EntityData foxVariant(int variant);
|
|
||||||
EntityData foxProperties(boolean sitting, boolean crouching, boolean sleeping, boolean facePlanted);
|
|
||||||
|
|
||||||
// Frog
|
|
||||||
EntityData frogVariant(int variant);
|
|
||||||
|
|
||||||
// Ghast
|
|
||||||
EntityData ghastAttacking(boolean attacking);
|
|
||||||
|
|
||||||
// Goat
|
|
||||||
EntityData goatHasLeftHorn(boolean hasLeftHorn);
|
|
||||||
EntityData goatHasRightHorn(boolean hasRightHorn);
|
|
||||||
|
|
||||||
// Guardian
|
|
||||||
|
|
||||||
// Hoglin
|
|
||||||
EntityData hoglinImmuneToZombification(boolean immuneToZombification);
|
|
||||||
|
|
||||||
// Villager
|
|
||||||
EntityData villagerData(int type, int profession, int level);
|
|
||||||
}
|
|
|
@ -1,93 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.metadata;
|
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
|
||||||
import lol.pyr.znpcsplus.util.CreeperState;
|
|
||||||
import lol.pyr.znpcsplus.util.Vector3f;
|
|
||||||
|
|
||||||
public class V1_10MetadataFactory extends V1_9MetadataFactory {
|
|
||||||
@Override
|
|
||||||
public EntityData skinLayers(boolean cape, boolean jacket, boolean leftSleeve, boolean rightSleeve, boolean leftLeg, boolean rightLeg, boolean hat) {
|
|
||||||
return createSkinLayers(13, cape, jacket, leftSleeve, rightSleeve, leftLeg, rightLeg, hat);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData noGravity() {
|
|
||||||
return newEntityData(5, EntityDataTypes.BOOLEAN, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData potionColor(int color) {
|
|
||||||
return newEntityData(8, EntityDataTypes.INT, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData potionAmbient(boolean ambient) {
|
|
||||||
return newEntityData(9, EntityDataTypes.BOOLEAN, ambient);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandProperties(boolean small, boolean arms, boolean noBasePlate) {
|
|
||||||
return newEntityData(11, EntityDataTypes.BYTE, (byte) ((small ? 0x01 : 0) | (arms ? 0x04 : 0) | (noBasePlate ? 0x08 : 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandHeadRotation(Vector3f headRotation) {
|
|
||||||
return createRotations(12, headRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandBodyRotation(Vector3f bodyRotation) {
|
|
||||||
return createRotations(13, bodyRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandLeftArmRotation(Vector3f leftArmRotation) {
|
|
||||||
return createRotations(14, leftArmRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandRightArmRotation(Vector3f rightArmRotation) {
|
|
||||||
return createRotations(15, rightArmRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandLeftLegRotation(Vector3f leftLegRotation) {
|
|
||||||
return createRotations(16, leftLegRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandRightLegRotation(Vector3f rightLegRotation) {
|
|
||||||
return createRotations(17, rightLegRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData batHanging(boolean hanging) {
|
|
||||||
return newEntityData(12, EntityDataTypes.BYTE, (byte) (hanging ? 0x01 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData blazeOnFire(boolean onFire) {
|
|
||||||
return newEntityData(12, EntityDataTypes.BYTE, (byte) (onFire ? 0x01 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData creeperState(CreeperState state) {
|
|
||||||
return newEntityData(12, EntityDataTypes.INT, state.getState());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData creeperCharged(boolean charged) {
|
|
||||||
return newEntityData(13, EntityDataTypes.BOOLEAN, charged);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData ghastAttacking(boolean attacking) {
|
|
||||||
return newEntityData(12, EntityDataTypes.BOOLEAN, attacking);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData villagerData(int type, int profession, int level) {
|
|
||||||
return newEntityData(13, EntityDataTypes.INT, profession);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.metadata;
|
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
|
||||||
|
|
||||||
public class V1_11MetadataFactory extends V1_10MetadataFactory {
|
|
||||||
@Override
|
|
||||||
public EntityData effects(boolean onFire, boolean glowing, boolean invisible, boolean usingElytra, boolean usingItemLegacy) {
|
|
||||||
return super.effects(onFire, glowing, invisible, usingElytra, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData usingItem(boolean usingItem, boolean offHand, boolean riptide) {
|
|
||||||
return newEntityData(6, EntityDataTypes.BYTE, (byte) ((usingItem ? 0x01 : 0) | (offHand ? 0x02 : 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData evokerSpell(int spell) {
|
|
||||||
return newEntityData(12, EntityDataTypes.BYTE, (byte) spell);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.metadata;
|
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
|
||||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
|
||||||
import lol.pyr.znpcsplus.entity.ParrotNBTCompound;
|
|
||||||
import lol.pyr.znpcsplus.util.ParrotVariant;
|
|
||||||
|
|
||||||
public class V1_12MetadataFactory extends V1_11MetadataFactory {
|
|
||||||
@Override
|
|
||||||
public EntityData shoulderEntityLeft(ParrotVariant variant) {
|
|
||||||
return createShoulderEntityLeft(15, variant);
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityData createShoulderEntityLeft(int index, ParrotVariant variant) {
|
|
||||||
return newEntityData(index, EntityDataTypes.NBT, variant == ParrotVariant.NONE ? new NBTCompound() : new ParrotNBTCompound(variant).getTag());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData shoulderEntityRight(ParrotVariant variant) {
|
|
||||||
return createShoulderEntityRight(16, variant);
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityData createShoulderEntityRight(int index, ParrotVariant variant) {
|
|
||||||
return newEntityData(index, EntityDataTypes.NBT, variant == ParrotVariant.NONE ? new NBTCompound() : new ParrotNBTCompound(variant).getTag());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData evokerSpell(int spell) {
|
|
||||||
return newEntityData(13, EntityDataTypes.BYTE, (byte) spell);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.metadata;
|
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
|
||||||
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class V1_13MetadataFactory extends V1_12MetadataFactory {
|
|
||||||
@Override
|
|
||||||
public EntityData name(Component name) {
|
|
||||||
return newEntityData(2, EntityDataTypes.OPTIONAL_COMPONENT, Optional.of(AdventureSerializer.getGsonSerializer().serialize(name)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData usingItem(boolean usingItem, boolean offHand, boolean riptide) {
|
|
||||||
return newEntityData(6, EntityDataTypes.BYTE, (byte) ((usingItem ? 0x01 : 0) | (offHand ? 0x02 : 0) | (riptide ? 0x04 : 0)));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,143 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.metadata;
|
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.villager.VillagerData;
|
|
||||||
import lol.pyr.znpcsplus.util.CatVariant;
|
|
||||||
import lol.pyr.znpcsplus.util.CreeperState;
|
|
||||||
import lol.pyr.znpcsplus.util.ParrotVariant;
|
|
||||||
import lol.pyr.znpcsplus.util.Vector3f;
|
|
||||||
import org.bukkit.DyeColor;
|
|
||||||
|
|
||||||
public class V1_14MetadataFactory extends V1_13MetadataFactory {
|
|
||||||
@Override
|
|
||||||
public EntityData skinLayers(boolean cape, boolean jacket, boolean leftSleeve, boolean rightSleeve, boolean leftLeg, boolean rightLeg, boolean hat) {
|
|
||||||
return createSkinLayers(15, cape, jacket, leftSleeve, rightSleeve, leftLeg, rightLeg, hat);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData pose(EntityPose pose) {
|
|
||||||
return newEntityData(6, EntityDataTypes.ENTITY_POSE, pose);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData usingItem(boolean usingItem, boolean offHand, boolean riptide) {
|
|
||||||
return newEntityData(7, EntityDataTypes.BYTE, (byte) ((usingItem ? 0x01 : 0) | (offHand ? 0x02 : 0) | (riptide ? 0x04 : 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData potionColor(int color) {
|
|
||||||
return newEntityData(9, EntityDataTypes.INT, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData potionAmbient(boolean ambient) {
|
|
||||||
return newEntityData(10, EntityDataTypes.BOOLEAN, ambient);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData shoulderEntityLeft(ParrotVariant variant) {
|
|
||||||
return createShoulderEntityLeft(17, variant);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData shoulderEntityRight(ParrotVariant variant) {
|
|
||||||
return createShoulderEntityRight(18, variant);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandProperties(boolean small, boolean arms, boolean noBasePlate) {
|
|
||||||
return newEntityData(13, EntityDataTypes.BYTE, (byte) ((small ? 0x01 : 0) | (arms ? 0x04 : 0) | (noBasePlate ? 0x08 : 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandHeadRotation(Vector3f headRotation) {
|
|
||||||
return createRotations(14, headRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandBodyRotation(Vector3f bodyRotation) {
|
|
||||||
return createRotations(15, bodyRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandLeftArmRotation(Vector3f leftArmRotation) {
|
|
||||||
return createRotations(16, leftArmRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandRightArmRotation(Vector3f rightArmRotation) {
|
|
||||||
return createRotations(17, rightArmRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandLeftLegRotation(Vector3f leftLegRotation) {
|
|
||||||
return createRotations(18, leftLegRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandRightLegRotation(Vector3f rightLegRotation) {
|
|
||||||
return createRotations(19, rightLegRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData batHanging(boolean hanging) {
|
|
||||||
return newEntityData(14, EntityDataTypes.BYTE, (byte) (hanging ? 0x01 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData blazeOnFire(boolean onFire) {
|
|
||||||
return newEntityData(14, EntityDataTypes.BYTE, (byte) (onFire ? 0x01 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData catVariant(CatVariant variant) {
|
|
||||||
return newEntityData(17, EntityDataTypes.CAT_VARIANT, variant.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData catLying(boolean lying) {
|
|
||||||
throw new UnsupportedOperationException("The cat lying entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData catCollarColor(DyeColor collarColor) {
|
|
||||||
return newEntityData(20, EntityDataTypes.INT, collarColor.ordinal());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData creeperState(CreeperState state) {
|
|
||||||
return newEntityData(14, EntityDataTypes.INT, state.getState());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData creeperCharged(boolean charged) {
|
|
||||||
return newEntityData(15, EntityDataTypes.BOOLEAN, charged);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData evokerSpell(int spell) {
|
|
||||||
return newEntityData(15, EntityDataTypes.BYTE, (byte) spell);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData foxVariant(int variant) {
|
|
||||||
return newEntityData(15, EntityDataTypes.INT, variant);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData foxProperties(boolean sitting, boolean crouching, boolean sleeping, boolean facePlanted) {
|
|
||||||
return newEntityData(16, EntityDataTypes.BYTE, (byte) ((sitting ? 0x01 : 0) | (crouching ? 0x04 : 0) | (sleeping ? 0x20 : 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData ghastAttacking(boolean attacking) {
|
|
||||||
return newEntityData(14, EntityDataTypes.BOOLEAN, attacking);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData villagerData(int type, int profession, int level) {
|
|
||||||
return newEntityData(16, EntityDataTypes.VILLAGER_DATA, new VillagerData(type, profession, level));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,127 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.metadata;
|
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.villager.VillagerData;
|
|
||||||
import lol.pyr.znpcsplus.util.CatVariant;
|
|
||||||
import lol.pyr.znpcsplus.util.CreeperState;
|
|
||||||
import lol.pyr.znpcsplus.util.ParrotVariant;
|
|
||||||
import lol.pyr.znpcsplus.util.Vector3f;
|
|
||||||
import org.bukkit.DyeColor;
|
|
||||||
|
|
||||||
public class V1_15MetadataFactory extends V1_14MetadataFactory {
|
|
||||||
@Override
|
|
||||||
public EntityData shoulderEntityLeft(ParrotVariant variant) {
|
|
||||||
return createShoulderEntityLeft(18, variant);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData shoulderEntityRight(ParrotVariant variant) {
|
|
||||||
return createShoulderEntityRight(19, variant);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandProperties(boolean small, boolean arms, boolean noBasePlate) {
|
|
||||||
return newEntityData(14, EntityDataTypes.BYTE, (byte) ((small ? 0x01 : 0) | (arms ? 0x04 : 0) | (!noBasePlate ? 0x08 : 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandHeadRotation(Vector3f headRotation) {
|
|
||||||
return createRotations(15, headRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandBodyRotation(Vector3f bodyRotation) {
|
|
||||||
return createRotations(16, bodyRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandLeftArmRotation(Vector3f leftArmRotation) {
|
|
||||||
return createRotations(17, leftArmRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandRightArmRotation(Vector3f rightArmRotation) {
|
|
||||||
return createRotations(18, rightArmRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandLeftLegRotation(Vector3f leftLegRotation) {
|
|
||||||
return createRotations(19, leftLegRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandRightLegRotation(Vector3f rightLegRotation) {
|
|
||||||
return createRotations(20, rightLegRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData batHanging(boolean hanging) {
|
|
||||||
return newEntityData(15, EntityDataTypes.BYTE, (byte) (hanging ? 0x01 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData beeAngry(boolean angry) {
|
|
||||||
return newEntityData(17, EntityDataTypes.INT, angry ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData beeHasNectar(boolean hasNectar) {
|
|
||||||
return newEntityData(16, EntityDataTypes.BYTE, (byte) (hasNectar ? 0x08 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData blazeOnFire(boolean onFire) {
|
|
||||||
return newEntityData(15, EntityDataTypes.BYTE, (byte) (onFire ? 0x01 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData catVariant(CatVariant variant) {
|
|
||||||
return newEntityData(18, EntityDataTypes.CAT_VARIANT, variant.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData catLying(boolean lying) {
|
|
||||||
return newEntityData(19, EntityDataTypes.BOOLEAN, lying);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData catCollarColor(DyeColor collarColor) {
|
|
||||||
return newEntityData(21, EntityDataTypes.INT, collarColor.ordinal());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData creeperState(CreeperState state) {
|
|
||||||
return newEntityData(15, EntityDataTypes.INT, state.getState());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData creeperCharged(boolean charged) {
|
|
||||||
return newEntityData(16, EntityDataTypes.BOOLEAN, charged);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData evokerSpell(int spell) {
|
|
||||||
return newEntityData(16, EntityDataTypes.BYTE, (byte) spell);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData foxVariant(int variant) {
|
|
||||||
return newEntityData(16, EntityDataTypes.INT, variant);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData foxProperties(boolean sitting, boolean crouching, boolean sleeping, boolean facePlanted) {
|
|
||||||
return newEntityData(17, EntityDataTypes.BYTE, (byte) ((sitting ? 0x01 : 0) | (crouching ? 0x04 : 0) | (sleeping ? 0x20 : 0) | (facePlanted ? 0x40 : 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData ghastAttacking(boolean attacking) {
|
|
||||||
return newEntityData(15, EntityDataTypes.BOOLEAN, attacking);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData villagerData(int type, int profession, int level) {
|
|
||||||
return newEntityData(17, EntityDataTypes.VILLAGER_DATA, new VillagerData(type, profession, level));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.metadata;
|
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
|
||||||
|
|
||||||
public class V1_16MetadataFactory extends V1_15MetadataFactory {
|
|
||||||
@Override
|
|
||||||
public EntityData skinLayers(boolean cape, boolean jacket, boolean leftSleeve, boolean rightSleeve, boolean leftLeg, boolean rightLeg, boolean hat) {
|
|
||||||
return createSkinLayers(16, cape, jacket, leftSleeve, rightSleeve, leftLeg, rightLeg, hat);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData hoglinImmuneToZombification(boolean immuneToZombification) {
|
|
||||||
return newEntityData(16, EntityDataTypes.BOOLEAN, immuneToZombification);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,202 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.metadata;
|
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.villager.VillagerData;
|
|
||||||
import lol.pyr.znpcsplus.util.CatVariant;
|
|
||||||
import lol.pyr.znpcsplus.util.CreeperState;
|
|
||||||
import lol.pyr.znpcsplus.util.ParrotVariant;
|
|
||||||
import lol.pyr.znpcsplus.util.Vector3f;
|
|
||||||
import org.bukkit.DyeColor;
|
|
||||||
|
|
||||||
public class V1_17MetadataFactory extends V1_16MetadataFactory {
|
|
||||||
@Override
|
|
||||||
public EntityData skinLayers(boolean cape, boolean jacket, boolean leftSleeve, boolean rightSleeve, boolean leftLeg, boolean rightLeg, boolean hat) {
|
|
||||||
return createSkinLayers(17, cape, jacket, leftSleeve, rightSleeve, leftLeg, rightLeg, hat);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData effects(boolean onFire, boolean glowing, boolean invisible, boolean usingElytra, boolean usingItemLegacy) {
|
|
||||||
return newEntityData(0, EntityDataTypes.BYTE, (byte) ((onFire ? 0x01 : 0) | (invisible ? 0x20 : 0) | (glowing ? 0x40 : 0) | (usingElytra ? 0x80 : 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData shaking(boolean enabled) {
|
|
||||||
return newEntityData(7, EntityDataTypes.INT, enabled ? 140 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData usingItem(boolean usingItem, boolean offHand, boolean riptide) {
|
|
||||||
return newEntityData(8, EntityDataTypes.BYTE, (byte) ((usingItem ? 0x01 : 0) | (offHand ? 0x02 : 0) | (riptide ? 0x04 : 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData potionColor(int color) {
|
|
||||||
return newEntityData(10, EntityDataTypes.INT, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData potionAmbient(boolean ambient) {
|
|
||||||
return newEntityData(11, EntityDataTypes.BOOLEAN, ambient);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData shoulderEntityLeft(ParrotVariant variant) {
|
|
||||||
return createShoulderEntityLeft(19, variant);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData shoulderEntityRight(ParrotVariant variant) {
|
|
||||||
return createShoulderEntityRight(20, variant);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandProperties(boolean small, boolean arms, boolean noBasePlate) {
|
|
||||||
return newEntityData(15, EntityDataTypes.BYTE, (byte) ((small ? 0x01 : 0) | (arms ? 0x04 : 0) | (noBasePlate ? 0x08 : 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandHeadRotation(Vector3f headRotation) {
|
|
||||||
return createRotations(16, headRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandBodyRotation(Vector3f bodyRotation) {
|
|
||||||
return createRotations(17, bodyRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandLeftArmRotation(Vector3f leftArmRotation) {
|
|
||||||
return createRotations(18, leftArmRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandRightArmRotation(Vector3f rightArmRotation) {
|
|
||||||
return createRotations(19, rightArmRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandLeftLegRotation(Vector3f leftLegRotation) {
|
|
||||||
return createRotations(20, leftLegRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandRightLegRotation(Vector3f rightLegRotation) {
|
|
||||||
return createRotations(21, rightLegRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData axolotlVariant(int variant) {
|
|
||||||
return newEntityData(17, EntityDataTypes.INT, variant);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData playingDead(boolean playingDead) {
|
|
||||||
return newEntityData(18, EntityDataTypes.BOOLEAN, playingDead);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData batHanging(boolean hanging) {
|
|
||||||
return newEntityData(16, EntityDataTypes.BYTE, (byte) (hanging ? 0x01 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData beeAngry(boolean angry) {
|
|
||||||
return newEntityData(18, EntityDataTypes.INT, angry ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData beeHasNectar(boolean hasNectar) {
|
|
||||||
return newEntityData(17, EntityDataTypes.BYTE, (byte) (hasNectar ? 0x08 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData blazeOnFire(boolean onFire) {
|
|
||||||
return newEntityData(16, EntityDataTypes.BYTE, (byte) (onFire ? 0x01 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData catVariant(CatVariant variant) {
|
|
||||||
return newEntityData(19, EntityDataTypes.CAT_VARIANT, variant.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData catLying(boolean lying) {
|
|
||||||
return newEntityData(20, EntityDataTypes.BOOLEAN, lying);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData catTamed(boolean tamed) {
|
|
||||||
return newEntityData(17, EntityDataTypes.BYTE, (byte) (tamed ? 0x04 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData catCollarColor(DyeColor collarColor) {
|
|
||||||
return newEntityData(22, EntityDataTypes.INT, collarColor.ordinal());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData creeperState(CreeperState state) {
|
|
||||||
return newEntityData(16, EntityDataTypes.INT, state.getState());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData creeperCharged(boolean charged) {
|
|
||||||
return newEntityData(17, EntityDataTypes.BOOLEAN, charged);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData endermanHeldBlock(int carriedBlock) {
|
|
||||||
return newEntityData(16, EntityDataTypes.INT, carriedBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData endermanScreaming(boolean screaming) {
|
|
||||||
return newEntityData(17, EntityDataTypes.BOOLEAN, screaming);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData endermanStaring(boolean staring) {
|
|
||||||
return newEntityData(18, EntityDataTypes.BOOLEAN, staring);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData evokerSpell(int spell) {
|
|
||||||
return newEntityData(17, EntityDataTypes.BYTE, (byte) spell);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData foxVariant(int variant) {
|
|
||||||
return newEntityData(17, EntityDataTypes.INT, variant);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData foxProperties(boolean sitting, boolean crouching, boolean sleeping, boolean facePlanted) {
|
|
||||||
return newEntityData(18, EntityDataTypes.BYTE, (byte) ((sitting ? 0x01 : 0) | (crouching ? 0x04 : 0) | (sleeping ? 0x20 : 0) | (facePlanted ? 0x40 : 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData ghastAttacking(boolean attacking) {
|
|
||||||
return newEntityData(16, EntityDataTypes.BOOLEAN, attacking);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData goatHasLeftHorn(boolean hasLeftHorn) {
|
|
||||||
return newEntityData(18, EntityDataTypes.BOOLEAN, hasLeftHorn);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData goatHasRightHorn(boolean hasRightHorn) {
|
|
||||||
return newEntityData(19, EntityDataTypes.BOOLEAN, hasRightHorn);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData hoglinImmuneToZombification(boolean immuneToZombification) {
|
|
||||||
return newEntityData(17, EntityDataTypes.BOOLEAN, immuneToZombification);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData villagerData(int type, int profession, int level) {
|
|
||||||
return newEntityData(18, EntityDataTypes.VILLAGER_DATA, new VillagerData(type, profession, level));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.metadata;
|
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
|
||||||
import lol.pyr.znpcsplus.util.FrogVariant;
|
|
||||||
|
|
||||||
public class V1_19MetadataFactory extends V1_17MetadataFactory {
|
|
||||||
@Override
|
|
||||||
public EntityData frogVariant(int variant) {
|
|
||||||
return newEntityData(17, EntityDataTypes.FROG_VARIANT, variant);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,252 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.metadata;
|
|
||||||
|
|
||||||
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.entity.pose.EntityPose;
|
|
||||||
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
|
|
||||||
import lol.pyr.znpcsplus.util.*;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import org.bukkit.DyeColor;
|
|
||||||
|
|
||||||
public class V1_8MetadataFactory implements MetadataFactory {
|
|
||||||
@Override
|
|
||||||
public EntityData skinLayers(boolean cape, boolean jacket, boolean leftSleeve, boolean rightSleeve, boolean leftLeg, boolean rightLeg, boolean hat) {
|
|
||||||
return createSkinLayers(10, cape, jacket, leftSleeve, rightSleeve, leftLeg, rightLeg, hat);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData effects(boolean onFire, boolean glowing, boolean invisible, boolean usingElytra, boolean usingItemLegacy) {
|
|
||||||
return newEntityData(0, EntityDataTypes.BYTE, (byte) ((onFire ? 0x01 : 0) | (usingItemLegacy ? 0x10 : 0) | (invisible ? 0x20 : 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData name(Component name) {
|
|
||||||
return newEntityData(2, EntityDataTypes.STRING, AdventureSerializer.getLegacyGsonSerializer().serialize(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData nameShown() {
|
|
||||||
return newEntityData(3, EntityDataTypes.BYTE, (byte) 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData noGravity() {
|
|
||||||
throw new UnsupportedOperationException("The gravity entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData pose(EntityPose pose) {
|
|
||||||
throw new UnsupportedOperationException("The pose entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData shaking(boolean enabled) {
|
|
||||||
throw new UnsupportedOperationException("The shaking entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData usingItem(boolean enabled, boolean offHand, boolean riptide) {
|
|
||||||
throw new UnsupportedOperationException("The standalone using item data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData potionColor(int color) {
|
|
||||||
return newEntityData(7, EntityDataTypes.INT, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData potionAmbient(boolean ambient) {
|
|
||||||
return newEntityData(8, EntityDataTypes.BYTE, (byte) (ambient ? 1 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData shoulderEntityLeft(ParrotVariant variant) {
|
|
||||||
throw new UnsupportedOperationException("The shoulder entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData shoulderEntityRight(ParrotVariant variant) {
|
|
||||||
throw new UnsupportedOperationException("The shoulder entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandProperties(boolean small, boolean arms, boolean noBasePlate) {
|
|
||||||
return newEntityData(10, EntityDataTypes.BYTE, (byte) ((small ? 0x01 : 0) | (arms ? 0x04 : 0) | (noBasePlate ? 0x08 : 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandHeadRotation(Vector3f headRotation) {
|
|
||||||
return createRotations(11, headRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandBodyRotation(Vector3f bodyRotation) {
|
|
||||||
return createRotations(12, bodyRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandLeftArmRotation(Vector3f leftArmRotation) {
|
|
||||||
return createRotations(13, leftArmRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandRightArmRotation(Vector3f rightArmRotation) {
|
|
||||||
return createRotations(14, rightArmRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandLeftLegRotation(Vector3f leftLegRotation) {
|
|
||||||
return createRotations(15, leftLegRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData armorStandRightLegRotation(Vector3f rightLegRotation) {
|
|
||||||
return createRotations(16, rightLegRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData axolotlVariant(int variant) {
|
|
||||||
throw new UnsupportedOperationException("The axolotl variant entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData playingDead(boolean playingDead) {
|
|
||||||
throw new UnsupportedOperationException("The playing dead entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData batHanging(boolean hanging) {
|
|
||||||
return newEntityData(16, EntityDataTypes.BYTE, (byte) (hanging ? 1 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData beeAngry(boolean angry) {
|
|
||||||
throw new UnsupportedOperationException("The bee properties entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData beeHasNectar(boolean hasNectar) {
|
|
||||||
throw new UnsupportedOperationException("The bee properties entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData blazeOnFire(boolean onFire) {
|
|
||||||
return newEntityData(16, EntityDataTypes.BYTE, (byte) (onFire ? 1 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData catVariant(CatVariant variant) {
|
|
||||||
throw new UnsupportedOperationException("The cat variant entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData catLying(boolean lying) {
|
|
||||||
throw new UnsupportedOperationException("The cat lying entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData catTamed(boolean tamed) {
|
|
||||||
throw new UnsupportedOperationException("The cat tamed entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData catCollarColor(DyeColor collarColor) {
|
|
||||||
throw new UnsupportedOperationException("The cat collar color entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData creeperState(CreeperState state) {
|
|
||||||
return newEntityData(16, EntityDataTypes.BYTE, (byte) state.getState());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData creeperCharged(boolean charged) {
|
|
||||||
return newEntityData(17, EntityDataTypes.BYTE, (byte) (charged ? 1 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData endermanHeldBlock(int carriedBlock) {
|
|
||||||
throw new UnsupportedOperationException("The enderman carried block entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData endermanScreaming(boolean screaming) {
|
|
||||||
throw new UnsupportedOperationException("The enderman screaming entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData endermanStaring(boolean staring) {
|
|
||||||
return newEntityData(18, EntityDataTypes.BOOLEAN, staring);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData evokerSpell(int spell) {
|
|
||||||
throw new UnsupportedOperationException("The evoker spell entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData foxVariant(int variant) {
|
|
||||||
throw new UnsupportedOperationException("The fox variant entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData foxProperties(boolean sitting, boolean crouching, boolean sleeping, boolean facePlanted) {
|
|
||||||
throw new UnsupportedOperationException("The fox properties entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData frogVariant(int variant) {
|
|
||||||
throw new UnsupportedOperationException("The frog variant entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData ghastAttacking(boolean attacking) {
|
|
||||||
return newEntityData(16, EntityDataTypes.BYTE, (byte) (attacking ? 1 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData goatHasLeftHorn(boolean hasLeftHorn) {
|
|
||||||
throw new UnsupportedOperationException("The goat horn entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData goatHasRightHorn(boolean hasRightHorn) {
|
|
||||||
throw new UnsupportedOperationException("The goat horn entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData hoglinImmuneToZombification(boolean immuneToZombification) {
|
|
||||||
throw new UnsupportedOperationException("The hoglin zombification entity data isn't supported on this version");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData villagerData(int type, int profession, int level) {
|
|
||||||
return newEntityData(16, EntityDataTypes.INT, profession);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData silent(boolean enabled) {
|
|
||||||
return newEntityData(4, EntityDataTypes.BYTE, (byte) (enabled ? 1 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected EntityData createSkinLayers(int index, boolean cape, boolean jacket, boolean leftSleeve, boolean rightSleeve, boolean leftLeg, boolean rightLeg, boolean hat) {
|
|
||||||
return newEntityData(index, EntityDataTypes.BYTE, (byte) (
|
|
||||||
(cape ? 0x01 : 0) |
|
|
||||||
(jacket ? 0x02 : 0) |
|
|
||||||
(leftSleeve ? 0x04 : 0) |
|
|
||||||
(rightSleeve ? 0x08 : 0) |
|
|
||||||
(leftLeg ? 0x10 : 0) |
|
|
||||||
(rightLeg ? 0x20 : 0) |
|
|
||||||
(hat ? 0x40 : 0))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected <T> EntityData newEntityData(int index, EntityDataType<T> type, T value) {
|
|
||||||
return new EntityData(index, type, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected EntityData createRotations(int index, Vector3f rotations) {
|
|
||||||
return newEntityData(index, EntityDataTypes.ROTATION, new com.github.retrooper.packetevents.util.Vector3f(rotations.getX(), rotations.getY(), rotations.getZ()));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.metadata;
|
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
|
||||||
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
|
|
||||||
import lol.pyr.znpcsplus.util.CreeperState;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
|
|
||||||
public class V1_9MetadataFactory extends V1_8MetadataFactory {
|
|
||||||
@Override
|
|
||||||
public EntityData skinLayers(boolean cape, boolean jacket, boolean leftSleeve, boolean rightSleeve, boolean leftLeg, boolean rightLeg, boolean hat) {
|
|
||||||
return createSkinLayers(12, cape, jacket, leftSleeve, rightSleeve, leftLeg, rightLeg, hat);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData effects(boolean onFire, boolean glowing, boolean invisible, boolean usingElytra, boolean usingItemLegacy) {
|
|
||||||
return newEntityData(0, EntityDataTypes.BYTE, (byte) (
|
|
||||||
(onFire ? 0x01 : 0) |
|
|
||||||
(usingItemLegacy ? 0x10 : 0) |
|
|
||||||
(invisible ? 0x20 : 0) |
|
|
||||||
(glowing ? 0x40 : 0) |
|
|
||||||
(usingElytra ? 0x80 : 0)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData potionAmbient(boolean ambient) {
|
|
||||||
return newEntityData(8, EntityDataTypes.BOOLEAN, ambient);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData batHanging(boolean hanging) {
|
|
||||||
return newEntityData(11, EntityDataTypes.BYTE, (byte) (hanging ? 0x01 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData blazeOnFire(boolean onFire) {
|
|
||||||
return newEntityData(16, EntityDataTypes.BYTE, (byte) (onFire ? 1 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData creeperState(CreeperState state) {
|
|
||||||
return newEntityData(11, EntityDataTypes.INT, state.getState());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData creeperCharged(boolean charged) {
|
|
||||||
return newEntityData(12, EntityDataTypes.BOOLEAN, charged);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData name(Component name) {
|
|
||||||
return newEntityData(2, EntityDataTypes.STRING, AdventureSerializer.getGsonSerializer().serialize(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData nameShown() {
|
|
||||||
return newEntityData(3, EntityDataTypes.BOOLEAN, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData silent(boolean enabled) {
|
|
||||||
return newEntityData(4, EntityDataTypes.BOOLEAN, enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData ghastAttacking(boolean attacking) {
|
|
||||||
return newEntityData(11, EntityDataTypes.BOOLEAN, attacking);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityData villagerData(int type, int profession, int level) {
|
|
||||||
return newEntityData(12, EntityDataTypes.INT, profession);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +1,12 @@
|
||||||
package lol.pyr.znpcsplus.npc;
|
package lol.pyr.znpcsplus.npc;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||||
import lol.pyr.znpcsplus.api.entity.EntityProperty;
|
import lol.pyr.znpcsplus.api.entity.EntityProperty;
|
||||||
import lol.pyr.znpcsplus.api.npc.Npc;
|
import lol.pyr.znpcsplus.api.npc.Npc;
|
||||||
import lol.pyr.znpcsplus.api.npc.NpcType;
|
import lol.pyr.znpcsplus.api.npc.NpcType;
|
||||||
import lol.pyr.znpcsplus.config.ConfigManager;
|
import lol.pyr.znpcsplus.config.ConfigManager;
|
||||||
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
|
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
|
||||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
||||||
import lol.pyr.znpcsplus.interaction.InteractionActionImpl;
|
import lol.pyr.znpcsplus.interaction.InteractionActionImpl;
|
||||||
|
@ -32,18 +34,18 @@ public class NpcImpl extends Viewable implements Npc {
|
||||||
private final Map<EntityPropertyImpl<?>, Object> propertyMap = new HashMap<>();
|
private final Map<EntityPropertyImpl<?>, Object> propertyMap = new HashMap<>();
|
||||||
private final List<InteractionActionImpl> actions = new ArrayList<>();
|
private final List<InteractionActionImpl> actions = new ArrayList<>();
|
||||||
|
|
||||||
protected NpcImpl(UUID uuid, ConfigManager configManager, LegacyComponentSerializer textSerializer, World world, NpcTypeImpl type, NpcLocation location, PacketFactory packetFactory) {
|
protected NpcImpl(UUID uuid, EntityPropertyRegistryImpl propertyRegistry, ConfigManager configManager, LegacyComponentSerializer textSerializer, World world, NpcTypeImpl type, NpcLocation location, PacketFactory packetFactory) {
|
||||||
this(uuid, configManager, packetFactory, textSerializer, world.getName(), type, location);
|
this(uuid, propertyRegistry, configManager, packetFactory, textSerializer, world.getName(), type, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NpcImpl(UUID uuid, ConfigManager configManager, PacketFactory packetFactory, LegacyComponentSerializer textSerializer, String world, NpcTypeImpl type, NpcLocation location) {
|
public NpcImpl(UUID uuid, EntityPropertyRegistryImpl propertyRegistry, ConfigManager configManager, PacketFactory packetFactory, LegacyComponentSerializer textSerializer, String world, NpcTypeImpl type, NpcLocation location) {
|
||||||
this.packetFactory = packetFactory;
|
this.packetFactory = packetFactory;
|
||||||
this.worldName = world;
|
this.worldName = world;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.location = location;
|
this.location = location;
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
entity = new PacketEntity(packetFactory, this, type.getType(), location);
|
entity = new PacketEntity(packetFactory, this, type.getType(), location);
|
||||||
hologram = new HologramImpl(configManager, packetFactory, textSerializer, location.withY(location.getY() + type.getHologramOffset()));
|
hologram = new HologramImpl(propertyRegistry, configManager, packetFactory, textSerializer, location.withY(location.getY() + type.getHologramOffset()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -118,12 +120,11 @@ public class NpcImpl extends Viewable implements Npc {
|
||||||
hologram.hide(player);
|
hologram.hide(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UNSAFE_refreshMeta() {
|
private <T> void UNSAFE_refreshProperty(EntityPropertyImpl<T> property) {
|
||||||
for (Player viewer : getViewers()) entity.refreshMeta(viewer);
|
for (Player viewer : getViewers()) {
|
||||||
|
List<EntityData> data = property.applyStandalone(viewer, entity, true);
|
||||||
|
if (data.size() > 0) packetFactory.sendMetadata(viewer, entity, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UNSAFE_remakeTeam() {
|
|
||||||
for (Player viewer : getViewers()) entity.remakeTeam(viewer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -141,10 +142,10 @@ public class NpcImpl extends Viewable implements Npc {
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> void setProperty(EntityPropertyImpl<T> key, T value) {
|
public <T> void setProperty(EntityPropertyImpl<T> key, T value) {
|
||||||
if (value == null || value.equals(key.getDefaultValue())) removeProperty(key);
|
if (key == null) return;
|
||||||
|
if (value == null || value.equals(key.getDefaultValue())) propertyMap.remove(key);
|
||||||
else propertyMap.put(key, value);
|
else propertyMap.put(key, value);
|
||||||
UNSAFE_refreshMeta();
|
UNSAFE_refreshProperty(key);
|
||||||
if (key.getName().equalsIgnoreCase("glow")) UNSAFE_remakeTeam();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -152,14 +153,8 @@ public class NpcImpl extends Viewable implements Npc {
|
||||||
setProperty((EntityPropertyImpl<T>) property, (T) value);
|
setProperty((EntityPropertyImpl<T>) property, (T) value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeProperty(EntityPropertyImpl<?> key) {
|
@Override
|
||||||
propertyMap.remove(key);
|
public Set<EntityProperty<?>> getAppliedProperties() {
|
||||||
UNSAFE_refreshMeta();
|
|
||||||
if (key.getName().equalsIgnoreCase("glow")) UNSAFE_remakeTeam();
|
|
||||||
else if (key.getName().equalsIgnoreCase("dinnerbone")) respawn();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<EntityPropertyImpl<?>> getAppliedProperties() {
|
|
||||||
return Collections.unmodifiableSet(propertyMap.keySet());
|
return Collections.unmodifiableSet(propertyMap.keySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ public class NpcRegistryImpl implements NpcRegistry {
|
||||||
private final PacketFactory packetFactory;
|
private final PacketFactory packetFactory;
|
||||||
private final ConfigManager configManager;
|
private final ConfigManager configManager;
|
||||||
private final LegacyComponentSerializer textSerializer;
|
private final LegacyComponentSerializer textSerializer;
|
||||||
|
private final EntityPropertyRegistryImpl propertyRegistry;
|
||||||
|
|
||||||
private final List<NpcEntryImpl> npcList = new ArrayList<>();
|
private final List<NpcEntryImpl> npcList = new ArrayList<>();
|
||||||
private final Map<String, NpcEntryImpl> npcIdLookupMap = new HashMap<>();
|
private final Map<String, NpcEntryImpl> npcIdLookupMap = new HashMap<>();
|
||||||
|
@ -29,6 +30,7 @@ public class NpcRegistryImpl implements NpcRegistry {
|
||||||
|
|
||||||
public NpcRegistryImpl(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, TaskScheduler scheduler, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer) {
|
public NpcRegistryImpl(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, TaskScheduler scheduler, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer) {
|
||||||
this.textSerializer = textSerializer;
|
this.textSerializer = textSerializer;
|
||||||
|
this.propertyRegistry = propertyRegistry;
|
||||||
storage = configManager.getConfig().storageType().create(configManager, plugin, packetFactory, actionRegistry, typeRegistry, propertyRegistry, textSerializer);
|
storage = configManager.getConfig().storageType().create(configManager, plugin, packetFactory, actionRegistry, typeRegistry, propertyRegistry, textSerializer);
|
||||||
this.packetFactory = packetFactory;
|
this.packetFactory = packetFactory;
|
||||||
this.configManager = configManager;
|
this.configManager = configManager;
|
||||||
|
@ -101,7 +103,9 @@ public class NpcRegistryImpl implements NpcRegistry {
|
||||||
}
|
}
|
||||||
|
|
||||||
public NpcEntryImpl getByEntityId(int id) {
|
public NpcEntryImpl getByEntityId(int id) {
|
||||||
return npcList.stream().filter(entry -> entry.getNpc().getEntity().getEntityId() == id).findFirst().orElse(null);
|
return npcList.stream().filter(entry -> entry.getNpc().getEntity().getEntityId() == id ||
|
||||||
|
entry.getNpc().getHologram().getLines().stream().anyMatch(line -> line.getEntityId() == id)) // Also match the holograms of npcs
|
||||||
|
.findFirst().orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<String> getAllIds() {
|
public Collection<String> getAllIds() {
|
||||||
|
@ -134,7 +138,8 @@ public class NpcRegistryImpl implements NpcRegistry {
|
||||||
public NpcEntryImpl create(String id, World world, NpcTypeImpl type, NpcLocation location) {
|
public NpcEntryImpl create(String id, World world, NpcTypeImpl type, NpcLocation location) {
|
||||||
id = id.toLowerCase();
|
id = id.toLowerCase();
|
||||||
if (npcIdLookupMap.containsKey(id)) throw new IllegalArgumentException("An npc with the id " + id + " already exists!");
|
if (npcIdLookupMap.containsKey(id)) throw new IllegalArgumentException("An npc with the id " + id + " already exists!");
|
||||||
NpcImpl npc = new NpcImpl(UUID.randomUUID(), configManager, textSerializer, world, type, location, packetFactory);
|
NpcImpl npc = new NpcImpl(UUID.randomUUID(), propertyRegistry, configManager, textSerializer, world, type, location, packetFactory);
|
||||||
|
type.applyDefaultProperties(npc);
|
||||||
NpcEntryImpl entry = new NpcEntryImpl(id, npc);
|
NpcEntryImpl entry = new NpcEntryImpl(id, npc);
|
||||||
register(entry);
|
register(entry);
|
||||||
return entry;
|
return entry;
|
||||||
|
|
|
@ -3,25 +3,29 @@ package lol.pyr.znpcsplus.npc;
|
||||||
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.type.EntityType;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||||
import lol.pyr.znpcsplus.api.entity.EntityProperty;
|
import lol.pyr.znpcsplus.api.entity.EntityProperty;
|
||||||
import lol.pyr.znpcsplus.api.npc.NpcType;
|
import lol.pyr.znpcsplus.api.npc.NpcType;
|
||||||
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
|
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class NpcTypeImpl implements NpcType {
|
public class NpcTypeImpl implements NpcType {
|
||||||
private final EntityType type;
|
private final EntityType type;
|
||||||
private final Set<EntityPropertyImpl<?>> allowedProperties;
|
private final Set<EntityPropertyImpl<?>> allowedProperties;
|
||||||
|
private final Map<EntityPropertyImpl<?>, Object> defaultProperties;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final double hologramOffset;
|
private final double hologramOffset;
|
||||||
|
|
||||||
private NpcTypeImpl(String name, EntityType type, double hologramOffset, Set<EntityPropertyImpl<?>> allowedProperties) {
|
private NpcTypeImpl(String name, EntityType type, double hologramOffset, Set<EntityPropertyImpl<?>> allowedProperties, Map<EntityPropertyImpl<?>, Object> defaultProperties) {
|
||||||
this.name = name.toLowerCase();
|
this.name = name.toLowerCase();
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.hologramOffset = hologramOffset;
|
this.hologramOffset = hologramOffset;
|
||||||
this.allowedProperties = allowedProperties;
|
this.allowedProperties = allowedProperties;
|
||||||
|
this.defaultProperties = defaultProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
@ -40,11 +44,20 @@ public class NpcTypeImpl implements NpcType {
|
||||||
return allowedProperties.stream().map(property -> (EntityProperty<?>) property).collect(Collectors.toSet());
|
return allowedProperties.stream().map(property -> (EntityProperty<?>) property).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void applyDefaultProperties(NpcImpl npc) {
|
||||||
|
for (Map.Entry<EntityPropertyImpl<?>, Object> entry : defaultProperties.entrySet()) {
|
||||||
|
npc.UNSAFE_setProperty(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected static final class Builder {
|
protected static final class Builder {
|
||||||
|
private final static Logger logger = Logger.getLogger("NpcTypeBuilder");
|
||||||
|
|
||||||
private final EntityPropertyRegistryImpl propertyRegistry;
|
private final EntityPropertyRegistryImpl propertyRegistry;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final EntityType type;
|
private final EntityType type;
|
||||||
private final List<EntityPropertyImpl<?>> allowedProperties = new ArrayList<>();
|
private final List<EntityPropertyImpl<?>> allowedProperties = new ArrayList<>();
|
||||||
|
private final Map<EntityPropertyImpl<?>, Object> defaultProperties = new HashMap<>();
|
||||||
private double hologramOffset = 0;
|
private double hologramOffset = 0;
|
||||||
|
|
||||||
Builder(EntityPropertyRegistryImpl propertyRegistry, String name, EntityType type) {
|
Builder(EntityPropertyRegistryImpl propertyRegistry, String name, EntityType type) {
|
||||||
|
@ -67,7 +80,26 @@ public class NpcTypeImpl implements NpcType {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder addProperties(String... names) {
|
public Builder addProperties(String... names) {
|
||||||
for (String name : names) allowedProperties.add(propertyRegistry.getByName(name));
|
for (String name : names) {
|
||||||
|
if (propertyRegistry.getByName(name) == null) {
|
||||||
|
// Only for use in development, please comment this out in production because some properties are version-dependent
|
||||||
|
// logger.warning("Tried to register the non-existent \"" + name + "\" property to the \"" + this.name + "\" npc type");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
allowedProperties.add(propertyRegistry.getByName(name));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T> Builder addDefaultProperty(String name, T value) {
|
||||||
|
EntityPropertyImpl<T> property = (EntityPropertyImpl<T>) propertyRegistry.getByName(name);
|
||||||
|
if (property == null) {
|
||||||
|
// Only for use in development, please comment this out in production because some properties are version-dependent
|
||||||
|
// logger.warning("Tried to register the non-existent \"" + name + "\" default property to the \"" + this.name + "\" npc type");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
defaultProperties.put(property, value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,22 +109,51 @@ public class NpcTypeImpl implements NpcType {
|
||||||
}
|
}
|
||||||
|
|
||||||
public NpcTypeImpl build() {
|
public NpcTypeImpl build() {
|
||||||
allowedProperties.add(propertyRegistry.getByName("fire"));
|
ServerVersion version = PacketEvents.getAPI().getServerManager().getVersion();
|
||||||
allowedProperties.add(propertyRegistry.getByName("invisible"));
|
addProperties("fire", "invisible", "silent", "look",
|
||||||
allowedProperties.add(propertyRegistry.getByName("silent"));
|
"potion_color", "potion_ambient", "dinnerbone");
|
||||||
allowedProperties.add(propertyRegistry.getByName("look"));
|
// TODO: make this look nicer after completing the rest of the properties
|
||||||
allowedProperties.add(propertyRegistry.getByName("skin_cape"));
|
if (version.isNewerThanOrEquals(ServerVersion.V_1_9)) addProperties("glow");
|
||||||
allowedProperties.add(propertyRegistry.getByName("using_item"));
|
if (version.isNewerThanOrEquals(ServerVersion.V_1_14)) {
|
||||||
allowedProperties.add(propertyRegistry.getByName("potion_color"));
|
addProperties("pose");
|
||||||
allowedProperties.add(propertyRegistry.getByName("potion_ambient"));
|
if (EntityTypes.isTypeInstanceOf(type, EntityTypes.HORSE)) {
|
||||||
allowedProperties.add(propertyRegistry.getByName("dinnerbone"));
|
addProperties("chestplate");
|
||||||
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9))
|
}
|
||||||
allowedProperties.add(propertyRegistry.getByName("glow"));
|
}
|
||||||
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_14))
|
if (version.isNewerThanOrEquals(ServerVersion.V_1_17)) addProperties("shaking");
|
||||||
allowedProperties.add(propertyRegistry.getByName("pose"));
|
if (EntityTypes.isTypeInstanceOf(type, EntityTypes.ABSTRACT_AGEABLE) || EntityTypes.isTypeInstanceOf(type, EntityTypes.ZOMBIE) || EntityTypes.isTypeInstanceOf(type, EntityTypes.ZOGLIN)) {
|
||||||
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_17))
|
addProperties("baby");
|
||||||
allowedProperties.add(propertyRegistry.getByName("shaking"));
|
}
|
||||||
return new NpcTypeImpl(name, type, hologramOffset, new HashSet<>(allowedProperties));
|
if (EntityTypes.isTypeInstanceOf(type, EntityTypes.ABSTRACT_HORSE)) {
|
||||||
|
addProperties("is_saddled", "is_eating", "is_rearing", "has_mouth_open");
|
||||||
|
}
|
||||||
|
if (EntityTypes.isTypeInstanceOf(type, EntityTypes.CHESTED_HORSE)) {
|
||||||
|
addProperties("has_chest");
|
||||||
|
} else if (version.isOlderThan(ServerVersion.V_1_11) && type.equals(EntityTypes.HORSE)) {
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,14 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry {
|
||||||
register(builder(p, "player", EntityTypes.PLAYER)
|
register(builder(p, "player", EntityTypes.PLAYER)
|
||||||
.setHologramOffset(-0.15D)
|
.setHologramOffset(-0.15D)
|
||||||
.addEquipmentProperties()
|
.addEquipmentProperties()
|
||||||
.addProperties("skin_cape", "skin_jacket", "skin_left_sleeve", "skin_right_sleeve", "skin_left_leg", "skin_right_leg", "skin_hat", "shoulder_entity_left", "shoulder_entity_right"));
|
.addProperties("skin_cape", "skin_jacket", "skin_left_sleeve", "skin_right_sleeve", "skin_left_leg", "skin_right_leg", "skin_hat", "shoulder_entity_left", "shoulder_entity_right")
|
||||||
|
.addDefaultProperty("skin_cape", true)
|
||||||
|
.addDefaultProperty("skin_jacket", true)
|
||||||
|
.addDefaultProperty("skin_left_sleeve", true)
|
||||||
|
.addDefaultProperty("skin_right_sleeve", true)
|
||||||
|
.addDefaultProperty("skin_left_leg", true)
|
||||||
|
.addDefaultProperty("skin_right_leg", true)
|
||||||
|
.addDefaultProperty("skin_hat", true));
|
||||||
|
|
||||||
// Most hologram offsets generated using Entity#getHeight() in 1.19.4
|
// Most hologram offsets generated using Entity#getHeight() in 1.19.4
|
||||||
|
|
||||||
|
@ -88,7 +95,8 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry {
|
||||||
.setHologramOffset(-1.125));
|
.setHologramOffset(-1.125));
|
||||||
|
|
||||||
register(builder(p, "horse", EntityTypes.HORSE)
|
register(builder(p, "horse", EntityTypes.HORSE)
|
||||||
.setHologramOffset(-0.375));
|
.setHologramOffset(-0.375)
|
||||||
|
.addProperties("horse_type", "horse_style", "horse_color", "horse_armor"));
|
||||||
|
|
||||||
register(builder(p, "iron_golem", EntityTypes.IRON_GOLEM)
|
register(builder(p, "iron_golem", EntityTypes.IRON_GOLEM)
|
||||||
.setHologramOffset(0.725));
|
.setHologramOffset(0.725));
|
||||||
|
@ -96,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));
|
||||||
|
@ -143,7 +153,8 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry {
|
||||||
.setHologramOffset(1.525));
|
.setHologramOffset(1.525));
|
||||||
|
|
||||||
register(builder(p, "wolf", EntityTypes.WOLF)
|
register(builder(p, "wolf", EntityTypes.WOLF)
|
||||||
.setHologramOffset(-1.125));
|
.setHologramOffset(-1.125)
|
||||||
|
.addProperties("tamed"));
|
||||||
|
|
||||||
register(builder(p, "zombie", EntityTypes.ZOMBIE)
|
register(builder(p, "zombie", EntityTypes.ZOMBIE)
|
||||||
.setHologramOffset(-0.025)
|
.setHologramOffset(-0.025)
|
||||||
|
@ -164,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;
|
||||||
|
|
||||||
|
@ -193,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)
|
||||||
|
@ -216,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;
|
||||||
|
|
||||||
|
@ -235,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));
|
||||||
|
@ -250,24 +266,27 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry {
|
||||||
|
|
||||||
register(builder(p, "cat", EntityTypes.CAT)
|
register(builder(p, "cat", EntityTypes.CAT)
|
||||||
.setHologramOffset(-1.275)
|
.setHologramOffset(-1.275)
|
||||||
.addProperties("cat_variant", "cat_lying", "cat_collar_color"));
|
.addProperties("cat_variant", "cat_laying", "cat_relaxed", "cat_collar", "tamed"));
|
||||||
|
|
||||||
register(builder(p, "fox", EntityTypes.FOX)
|
register(builder(p, "fox", EntityTypes.FOX)
|
||||||
.setHologramOffset(-1.275)
|
.setHologramOffset(-1.275)
|
||||||
.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)
|
||||||
|
@ -283,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)
|
||||||
|
@ -320,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));
|
||||||
|
@ -334,7 +354,8 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry {
|
||||||
.setHologramOffset(0.125));
|
.setHologramOffset(0.125));
|
||||||
|
|
||||||
register(builder(p, "camel", EntityTypes.CAMEL)
|
register(builder(p, "camel", EntityTypes.CAMEL)
|
||||||
.setHologramOffset(0.25));
|
.setHologramOffset(0.25)
|
||||||
|
.addProperties("bashing"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<NpcType> getAll() {
|
public Collection<NpcType> getAll() {
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package lol.pyr.znpcsplus.packets;
|
package lol.pyr.znpcsplus.packets;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||||
|
import com.github.retrooper.packetevents.protocol.player.Equipment;
|
||||||
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
||||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public interface PacketFactory {
|
public interface PacketFactory {
|
||||||
|
@ -16,10 +17,9 @@ public interface PacketFactory {
|
||||||
void teleportEntity(Player player, PacketEntity entity);
|
void teleportEntity(Player player, PacketEntity entity);
|
||||||
CompletableFuture<Void> addTabPlayer(Player player, PacketEntity entity, PropertyHolder properties);
|
CompletableFuture<Void> addTabPlayer(Player player, PacketEntity entity, PropertyHolder properties);
|
||||||
void removeTabPlayer(Player player, PacketEntity entity);
|
void removeTabPlayer(Player player, PacketEntity entity);
|
||||||
void createTeam(Player player, PacketEntity entity, PropertyHolder properties);
|
void createTeam(Player player, PacketEntity entity, NamedTextColor glowColor);
|
||||||
void removeTeam(Player player, PacketEntity entity);
|
void removeTeam(Player player, PacketEntity entity);
|
||||||
Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties);
|
|
||||||
void sendAllMetadata(Player player, PacketEntity entity, PropertyHolder properties);
|
void sendAllMetadata(Player player, PacketEntity entity, PropertyHolder properties);
|
||||||
|
void sendEquipment(Player player, PacketEntity entity, Equipment equipment);
|
||||||
void sendMetadata(Player player, PacketEntity entity, List<EntityData> data);
|
void sendMetadata(Player player, PacketEntity entity, List<EntityData> data);
|
||||||
void sendEquipment(Player player, PacketEntity entity, PropertyHolder properties);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.packets;
|
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.PacketEventsAPI;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
|
||||||
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
|
||||||
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
|
|
||||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
|
||||||
import lol.pyr.znpcsplus.metadata.MetadataFactory;
|
|
||||||
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class V1_10PacketFactory extends V1_9PacketFactory {
|
|
||||||
public V1_10PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory, PacketEventsAPI<Plugin> packetEvents, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer) {
|
|
||||||
super(scheduler, metadataFactory, packetEvents, propertyRegistry, textSerializer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties) {
|
|
||||||
Map<Integer, EntityData> data = super.generateMetadata(player, entity, properties);
|
|
||||||
add(data, metadataFactory.noGravity());
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.packets;
|
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.PacketEventsAPI;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
|
||||||
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
|
||||||
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
|
|
||||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
|
||||||
import lol.pyr.znpcsplus.metadata.MetadataFactory;
|
|
||||||
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class V1_11PacketFactory extends V1_10PacketFactory {
|
|
||||||
public V1_11PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory, PacketEventsAPI<Plugin> packetEvents, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer) {
|
|
||||||
super(scheduler, metadataFactory, packetEvents, propertyRegistry, textSerializer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties) {
|
|
||||||
Map<Integer, EntityData> data = super.generateMetadata(player, entity, properties);
|
|
||||||
add(data, metadataFactory.usingItem(properties.getProperty(propertyRegistry.getByName("using_item", Boolean.class)), false, false));
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.packets;
|
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.PacketEventsAPI;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
|
|
||||||
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
|
||||||
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
|
|
||||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
|
||||||
import lol.pyr.znpcsplus.metadata.MetadataFactory;
|
|
||||||
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
|
||||||
import lol.pyr.znpcsplus.util.NpcPose;
|
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class V1_14PacketFactory extends V1_11PacketFactory {
|
|
||||||
public V1_14PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory, PacketEventsAPI<Plugin> packetEvents, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer) {
|
|
||||||
super(scheduler, metadataFactory, packetEvents, propertyRegistry, textSerializer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties) {
|
|
||||||
Map<Integer, EntityData> data = super.generateMetadata(player, entity, properties);
|
|
||||||
add(data, metadataFactory.pose(adaptNpcPose(properties.getProperty(propertyRegistry.getByName("pose", NpcPose.class)))));
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected EntityPose adaptNpcPose(NpcPose pose) {
|
|
||||||
return EntityPose.valueOf(pose.name());
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue