Помогите Как создать пакетный армор стенд

  • Автор темы Автор темы Kurumi
  • Дата начала Дата начала

Kurumi

Активный участник
Пользователь
Баллы
76
Имя в Minecraft
Kurumi
Здрасьте, хочу создать пакетный стенд и посадить его на игрока. Видимо я плохо обращаюсь с гуглом, потому что не могу найти
Поделитесь опытом
 
Появилась новая проблема
Хочу сажать на игроков стенды, чтобы отображать их донатные ранги
Набросал код, но он работает некорректно: сначала стенд появляется, всё работает, но потом через пару секунд он останавливается на месте и все, получается что он уже не на игроке. Еще, почему-то, у других игроков стенда не видно, хотя пакеты я отправляю всем.
Так же на сервере по какой-то причине остаются старые стенды, не знаю как их удалить
Мой код для наглядности
Код:
public class NameplateUtil {

    private List<Packet> packetList;

    public NameplateUtil() {
        this.packetList = new ArrayList<>();
    }

    public void setPlate(String rank, Player p) {
        Location loc = p.getLocation();
        WorldServer worldServer = ((CraftWorld)p.getWorld()).getHandle();
        EntityArmorStand stand = new EntityArmorStand(worldServer);

        stand.setLocation(loc.getX(), loc.getY(), loc.getZ(), 0, 0);
        stand.setCustomName(rank);
        stand.setCustomNameVisible(true);
        stand.setNoGravity(true);
        stand.setSmall(true);
        stand.setInvisible(true);

        EntitySlime entitySlime = new EntitySlime(worldServer);
        entitySlime.setLocation(loc.getX(), loc.getY(), loc.getZ(), 0, 0);
        entitySlime.setSize(-2, false);
        entitySlime.setInvisible(true);

        entitySlime.getBukkitEntity().addPassenger(stand.getBukkitEntity());

        CraftPlayer craftPlayer = (CraftPlayer) p;
        craftPlayer.addPassenger(entitySlime.getBukkitEntity());


        PacketPlayOutSpawnEntityLiving packetSlime = new PacketPlayOutSpawnEntityLiving(entitySlime);
        ((CraftPlayer)p).getHandle().playerConnection.sendPacket(packetSlime);
        PacketPlayOutSpawnEntityLiving packetStand = new PacketPlayOutSpawnEntityLiving(stand);
        ((CraftPlayer)p).getHandle().playerConnection.sendPacket(packetStand);
        PacketPlayOutMount packetPlayOutMount = new PacketPlayOutMount(entitySlime);
        craftPlayer.getHandle().playerConnection.sendPacket(packetPlayOutMount);

        packetList.add(packetSlime);
        packetList.add(packetStand);
        packetList.add(packetPlayOutMount);

        updatePackets();
    }

    public void updatePackets() {
        for(Player player : Bukkit.getOnlinePlayers())
            for(Packet packet : packetList)
                ((CraftPlayer)player).getHandle().playerConnection.sendPacket(packet);
    }
}
Использую метод #setPlate() при входе игрока на сервер
 
Если не секрет, зачем делать костыли, а не сделать ником или под ником?
 
Если делать через бакитовский борд апи, у игрока под ником перед твоей кастомной надписью будет выводится скор. Выглядеть это будет примерно так: "0 Премиум" и избавиться от этого, на сколько мне известно, нельзя, так как именно для этих скоров и создавался борд апи
 
Появилась новая проблема
Хочу сажать на игроков стенды, чтобы отображать их донатные ранги
Набросал код, но он работает некорректно: сначала стенд появляется, всё работает, но потом через пару секунд он останавливается на месте и все, получается что он уже не на игроке. Еще, почему-то, у других игроков стенда не видно, хотя пакеты я отправляю всем.
Так же на сервере по какой-то причине остаются старые стенды, не знаю как их удалить
Мой код для наглядности
Код:
public class NameplateUtil {

    private List<Packet> packetList;

    public NameplateUtil() {
        this.packetList = new ArrayList<>();
    }

