From 24c6e9695eb286d2ff65d8ba0ea9bd7b30abce83 Mon Sep 17 00:00:00 2001
From: Pyrbu <pyrmcserver@gmail.com>
Date: Tue, 25 Apr 2023 17:05:28 +0100
Subject: [PATCH] add invisible property

---
 src/main/java/lol/pyr/znpcsplus/ZNPCsPlus.java              | 1 +
 .../java/lol/pyr/znpcsplus/metadata/MetadataFactory.java    | 2 +-
 src/main/java/lol/pyr/znpcsplus/metadata/V1_8Factory.java   | 4 ++--
 src/main/java/lol/pyr/znpcsplus/metadata/V1_9Factory.java   | 4 ++--
 src/main/java/lol/pyr/znpcsplus/npc/NPCProperty.java        | 1 +
 src/main/java/lol/pyr/znpcsplus/npc/NPCType.java            | 1 +
 src/main/java/lol/pyr/znpcsplus/packets/V1_8Factory.java    | 6 ++++--
 src/main/java/lol/pyr/znpcsplus/packets/V1_9Factory.java    | 3 ++-
 8 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/src/main/java/lol/pyr/znpcsplus/ZNPCsPlus.java b/src/main/java/lol/pyr/znpcsplus/ZNPCsPlus.java
