added End Crystal and its properties
This commit is contained in:
		
							parent
							
								
									f519020c5b
								
							
						
					
					
						commit
						f3c0df41dc
					
				
					 8 changed files with 201 additions and 5 deletions
				
			
		
							
								
								
									
										46
									
								
								api/src/main/java/lol/pyr/znpcsplus/util/Vector3i.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								api/src/main/java/lol/pyr/znpcsplus/util/Vector3i.java
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,46 @@
 | 
			
		|||
package lol.pyr.znpcsplus.util;
 | 
			
		||||
 | 
			
		||||
public class Vector3i {
 | 
			
		||||
    private final int x;
 | 
			
		||||
    private final int y;
 | 
			
		||||
    private final int z;
 | 
			
		||||
 | 
			
		||||
    public Vector3i(int x, int y, int z) {
 | 
			
		||||
        this.x = x;
 | 
			
		||||
        this.y = y;
 | 
			
		||||
        this.z = z;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getX() {
 | 
			
		||||
        return this.x;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getY() {
 | 
			
		||||
        return this.y;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getZ() {
 | 
			
		||||
        return this.z;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return this.x + "," + this.y + "," + this.z;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String toPrettyString() {
 | 
			
		||||
        return "(" + this.x + ", " + this.y + ", " + this.z + ")";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Vector3i fromString(String s) {
 | 
			
		||||
        String[] split = s.split(",");
 | 
			
		||||
        if (split.length < 3) {
 | 
			
		||||
            return null;
 | 
			
		||||
        } else {
 | 
			
		||||
            try {
 | 
			
		||||
                return new Vector3i(Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2]));
 | 
			
		||||
            } catch (NumberFormatException var3) {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -251,6 +251,7 @@ public class ZNpcsPlus extends JavaPlugin {
 | 
			
		|||
        manager.registerParser(Color.class, new ColorParser(incorrectUsageMessage));
 | 
			
		||||
        manager.registerParser(Vector3f.class, new Vector3fParser(incorrectUsageMessage));
 | 
			
		||||
        manager.registerParser(String.class, new StringParser(incorrectUsageMessage));
 | 
			
		||||
        manager.registerParser(Vector3i.class, new Vector3iParser(incorrectUsageMessage));
 | 
			
		||||
 | 
			
		||||
        // TODO: Need to find a better way to do this
 | 
			
		||||
        registerEnumParser(manager, NpcPose.class, incorrectUsageMessage);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,9 @@ import net.kyori.adventure.text.Component;
 | 
			
		|||
import net.kyori.adventure.text.format.NamedTextColor;
 | 
			
		||||
import org.bukkit.Color;
 | 
			
		||||
import com.github.retrooper.packetevents.protocol.item.ItemStack;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.block.Block;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
| 
						 | 
				
			
			@ -117,9 +120,20 @@ public class PropertySetCommand implements CommandHandler {
 | 
			
		|||
            value = context.parse(type);
 | 
			
		||||
            valueName = value == null ? "NONE" : ((NpcEntryImpl) value).getId();
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
        else if (type == Vector3i.class) {
 | 
			
		||||
            value = context.parse(type);
 | 
			
		||||
            valueName = String.valueOf(value);
 | 
			
		||||
            valueName = value == null ? "NONE" : ((Vector3i) value).toPrettyString();
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            try {
 | 
			
		||||
                value = context.parse(type);
 | 
			
		||||
                valueName = String.valueOf(value);
 | 
			
		||||
            } catch (NullPointerException e) {
 | 
			
		||||
                context.send(Component.text("An error occurred while trying to parse the value. Please report this to the plugin author.",
 | 
			
		||||
                        NamedTextColor.RED));
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        npc.UNSAFE_setProperty(property, value);
 | 
			
		||||
| 
						 | 
				
			
			@ -144,6 +158,17 @@ public class PropertySetCommand implements CommandHandler {
 | 
			
		|||
                        context.suggestEnum(Arrays.stream(SpellType.values()).filter(spellType -> spellType.ordinal() <= 3).toArray(SpellType[]::new)) :
 | 
			
		||||
                        context.suggestEnum(SpellType.values());
 | 
			
		||||
 | 
			
		||||
                if (type == Vector3i.class) {
 | 
			
		||||
                    if (context.getSender() instanceof Player) {
 | 
			
		||||
                        Player player = (Player) context.getSender();
 | 
			
		||||
                        Block targetBlock = player.getTargetBlock(Collections.singleton(Material.AIR), 5);
 | 
			
		||||
                        if (targetBlock.getType().equals(Material.AIR)) return Collections.emptyList();
 | 
			
		||||
                        return context.suggestLiteral(
 | 
			
		||||
                                targetBlock.getX() + "",
 | 
			
		||||
                                targetBlock.getX() + " " + targetBlock.getY(),
 | 
			
		||||
                                targetBlock.getX() + " " + targetBlock.getY() + " " + targetBlock.getZ());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                // Suggest enum values directly
 | 
			
		||||
                if (type.isEnum()) {
 | 
			
		||||
                    return context.suggestEnum((Enum<?>[]) type.getEnumConstants());
 | 
			
		||||
| 
						 | 
				
			
			@ -154,6 +179,25 @@ public class PropertySetCommand implements CommandHandler {
 | 
			
		|||
                    // 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();
 | 
			
		||||
                }
 | 
			
		||||
                if (type == Vector3i.class) {
 | 
			
		||||
                    if (context.getSender() instanceof Player) {
 | 
			
		||||
                        Player player = (Player) context.getSender();
 | 
			
		||||
                        Block targetBlock = player.getTargetBlock(Collections.singleton(Material.AIR), 5);
 | 
			
		||||
                        if (targetBlock.getType().equals(Material.AIR)) return Collections.emptyList();
 | 
			
		||||
                        return context.suggestLiteral(
 | 
			
		||||
                                targetBlock.getY() + "",
 | 
			
		||||
                                targetBlock.getY() + " " + targetBlock.getZ());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else if (context.argSize() == 5) {
 | 
			
		||||
                if (type == Vector3i.class) {
 | 
			
		||||
                    if (context.getSender() instanceof Player) {
 | 
			
		||||
                        Player player = (Player) context.getSender();
 | 
			
		||||
                        Block targetBlock = player.getTargetBlock(Collections.singleton(Material.AIR), 5);
 | 
			
		||||
                        if (targetBlock.getType().equals(Material.AIR)) return Collections.emptyList();
 | 
			
		||||
                        return context.suggestLiteral(targetBlock.getZ() + "");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return Collections.emptyList();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,6 +56,7 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
 | 
			
		|||
        registerSerializer(new Vector3fPropertySerializer());
 | 
			
		||||
        registerSerializer(new BlockStatePropertySerializer());
 | 
			
		||||
        registerSerializer(new LookTypeSerializer());
 | 
			
		||||
        registerSerializer(new GenericSerializer<>(Vector3i::toString, Vector3i::fromString, Vector3i.class));
 | 
			
		||||
 | 
			
		||||
        registerEnumSerializer(NpcPose.class);
 | 
			
		||||
        registerEnumSerializer(DyeColor.class);
 | 
			
		||||
| 
						 | 
				
			
			@ -251,6 +252,17 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
 | 
			
		|||
        register(new BitsetProperty("is_rearing", horseIndex, horseEating << 1, false, legacyBooleans));
 | 
			
		||||
        register(new BitsetProperty("has_mouth_open", horseIndex, horseEating << 2, false, legacyBooleans));
 | 
			
		||||
 | 
			
		||||
        // End Crystal
 | 
			
		||||
        if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) {
 | 
			
		||||
            int endCrystalIndex;
 | 
			
		||||
            if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) endCrystalIndex = 8;
 | 
			
		||||
            else if (ver.isNewerThanOrEquals(ServerVersion.V_1_15)) endCrystalIndex = 7;
 | 
			
		||||
            else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) endCrystalIndex = 6;
 | 
			
		||||
            else endCrystalIndex = 5;
 | 
			
		||||
            register(new OptionalBlockPosProperty("beam_target", null, endCrystalIndex++));
 | 
			
		||||
            register(new BooleanProperty("show_base", endCrystalIndex, true, false));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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()));
 | 
			
		||||
| 
						 | 
				
			
			@ -367,7 +379,7 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
 | 
			
		|||
        else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) witherIndex = 11;
 | 
			
		||||
        else witherIndex = 17;
 | 
			
		||||
        witherIndex += 3; // skip the first 3 indexes, will be used for the other properties later
 | 
			
		||||
        register(new IntegerProperty("invulnerable_time", witherIndex++, 0, false));
 | 
			
		||||
        register(new IntegerProperty("invulnerable_time", witherIndex, 0, false));
 | 
			
		||||
 | 
			
		||||
        if (!ver.isNewerThanOrEquals(ServerVersion.V_1_9)) return;
 | 
			
		||||
        // Shulker
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.entity.data.EntityDataTypes;
 | 
			
		||||
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
 | 
			
		||||
import lol.pyr.znpcsplus.entity.PacketEntity;
 | 
			
		||||
import lol.pyr.znpcsplus.util.Vector3i;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
 | 
			
		||||
public class OptionalBlockPosProperty extends EntityPropertyImpl<Vector3i> {
 | 
			
		||||
    private final int index;
 | 
			
		||||
 | 
			
		||||
    public OptionalBlockPosProperty(String name, Vector3i defaultValue, int index) {
 | 
			
		||||
        super(name, defaultValue, Vector3i.class);
 | 
			
		||||
        this.index = index;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
 | 
			
		||||
        Vector3i value = entity.getProperty(this);
 | 
			
		||||
        if (value == null) properties.put(index, new EntityData(index, EntityDataTypes.OPTIONAL_BLOCK_POSITION, Optional.empty()));
 | 
			
		||||
        else properties.put(index, new EntityData(index, EntityDataTypes.OPTIONAL_BLOCK_POSITION,
 | 
			
		||||
                Optional.of(new com.github.retrooper.packetevents.util.Vector3i(value.getX(), value.getY(), value.getZ()))));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
package lol.pyr.znpcsplus.entity.serializers;
 | 
			
		||||
 | 
			
		||||
import lol.pyr.znpcsplus.entity.PropertySerializer;
 | 
			
		||||
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
 | 
			
		||||
public class GenericSerializer<T> implements PropertySerializer<T> {
 | 
			
		||||
    private final Function<T, String> encoder;
 | 
			
		||||
    private final Function<String, T> decoder;
 | 
			
		||||
    private final Class<T> typeClass;
 | 
			
		||||
 | 
			
		||||
    public GenericSerializer(Function<T, String> encoder, Function<String, T> decoder, Class<T> typeClass) {
 | 
			
		||||
        this.encoder = encoder;
 | 
			
		||||
        this.decoder = decoder;
 | 
			
		||||
        this.typeClass = typeClass;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String serialize(T property) {
 | 
			
		||||
        return encoder.apply(property);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public T deserialize(String property) {
 | 
			
		||||
        return decoder.apply(property);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Class<T> getTypeClass() {
 | 
			
		||||
        return typeClass;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -73,6 +73,10 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry {
 | 
			
		|||
                .setHologramOffset(-0.275)
 | 
			
		||||
                .addProperties("creeper_state", "creeper_charged"));
 | 
			
		||||
 | 
			
		||||
        register(builder(p, "end_crystal", EntityTypes.END_CRYSTAL)
 | 
			
		||||
                .setHologramOffset(0.025)
 | 
			
		||||
                .addProperties("beam_target", "show_base"));
 | 
			
		||||
 | 
			
		||||
        register(builder(p, "ender_dragon", EntityTypes.ENDER_DRAGON)
 | 
			
		||||
                .setHologramOffset(6.0245));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -206,8 +210,7 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry {
 | 
			
		|||
                .addEquipmentProperties());
 | 
			
		||||
 | 
			
		||||
        register(builder(p, "evoker", EntityTypes.EVOKER)
 | 
			
		||||
                .setHologramOffset(-0.025)
 | 
			
		||||
                .addProperties("evoker_spell"));
 | 
			
		||||
                .setHologramOffset(-0.025));
 | 
			
		||||
 | 
			
		||||
        register(builder(p, "llama", EntityTypes.LLAMA)
 | 
			
		||||
                .setHologramOffset(-0.105)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
package lol.pyr.znpcsplus.parsers;
 | 
			
		||||
 | 
			
		||||
import lol.pyr.director.adventure.command.CommandContext;
 | 
			
		||||
import lol.pyr.director.adventure.parse.ParserType;
 | 
			
		||||
import lol.pyr.director.common.command.CommandExecutionException;
 | 
			
		||||
import lol.pyr.director.common.message.Message;
 | 
			
		||||
import lol.pyr.znpcsplus.util.Vector3i;
 | 
			
		||||
 | 
			
		||||
import java.util.Deque;
 | 
			
		||||
 | 
			
		||||
public class Vector3iParser extends ParserType<Vector3i> {
 | 
			
		||||
    public Vector3iParser(Message<CommandContext> message) {
 | 
			
		||||
        super(message);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Vector3i parse(Deque<String> deque) throws CommandExecutionException {
 | 
			
		||||
        if (deque.size() == 0) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            return new Vector3i(
 | 
			
		||||
                    Integer.parseInt(deque.pop()),
 | 
			
		||||
                    Integer.parseInt(deque.pop()),
 | 
			
		||||
                    Integer.parseInt(deque.pop()));
 | 
			
		||||
        } catch (NumberFormatException e) {
 | 
			
		||||
            throw new CommandExecutionException();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in a new issue