From 49c23a85a4bba584aade82c0c6e73b0eaa6c352a Mon Sep 17 00:00:00 2001 From: D3v1s0m <49519439+D3v1s0m@users.noreply.github.com> Date: Mon, 3 Jul 2023 10:47:10 +0530 Subject: [PATCH] Added Enderman properties, TODO: fix them lol --- .../lol/pyr/znpcsplus/util/BlockState.java | 14 ++++++ .../commands/property/PropertySetCommand.java | 49 +++++++++++++++++-- .../entity/EntityPropertyRegistryImpl.java | 20 ++++---- .../BlockStatePropertySerializer.java | 27 ++++++++++ .../znpcsplus/metadata/MetadataFactory.java | 10 ++-- .../metadata/V1_17MetadataFactory.java | 15 ++++++ .../metadata/V1_8MetadataFactory.java | 20 ++++++-- .../znpcsplus/npc/NpcTypeRegistryImpl.java | 3 +- .../znpcsplus/packets/V1_8PacketFactory.java | 7 +++ 9 files changed, 140 insertions(+), 25 deletions(-) create mode 100644 api/src/main/java/lol/pyr/znpcsplus/util/BlockState.java create mode 100644 plugin/src/main/java/lol/pyr/znpcsplus/entity/serializers/BlockStatePropertySerializer.java diff --git a/api/src/main/java/lol/pyr/znpcsplus/util/BlockState.java b/api/src/main/java/lol/pyr/znpcsplus/util/BlockState.java new file mode 100644 index 0000000..6a4e41b --- /dev/null +++ b/api/src/main/java/lol/pyr/znpcsplus/util/BlockState.java @@ -0,0 +1,14 @@ +package lol.pyr.znpcsplus.util; + +public class BlockState { + private final int globalId; + + public BlockState(int globalId) { + this.globalId = globalId; + } + + public int getGlobalId() { + return globalId; + } + +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/commands/property/PropertySetCommand.java b/plugin/src/main/java/lol/pyr/znpcsplus/commands/property/PropertySetCommand.java index 80b7bed..f41ba10 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/commands/property/PropertySetCommand.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/commands/property/PropertySetCommand.java @@ -1,6 +1,9 @@ package lol.pyr.znpcsplus.commands.property; import com.github.retrooper.packetevents.protocol.item.ItemStack; +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.StateTypes; import io.github.retrooper.packetevents.util.SpigotConversionUtil; import lol.pyr.director.adventure.command.CommandContext; import lol.pyr.director.adventure.command.CommandHandler; @@ -10,11 +13,7 @@ import lol.pyr.znpcsplus.entity.EntityPropertyImpl; import lol.pyr.znpcsplus.npc.NpcEntryImpl; import lol.pyr.znpcsplus.npc.NpcImpl; import lol.pyr.znpcsplus.npc.NpcRegistryImpl; -import lol.pyr.znpcsplus.util.CatVariant; -import lol.pyr.znpcsplus.util.CreeperState; -import lol.pyr.znpcsplus.util.NpcPose; -import lol.pyr.znpcsplus.util.Vector3f; -import lol.pyr.znpcsplus.util.ParrotVariant; +import lol.pyr.znpcsplus.util.*; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Color; @@ -65,6 +64,39 @@ public class PropertySetCommand implements CommandHandler { value = ParrotVariant.NONE; valueName = "NONE"; } + else if (type == BlockState.class) { + String inputType = context.popString().toLowerCase(); + switch (inputType) { + case "hand": + org.bukkit.inventory.ItemStack bukkitStack = context.ensureSenderIsPlayer().getInventory().getItemInHand(); + if (bukkitStack.getAmount() == 0) { + value = new BlockState(0); + valueName = "EMPTY"; + } else { + WrappedBlockState blockState = StateTypes.getByName(bukkitStack.getType().name().toLowerCase()).createBlockState(); +// WrappedBlockState blockState = WrappedBlockState.getByString(bukkitStack.getType().name().toLowerCase()); + value = new BlockState(blockState.getGlobalId()); + valueName = bukkitStack.toString(); + } + break; + case "looking_at": + + // TODO + + value = new BlockState(0); + valueName = "EMPTY"; + break; + case "block": + context.ensureArgsNotEmpty(); + WrappedBlockState blockState = WrappedBlockState.getByString(context.popString()); + value = new BlockState(blockState.getGlobalId()); + valueName = blockState.toString(); + break; + default: + context.send(Component.text("Invalid input type " + inputType + ", must be hand, looking_at, or block", NamedTextColor.RED)); + return; + } + } else { value = context.parse(type); valueName = String.valueOf(value); @@ -92,6 +124,13 @@ public class PropertySetCommand implements CommandHandler { 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"); + } + else if (context.argSize() == 4) { + if (type == BlockState.class) { + // TODO: suggest block with nbt like minecraft setblock command + return context.suggestionParse(2, String.class).equals("block") ? context.suggestStream(StateTypes.values().stream().map(StateType::getName)) : Collections.emptyList(); + } } } return Collections.emptyList(); 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 38c7544..3bbb60e 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java @@ -6,11 +6,7 @@ import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry; import lol.pyr.znpcsplus.api.skin.SkinDescriptor; import lol.pyr.znpcsplus.entity.serializers.*; import lol.pyr.znpcsplus.skin.cache.MojangSkinCache; -import lol.pyr.znpcsplus.util.CatVariant; -import lol.pyr.znpcsplus.util.CreeperState; -import lol.pyr.znpcsplus.util.NpcPose; -import lol.pyr.znpcsplus.util.Vector3f; -import lol.pyr.znpcsplus.util.ParrotVariant; +import lol.pyr.znpcsplus.util.*; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Color; @@ -35,6 +31,7 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { registerSerializer(new ItemStackPropertySerializer()); registerSerializer(new ColorPropertySerializer()); registerSerializer(new Vector3fPropertySerializer()); + registerSerializer(new BlockStatePropertySerializer()); registerEnumSerializer(NpcPose.class); registerEnumSerializer(DyeColor.class); @@ -113,8 +110,13 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { registerType("cat_collar_color", DyeColor.RED); // Creeper - registerType("creeper_state", CreeperState.IDLE); // TODO: -1 = idle, 1 = fuse - registerType("creeper_charged", false); // TODO + registerType("creeper_state", CreeperState.IDLE); + registerType("creeper_charged", false); + + // Enderman + registerType("enderman_held_block", new BlockState(0)); // TODO: figure out the type on this + registerType("enderman_screaming", false); // TODO + registerType("enderman_staring", false); // TODO // Pufferfish registerType("puff_state", null); // TODO: Make a puff state enum class @@ -203,10 +205,6 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { // Wither registerType("invulnerable_time", 0); // TODO - // Enderman - registerType("enderman_held_block", null); // TODO: figure out the type on this - registerType("enderman_screaming", false); // TODO - // Ghast registerType("attacking", false); // TODO diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/serializers/BlockStatePropertySerializer.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/serializers/BlockStatePropertySerializer.java new file mode 100644 index 0000000..c29f9b2 --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/serializers/BlockStatePropertySerializer.java @@ -0,0 +1,27 @@ +package lol.pyr.znpcsplus.entity.serializers; + +import lol.pyr.znpcsplus.entity.PropertySerializer; +import lol.pyr.znpcsplus.util.BlockState; + +public class BlockStatePropertySerializer implements PropertySerializer { + @Override + public String serialize(BlockState property) { + return String.valueOf(property.getGlobalId()); + } + + @Override + public BlockState deserialize(String property) { + try { + int id = Integer.parseInt(property); + return new BlockState(id); + } catch (Exception e) { + e.printStackTrace(); + } + return new BlockState(0); + } + + @Override + public Class getTypeClass() { + return BlockState.class; + } +} 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 82bf431..25683c7 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/metadata/MetadataFactory.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/metadata/MetadataFactory.java @@ -2,10 +2,7 @@ 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.CatVariant; -import lol.pyr.znpcsplus.util.CreeperState; -import lol.pyr.znpcsplus.util.ParrotVariant; -import lol.pyr.znpcsplus.util.Vector3f; +import lol.pyr.znpcsplus.util.*; import net.kyori.adventure.text.Component; import org.bukkit.DyeColor; @@ -71,4 +68,9 @@ public interface MetadataFactory { // Creeper EntityData creeperState(CreeperState state); EntityData creeperCharged(boolean charged); + + // Enderman + EntityData endermanHeldBlock(int heldBlock); + EntityData endermanScreaming(boolean screaming); + EntityData endermanStaring(boolean staring); } 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 741dbf2..2f7e1b1 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 @@ -143,4 +143,19 @@ public class V1_17MetadataFactory extends V1_16MetadataFactory { 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); + } } 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 e5c0e39..d15c1e3 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 @@ -5,10 +5,7 @@ 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.CatVariant; -import lol.pyr.znpcsplus.util.CreeperState; -import lol.pyr.znpcsplus.util.ParrotVariant; -import lol.pyr.znpcsplus.util.Vector3f; +import lol.pyr.znpcsplus.util.*; import net.kyori.adventure.text.Component; import org.bukkit.DyeColor; @@ -168,6 +165,21 @@ public class V1_8MetadataFactory implements MetadataFactory { 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 silent(boolean enabled) { return newEntityData(4, EntityDataTypes.BYTE, (byte) (enabled ? 1 : 0)); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeRegistryImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeRegistryImpl.java index bad1262..7a27b48 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeRegistryImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeRegistryImpl.java @@ -80,7 +80,8 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry { .setHologramOffset(6.0245)); register(builder(p, "enderman", EntityTypes.ENDERMAN) - .setHologramOffset(0.925)); + .setHologramOffset(0.925) + .addProperties("enderman_held_block", "enderman_screaming", "enderman_staring")); register(builder(p, "endermite", EntityTypes.ENDERMITE) .setHologramOffset(-1.675)); 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 4e8759b..bd49c8d 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 @@ -189,6 +189,13 @@ public class V1_8PacketFactory implements PacketFactory { add(data, metadataFactory.creeperState(properties.getProperty(propertyRegistry.getByName("creeper_state", CreeperState.class)))); add(data, metadataFactory.creeperCharged(properties.getProperty(propertyRegistry.getByName("creeper_charged", Boolean.class)))); } + else if (entity.getType().equals(EntityTypes.ENDERMAN)) { + add(data, metadataFactory.endermanHeldBlock( + properties.getProperty(propertyRegistry.getByName("enderman_held_block", BlockState.class)).getGlobalId()) + ); + add(data, metadataFactory.endermanScreaming(properties.getProperty(propertyRegistry.getByName("enderman_screaming", Boolean.class)))); + add(data, metadataFactory.endermanStaring(properties.getProperty(propertyRegistry.getByName("enderman_staring", Boolean.class)))); + } if (properties.getProperty(propertyRegistry.getByName("dinnerbone", Boolean.class))) { add(data, metadataFactory.name(Component.text("Dinnerbone")));