index 63e5ee5..e096ed3 100644
--- a/src/main/java/lol/pyr/znpcsplus/ZNPCsPlus.java
+++ b/src/main/java/lol/pyr/znpcsplus/ZNPCsPlus.java
@@ -147,6 +147,7 @@ public class ZNPCsPlus extends JavaPlugin {
                 NPC npc = new NPC(world, type, new PacketLocation(x * 3, 200, z * 3, 0, 0));
                 if (type.getType() == EntityTypes.PLAYER) {
                     SkinCache.fetchByName("Notch").thenAccept(skin -> npc.setProperty(NPCProperty.SKIN, new PrefetchedDescriptor(skin)));
+                    npc.setProperty(NPCProperty.INVISIBLE, true);
                 }
                 npc.setProperty(NPCProperty.GLOW, NamedTextColor.RED);
                 npc.setProperty(NPCProperty.FIRE, true);
diff --git a/src/main/java/lol/pyr/znpcsplus/metadata/MetadataFactory.java b/src/main/java/lol/pyr/znpcsplus/metadata/MetadataFactory.java
index 621fcd2..22c674d 100644
--- a/src/main/java/lol/pyr/znpcsplus/metadata/MetadataFactory.java
+++ b/src/main/java/lol/pyr/znpcsplus/metadata/MetadataFactory.java
@@ -24,7 +24,7 @@ import java.util.Map;
  */
 public interface MetadataFactory {
     EntityData skinLayers();
-    EntityData effects(boolean onFire, boolean glowing);
+    EntityData effects(boolean onFire, boolean glowing, boolean invisible);
 
     MetadataFactory factory = get();
 
diff --git a/src/main/java/lol/pyr/znpcsplus/metadata/V1_8Factory.java b/src/main/java/lol/pyr/znpcsplus/metadata/V1_8Factory.java
index b36b7fa..201aa2d 100644
--- a/src/main/java/lol/pyr/znpcsplus/metadata/V1_8Factory.java
+++ b/src/main/java/lol/pyr/znpcsplus/metadata/V1_8Factory.java
@@ -10,8 +10,8 @@ public class V1_8Factory implements MetadataFactory {
     }
 
     @Override
-    public EntityData effects(boolean onFire, boolean glowing) {
-        return new EntityData(0, EntityDataTypes.BYTE, onFire ? 0x01 : 0);
+    public EntityData effects(boolean onFire, boolean glowing, boolean invisible) {
+        return new EntityData(0, EntityDataTypes.BYTE, (onFire ? 0x01 : 0) | (invisible ? 0x20 : 0));
     }
 
     protected EntityData createSkinLayers(int index) {
diff --git a/src/main/java/lol/pyr/znpcsplus/metadata/V1_9Factory.java b/src/main/java/lol/pyr/znpcsplus/metadata/V1_9Factory.java
index 1a8a9c5..5e9ebc3 100644
--- a/src/main/java/lol/pyr/znpcsplus/metadata/V1_9Factory.java
+++ b/src/main/java/lol/pyr/znpcsplus/metadata/V1_9Factory.java
@@ -10,7 +10,7 @@ public class V1_9Factory extends V1_8Factory {
     }
 
     @Override
-    public EntityData effects(boolean onFire, boolean glowing) {
-        return new EntityData(0, EntityDataTypes.BYTE, (byte) ((onFire ? 0x01 : 0) | (glowing ? 0x40 : 0)));
+    public EntityData effects(boolean onFire, boolean glowing, boolean invisible) {
+        return new EntityData(0, EntityDataTypes.BYTE, (byte) ((onFire ? 0x01 : 0) | (invisible ? 0x20 : 0) | (glowing ? 0x40 : 0)));
     }
 }
diff --git a/src/main/java/lol/pyr/znpcsplus/npc/NPCProperty.java b/src/main/java/lol/pyr/znpcsplus/npc/NPCProperty.java
index 588aca8..6236194 100644
--- a/src/main/java/lol/pyr/znpcsplus/npc/NPCProperty.java
+++ b/src/main/java/lol/pyr/znpcsplus/npc/NPCProperty.java
@@ -38,4 +38,5 @@ public class NPCProperty<T> {
     public static NPCProperty<SkinDescriptor> SKIN = new NPCProperty<>("skin");
     public static NPCProperty<NamedTextColor> GLOW = new NPCProperty<>("glow");
     public static NPCProperty<Boolean> FIRE = new NPCProperty<>("fire", false);
+    public static NPCProperty<Boolean> INVISIBLE = new NPCProperty<>("invisible", false);
 }
\ No newline at end of file
diff --git a/src/main/java/lol/pyr/znpcsplus/npc/NPCType.java b/src/main/java/lol/pyr/znpcsplus/npc/NPCType.java
index 5ea159a..2e3c61c 100644
--- a/src/main/java/lol/pyr/znpcsplus/npc/NPCType.java
+++ b/src/main/java/lol/pyr/znpcsplus/npc/NPCType.java
@@ -27,6 +27,7 @@ public class NPCType {
         this.type = type;
         ArrayList<NPCProperty<?>> list = new ArrayList<>(List.of(allowedProperties));
         list.add(NPCProperty.FIRE);
+        list.add(NPCProperty.INVISIBLE);
         if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) list.add(NPCProperty.GLOW);
         this.allowedProperties = Set.copyOf(list);
     }
diff --git a/src/main/java/lol/pyr/znpcsplus/packets/V1_8Factory.java b/src/main/java/lol/pyr/znpcsplus/packets/V1_8Factory.java
index 8b32f96..ebeda9f 100644
--- a/src/main/java/lol/pyr/znpcsplus/packets/V1_8Factory.java
+++ b/src/main/java/lol/pyr/znpcsplus/packets/V1_8Factory.java
@@ -108,7 +108,9 @@ public class V1_8Factory implements PacketFactory {
     public void sendAllMetadata(Player player, PacketEntity entity) {
         NPC owner = entity.getOwner();
         if (entity.getType() == EntityTypes.PLAYER && owner.getProperty(NPCProperty.SKIN_LAYERS)) sendMetadata(player, entity, MetadataFactory.get().skinLayers());
-        if (owner.getProperty(NPCProperty.FIRE)) sendMetadata(player, entity, MetadataFactory.get().effects(true, false));
+        boolean fire = owner.getProperty(NPCProperty.FIRE);
+        boolean invisible = owner.getProperty(NPCProperty.INVISIBLE);
+        if (fire || invisible) sendMetadata(player, entity, MetadataFactory.get().effects(fire, false, invisible));
     }
 
     @Override
@@ -130,7 +132,7 @@ public class V1_8Factory implements PacketFactory {
         }
         CompletableFuture<UserProfile> future = new CompletableFuture<>();
         descriptor.fetch(player).thenAccept(skin -> {
-            skin.apply(profile);
+            if (skin != null) skin.apply(profile);
             future.complete(profile);
         });
         return future;
diff --git a/src/main/java/lol/pyr/znpcsplus/packets/V1_9Factory.java b/src/main/java/lol/pyr/znpcsplus/packets/V1_9Factory.java
index dac06ed..0a1eaeb 100644
--- a/src/main/java/lol/pyr/znpcsplus/packets/V1_9Factory.java
+++ b/src/main/java/lol/pyr/znpcsplus/packets/V1_9Factory.java
@@ -14,7 +14,8 @@ public class V1_9Factory extends V1_8Factory {
         if (entity.getType() == EntityTypes.PLAYER && owner.getProperty(NPCProperty.SKIN_LAYERS)) sendMetadata(player, entity, MetadataFactory.get().skinLayers());
         boolean glow = owner.hasProperty(NPCProperty.GLOW);
         boolean fire = owner.getProperty(NPCProperty.FIRE);
-        if (glow || fire) sendMetadata(player, entity, MetadataFactory.get().effects(fire, glow));
+        boolean invisible = owner.getProperty(NPCProperty.INVISIBLE);
+        if (glow || fire) sendMetadata(player, entity, MetadataFactory.get().effects(fire, glow, invisible));
     }
 
     @Override