From 079006d9cb3210ab3dd6d235a4fcd22d7087f547 Mon Sep 17 00:00:00 2001
From: D3v1s0m <49519439+D3v1s0m@users.noreply.github.com>
Date: Thu, 22 Jun 2023 20:02:02 +0530
Subject: [PATCH] implemented shaking and crouched properties

---
 .../entity/EntityPropertyRegistryImpl.java    |  2 +-
 .../znpcsplus/metadata/MetadataFactory.java   |  2 +-
 .../metadata/V1_17MetadataFactory.java        | 11 +++++++
 .../metadata/V1_8MetadataFactory.java         |  4 +--
 .../metadata/V1_9MetadataFactory.java         |  4 +--
 .../lol/pyr/znpcsplus/npc/NpcTypeImpl.java    |  3 ++
 .../znpcsplus/packets/V1_17PacketFactory.java | 31 +++++++++++++++++++
 .../znpcsplus/packets/V1_19PacketFactory.java |  2 +-
 .../znpcsplus/packets/V1_8PacketFactory.java  |  7 +++--
 .../znpcsplus/packets/V1_9PacketFactory.java  |  7 +++--
 10 files changed, 62 insertions(+), 11 deletions(-)
 create mode 100644 plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_17PacketFactory.java

diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java
index f105696..e2098ef 100644
--- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java
+++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java
@@ -46,7 +46,7 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
         registerType("using_item", false); // TODO: Eating/Drinking/Blocking with sword/etc
         registerType("potion_color", 0xFFFFFF); // TODO
         registerType("potion_ambient", false); // TODO
-        registerType("shaking", false); // TODO: Set the "ticks frozen in powdered snow" meta to 140 to get the entity to shake
+        registerType("shaking", false);
         registerType("baby", false); // TODO
 
         // Player
diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/metadata/MetadataFactory.java b/plugin/src/main/java/lol/pyr/znpcsplus/metadata/MetadataFactory.java
index 96f4a10..ef92ecb 100644
--- a/plugin/src/main/java/lol/pyr/znpcsplus/metadata/MetadataFactory.java
+++ b/plugin/src/main/java/lol/pyr/znpcsplus/metadata/MetadataFactory.java
@@ -20,7 +20,7 @@ import java.util.Collection;
  */
 public interface MetadataFactory {
     EntityData skinLayers(boolean cape, boolean jacket, boolean leftSleeve, boolean rightSleeve, boolean leftLeg, boolean rightLeg, boolean hat);
-    EntityData effects(boolean onFire, boolean glowing, boolean invisible);
+    Collection<EntityData> effects(boolean onFire, boolean crouched, boolean glowing, boolean invisible, boolean usingElytra, boolean shaking);
     EntityData silent(boolean enabled);
     Collection<EntityData> name(Component name);
     EntityData noGravity();
diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/metadata/V1_17MetadataFactory.java b/plugin/src/main/java/lol/pyr/znpcsplus/metadata/V1_17MetadataFactory.java
index c5a86d0..abd6809 100644
--- a/plugin/src/main/java/lol/pyr/znpcsplus/metadata/V1_17MetadataFactory.java
+++ b/plugin/src/main/java/lol/pyr/znpcsplus/metadata/V1_17MetadataFactory.java
@@ -1,10 +1,21 @@
 package lol.pyr.znpcsplus.metadata;
 
 import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
+import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
+
+import java.util.Collection;
 
 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 Collection<EntityData> effects(boolean onFire, boolean crouching, boolean glowing, boolean invisible, boolean usingElytra, boolean shaking) {
+        return list(
+                newEntityData(0, EntityDataTypes.BYTE, (byte) ((onFire ? 0x01 : 0) | (crouching ? 0x02 : 0) | (invisible ? 0x20 : 0) | (glowing ? 0x40 : 0) | (usingElytra ? 0x80 : 0))),
+                newEntityData(7, EntityDataTypes.INT, shaking ? 140 : 0)
+        );
+    }
 }
diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/metadata/V1_8MetadataFactory.java b/plugin/src/main/java/lol/pyr/znpcsplus/metadata/V1_8MetadataFactory.java
index 620a0b3..1c1e247 100644
--- a/plugin/src/main/java/lol/pyr/znpcsplus/metadata/V1_8MetadataFactory.java
+++ b/plugin/src/main/java/lol/pyr/znpcsplus/metadata/V1_8MetadataFactory.java
@@ -17,8 +17,8 @@ public class V1_8MetadataFactory implements MetadataFactory {
     }
 
     @Override
-    public EntityData effects(boolean onFire, boolean glowing, boolean invisible) {
-        return newEntityData(0, EntityDataTypes.BYTE, (byte) ((onFire ? 0x01 : 0) | (invisible ? 0x20 : 0)));
+    public Collection<EntityData> effects(boolean onFire, boolean crouched, boolean glowing, boolean invisible, boolean usingElytra, boolean shaking) {
+        return list(newEntityData(0, EntityDataTypes.BYTE, (byte) ((onFire ? 0x01 : 0) | (crouched ? 0x02 : 0) | (invisible ? 0x20 : 0))));
     }
 
     @Override
diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/metadata/V1_9MetadataFactory.java b/plugin/src/main/java/lol/pyr/znpcsplus/metadata/V1_9MetadataFactory.java
index 5421a40..abc401a 100644
--- a/plugin/src/main/java/lol/pyr/znpcsplus/metadata/V1_9MetadataFactory.java
+++ b/plugin/src/main/java/lol/pyr/znpcsplus/metadata/V1_9MetadataFactory.java
@@ -14,8 +14,8 @@ public class V1_9MetadataFactory extends V1_8MetadataFactory {
     }
 
     @Override
-    public EntityData effects(boolean onFire, boolean glowing, boolean invisible) {
-        return newEntityData(0, EntityDataTypes.BYTE, (byte) ((onFire ? 0x01 : 0) | (invisible ? 0x20 : 0) | (glowing ? 0x40 : 0)));
+    public Collection<EntityData> effects(boolean onFire, boolean crouched, boolean glowing, boolean invisible, boolean usingElytra, boolean shaking) {
+        return list(newEntityData(0, EntityDataTypes.BYTE, (byte) ((onFire ? 0x01 : 0) | (crouched ? 0x02 : 0) | (invisible ? 0x20 : 0) | (glowing ? 0x40 : 0) | (usingElytra ? 0x80 : 0))));
     }
 
     @Override
diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeImpl.java
index e899b7a..12ad3c7 100644
--- a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeImpl.java
+++ b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeImpl.java
@@ -72,6 +72,7 @@ public class NpcTypeImpl implements NpcType {
         }
 
         public NpcTypeImpl build() {
+            allowedProperties.add(propertyRegistry.getByName("crouched"));
             allowedProperties.add(propertyRegistry.getByName("fire"));
             allowedProperties.add(propertyRegistry.getByName("invisible"));
             allowedProperties.add(propertyRegistry.getByName("silent"));
@@ -79,6 +80,8 @@ public class NpcTypeImpl implements NpcType {
             allowedProperties.add(propertyRegistry.getByName("skin_cape"));
             if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9))
                 allowedProperties.add(propertyRegistry.getByName("glow"));
+            if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_17))
+                allowedProperties.add(propertyRegistry.getByName("shaking"));
             return new NpcTypeImpl(name, type, hologramOffset, new HashSet<>(allowedProperties));
         }
     }
diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_17PacketFactory.java b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_17PacketFactory.java
new file mode 100644
index 0000000..5ed5a79
--- /dev/null
+++ b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_17PacketFactory.java
@@ -0,0 +1,31 @@
+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 org.bukkit.entity.Player;
+import org.bukkit.plugin.Plugin;
+
+import java.util.Map;
+
+public class V1_17PacketFactory extends V1_16PacketFactory {
+    public V1_17PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory, PacketEventsAPI<Plugin> packetEvents, EntityPropertyRegistryImpl propertyRegistry) {
+        super(scheduler, metadataFactory, packetEvents, propertyRegistry);
+    }
+
+    @Override
+    public Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties) {
+        Map<Integer, EntityData> data = super.generateMetadata(player, entity, properties);
+        addAll(data, metadataFactory.effects(properties.getProperty(propertyRegistry.getByName("fire", Boolean.class)),
+                properties.getProperty(propertyRegistry.getByName("crouched", Boolean.class)),
+                properties.hasProperty(propertyRegistry.getByName("glow", Boolean.class)),
+                properties.getProperty(propertyRegistry.getByName("invisible", Boolean.class)),
+                false,
+                properties.getProperty(propertyRegistry.getByName("shaking", Boolean.class))));
+        return data;
+    }
+}
diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_19PacketFactory.java b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_19PacketFactory.java
index f875436..a06262a 100644
--- a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_19PacketFactory.java
+++ b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_19PacketFactory.java
@@ -19,7 +19,7 @@ import org.bukkit.plugin.Plugin;
 import java.util.EnumSet;
 import java.util.concurrent.CompletableFuture;
 
-public class V1_19PacketFactory extends V1_16PacketFactory {
+public class V1_19PacketFactory extends V1_17PacketFactory {
     private final boolean oldTabPackets;
     public V1_19PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory, PacketEventsAPI<Plugin> packetEvents, EntityPropertyRegistryImpl propertyRegistry) {
         super(scheduler, metadataFactory, packetEvents, propertyRegistry);
diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java
index dc4c1ed..6c7abdb 100644
--- a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java
+++ b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java
@@ -135,10 +135,13 @@ public class V1_8PacketFactory implements PacketFactory {
                 properties.getProperty(propertyRegistry.getByName("skin_right_leg", Boolean.class)),
                 properties.getProperty(propertyRegistry.getByName("skin_hat", Boolean.class))
         ));
-        add(data, metadataFactory.effects(
+        addAll(data, metadataFactory.effects(
                 properties.getProperty(propertyRegistry.getByName("fire", Boolean.class)),
+                properties.getProperty(propertyRegistry.getByName("crouched", Boolean.class)),
                 false,
-                properties.getProperty(propertyRegistry.getByName("invisible", Boolean.class)))
+                properties.getProperty(propertyRegistry.getByName("invisible", Boolean.class)),
+                false,
+                false)
         );
         add(data, metadataFactory.silent(properties.getProperty(propertyRegistry.getByName("silent", Boolean.class))));
         if (properties.hasProperty(propertyRegistry.getByName("name"))) addAll(data, metadataFactory.name(properties.getProperty(propertyRegistry.getByName("name", Component.class))));
diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_9PacketFactory.java b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_9PacketFactory.java
index 99667aa..02b8d26 100644
--- a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_9PacketFactory.java
+++ b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_9PacketFactory.java
@@ -20,9 +20,12 @@ public class V1_9PacketFactory extends V1_8PacketFactory {
     @Override
     public Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties) {
         Map<Integer, EntityData> data = super.generateMetadata(player, entity, properties);
-        add(data, metadataFactory.effects(properties.getProperty(propertyRegistry.getByName("fire", Boolean.class)),
+        addAll(data, metadataFactory.effects(properties.getProperty(propertyRegistry.getByName("fire", Boolean.class)),
+                properties.getProperty(propertyRegistry.getByName("crouched", Boolean.class)),
                 properties.hasProperty(propertyRegistry.getByName("glow", Boolean.class)),
-                properties.getProperty(propertyRegistry.getByName("invisible", Boolean.class))));
+                properties.getProperty(propertyRegistry.getByName("invisible", Boolean.class)),
+                false,
+                false));
         return data;
     }
 }