    public void setPlate(String rank, Player p) {
        Location loc = p.getLocation();
        WorldServer worldServer = ((CraftWorld)p.getWorld()).getHandle();
        EntityArmorStand stand = new EntityArmorStand(worldServer);

        stand.setLocation(loc.getX(), loc.getY(), loc.getZ(), 0, 0);
        stand.setCustomName(rank);
        stand.setCustomNameVisible(true);
        stand.setNoGravity(true);
        stand.setSmall(true);
        stand.setInvisible(true);

        EntitySlime entitySlime = new EntitySlime(worldServer);
        entitySlime.setLocation(loc.getX(), loc.getY(), loc.getZ(), 0, 0);
        entitySlime.setSize(-2, false);
        entitySlime.setInvisible(true);

        entitySlime.getBukkitEntity().addPassenger(stand.getBukkitEntity());

        CraftPlayer craftPlayer = (CraftPlayer) p;
        craftPlayer.addPassenger(entitySlime.getBukkitEntity());


        PacketPlayOutSpawnEntityLiving packetSlime = new PacketPlayOutSpawnEntityLiving(entitySlime);
        ((CraftPlayer)p).getHandle().playerConnection.sendPacket(packetSlime);
        PacketPlayOutSpawnEntityLiving packetStand = new PacketPlayOutSpawnEntityLiving(stand);
        ((CraftPlayer)p).getHandle().playerConnection.sendPacket(packetStand);
        PacketPlayOutMount packetPlayOutMount = new PacketPlayOutMount(entitySlime);
        craftPlayer.getHandle().playerConnection.sendPacket(packetPlayOutMount);

        packetList.add(packetSlime);
        packetList.add(packetStand);
        packetList.add(packetPlayOutMount);

        updatePackets();
    }

    public void updatePackets() {
        for(Player player : Bukkit.getOnlinePlayers())
            for(Packet packet : packetList)
                ((CraftPlayer)player).getHandle().playerConnection.sendPacket(packet);
    }
}
Использую метод #setPlate() при входе игрока на сервер
Вопрос еще актуален
 
Проверь сам, там кода на 3 строчки
Если ты сможешь выводить надпись без скора, тогда моё тебе почтение
Прошу прощения, попутал скорбоард со скором, беру слова обратно
 
@alexandrage
дядя помоги джуниору осилить реализацию этой прекрасной задумки, поделись своим многолетним опытом работы
 
Последнее редактирование:
Код посадки армор стенда на игрока, если я так понял, спавнит на месте игрока, но на +1 Y выше
Код:
ArmorStand stand = p.getWorld().spawn(p.getLocation().add(0, +1, 0), ArmorStand.class);
stand.setGravity(false);
stand.setVisible(false);
 
Вопрос еще актуален
в твоем коде, строчку можно упростить, так как ты уже получил локацию игрока, можно сделать просто вот так
Код:
Location loc = p.getLocation();
stand.setLocation(loc).add(0, 1, 0);

Если тебе локацию стенда на игроке надо получить отдельно, то вот тебе пример
Код:
Location loc = p.getLocation();
Location standloc = loc.clone().add(0, 1, 0);
ArmorStand stand = p.getWorld().spawn(standloc, ArmorStand.class);
stand.setGravity(false);
stand.setVisible(false);
 
Код посадки армор стенда на игрока, если я так понял, спавнит на месте игрока, но на +1 Y выше
Код:
ArmorStand stand = p.getWorld().spawn(p.getLocation().add(0, +1, 0), ArmorStand.class);
stand.setGravity(false);
stand.setVisible(false);
в твоем коде, строчку можно упростить, так как ты уже получил локацию игрока, можно сделать просто вот так
Код:
Location loc = p.getLocation();
stand.setLocation(loc).add(0, 1, 0);

Если тебе локацию стенда на игроке надо получить отдельно, то вот тебе пример
Код:
Location loc = p.getLocation();
Location standloc = loc.clone().add(0, 1, 0);
ArmorStand stand = p.getWorld().spawn(standloc, ArmorStand.class);
stand.setGravity(false);
stand.setVisible(false);
Вопрос был про пакеты, а не стандартный бакит апи
 
Откуда взял FakeEntity? Я чет ищу и не могу найти. В пртокол либе такого нет
Просто мой интерфейс был, создай автогеренатором в иде, или можно без него, если у тебя не будет других фейк ентити. В остальном протоколлиб и пакетврапер к нему.
Реализация на версиях ниже может отличатся.
 
Последнее редактирование:
Просто мой интерфейс был, создай автогеренатором в иде, или можно без него, если у тебя не будет других фейк ентити. В остальном протоколлиб и пакетврапер к нему.
Реализация на версиях ниже может отличатся.
Не спавнится стенд
https://pastebin.com/LqwdnciK
https://pastebin.com/mC95sz6F
 
Назад
Верх