Помогите NPC + NBT + Skin + Navigation

  • Автор темы Автор темы Dymeth
  • Дата начала Дата начала
Статус
Закрыто для дальнейших ответов.

Dymeth

Активный участник
Пользователь
Баллы
98
Имя в Minecraft
Dymeth
Привет всем.

Нужен способ...
1) Создать энтити-модельку игрока (NPC)
2) Применить на неё NBT-теги, спаршеные из строки обычного майновского формата
3) Применить на неё скин по профилю (texture+signature)
4) Заставить её передвигаться его по заданной траектории
5) Желательно ещё, чтобы NPC автоматически поворачивались к игроку

Все 4 пункта совместить не удаётся, выходят только такие два варианта:
1) Создать через Citizens, применить скин, заставить передвигаться. А НБТ в пролёте, т.к. применяется через NMS, который в NPC от Citizens не катируется. По этой же причине нельзя применять скины из LibsDisguises
2) Создать зомби/жителя через Bukkit, отключить AI, применить скин через LibsDisguises, повесить NBT-теги. Передвижение по траектории в пролёте, т.к. в бакките нет данного функционала. Для передвижения предлагают использовать BKCommonLib, но проблема в том, что при замене EntityiController'а перестаёт работать setRemoveWhenFarAway (он же же setPersistent).
UPD: На новых версиях добавили апи для управления передвижением, хотя оно и не такое гибкое.

В распоряжении:
1) Paper 1.16.5
2) ProtocolLib последней версии
3) Citizens последнего билда под 1.16.5
4) BKCommonLib последнего билда под 1.16.5
5) LibsDisguises последнего билда под 1.16.5

При необходимости готов подключить дополнительные зависимости

PHP:
>> String nbt;

Object nmsNbt = net.minecraft.server.VER.MojangsonParser.parse(nbt);
NbtBase<?> wrappedNbt = com.comphenix.protocol.wrappers.nbt.NbtFactory.fromNMSCompound(nmsNbt);

PHP:
>> org.bukkit.entity.Entity bukkitEntity;

net.minecraft.server.VER.Entity nmsEntity = ((org.bukkit.craftbukkit.VER.entity.CraftEntity) bukkitEntity).getHandle();
nmsEntity.a(wrappedNbt.getHandle());

PHP:
>> String texture; // base64
>> String signature;

com.comphenix.protocol.wrappers.WrappedGameProfile profile = new WrappedGameProfile(UUID.randomUUID(), ChatColor.RESET.toString());
profile.getProperties().put("textures", new WrappedSignedProperty("textures", texture, signature));
me.libraryaddict.disguise.disguisetypes.PlayerDisguise disguise = new PlayerDisguise(ChatColor.RESET.toString());
disguise.setSkin(profile);
 
Последнее редактирование:
Можно продолжить по первому варианту. В Citizens можно из NPC можно получить обычного баккитовского ентити.
PHP:
NPC selectedNPC = CitizensAPI.getDefaultNPCSelector().getSelected(sender);
Entity entity = selectedNPC.getEntity();
Дальше уже этой сущности суй нужные теги. Своими средствами, или чужими библиотеками типа этой https://www.spigotmc.org/resources/nbt-api.7939/.
 
Можно продолжить по первому варианту. В Citizens можно из NPC можно получить обычного баккитовского ентити.
PHP:
NPC selectedNPC = CitizensAPI.getDefaultNPCSelector().getSelected(sender);
Entity entity = selectedNPC.getEntity();
Дальше уже этой сущности суй нужные теги. Своими средствами, или чужими библиотеками типа этой https://www.spigotmc.org/resources/nbt-api.7939/.

А НБТ в пролёте, т.к. применяется через NMS, который в NPC от Citizens не катируется. По этой же причине нельзя применять скины из LibsDisguises
Это значит, что применять NBT на bukkit/nms entity просто-напросто бесполезно.
 
Это значит, что применять NBT на bukkit/nms entity просто-напросто бесполезно.
Не совсем бесполезно. Да, такие данные не сохраняются ведром, но можно заделать свой костыль для их сохранения и загрузки.
 
Не совсем бесполезно. Да, такие данные не сохраняются ведром, но можно заделать свой костыль для их сохранения и загрузки.
Причем тут загрузка и сохранение? Они как в принципе не применяются на NPC из Citizens. Или я делаю что-то не так?
 
Причем тут загрузка и сохранение? Они как в принципе не применяются на NPC из Citizens. Или я делаю что-то не так?
Я щас попробовал получить и присвоить хп непися через NBTAPI, все получилось.

PHP:
NPC selectedNPC = CitizensAPI.getDefaultNPCSelector().getSelected(sender);

if(selectedNPC != null){
   Entity entity = selectedNPC.getEntity();
   NBTEntity nbt = new NBTEntity(selectedNPC.getEntity());
   sender.sendMessage("Health: " + nbt.getDouble("Health"));
}
Если присвоить другое значение и опять вывести - выводит корректно. Хз конечно как с остальными свойствами, проверял только на этом.
 
Я щас попробовал получить и присвоить хп непися через NBTAPI, все получилось.

PHP:
NPC selectedNPC = CitizensAPI.getDefaultNPCSelector().getSelected(sender);

if(selectedNPC != null){
   Entity entity = selectedNPC.getEntity();
   NBTEntity nbt = new NBTEntity(selectedNPC.getEntity());
   sender.sendMessage("Health: " + nbt.getDouble("Health"));
}
Если присвоить другое значение и опять вывести - выводит корректно. Хз конечно как с остальными свойствами, проверял только на этом.
Я NBT использую в первую очередь для визуальной кастомизации мобов.
Поэтому важно, чтобы в первую очередь на клиенте всё нормально отображалось.
Вот пример NBT для зомби с мечом в руке:
{HandItems:[{Count:1,id:iron_sword},{}]}
Такие вещи спокойно задаются через API Citizens, но вот тем способом, что я привёл, сделать это не удаётся.
Другого способа назначать NBT из строки мобу я не знаю
 
Я NBT использую в первую очередь для визуальной кастомизации мобов.
Поэтому важно, чтобы в первую очередь на клиенте всё нормально отображалось.
Вот пример NBT для зомби с мечом в руке:
{HandItems:[{Count:1,id:iron_sword},{}]}
Такие вещи спокойно задаются через API Citizens, но вот тем способом, что я привёл, сделать это не удаётся.
Другого способа назначать NBT из строки мобу я не знаю
Если я тебя правильно понял:
PHP:
NBTEntity nbt = new NBTEntity(selectedNPC.getEntity());
NBTCompound compound = new NBTContainer("{HandItems:[{Count:1,id:iron_sword},{}]}");
nbt.mergeCompound(compound);
Работает, проверял. Но опять же до рестарта ¯\_(ツ)_/¯
 
Если я тебя правильно понял:
PHP:
NBTEntity nbt = new NBTEntity(selectedNPC.getEntity());
NBTCompound compound = new NBTContainer("{HandItems:[{Count:1,id:iron_sword},{}]}");
nbt.mergeCompound(compound);
Работает, проверял. Но опять же до рестарта ¯\_(ツ)_/¯
Окей, похоже, я делаю что-то не так. На досуге попробую разобраться.
Спасибо за помощь
 
Если я тебя правильно понял:
PHP:
NBTEntity nbt = new NBTEntity(selectedNPC.getEntity());
NBTCompound compound = new NBTContainer("{HandItems:[{Count:1,id:iron_sword},{}]}");
nbt.mergeCompound(compound);
Работает, проверял. Но опять же до рестарта ¯\_(ツ)_/¯
Спустя 1.5 года дошли руки заняться вопросом.
К сожалению, так и не смог заставить работать это дело.

Делал это:
- Создал чистый сервер на Paper 1.16.5, установил туда Citiznes и NBTAPI (последние билды)
- Написал простенький плагин
PHP:
    @EventHandler
    private void on(PlayerCommandPreprocessEvent event) {
        if (!event.getMessage().equalsIgnoreCase("/nbttest")) return;
        event.setCancelled(true);
        NPC selectedNPC = CitizensAPI.getDefaultNPCSelector().getSelected(event.getPlayer());
        if(selectedNPC == null) {
            event.getPlayer().sendMessage("NPC не выбран");
            return;
        }
        NBTEntity nbt = new NBTEntity(selectedNPC.getEntity());
        NBTCompound compound = new NBTContainer("{HandItems:[{Count:1,id:iron_sword},{}]}");
        nbt.mergeCompound(compound);
        event.getPlayer().sendMessage("Применили NBT");
    }
- Зашёл на сервер, создал NPC командой /npc create test
- Выполнил команду /nbttest
- Получил ответ "Применили NBT", однако меч у руке не появился. Моделька NPC осталась без изменений

Что я делаю не так?
 
2) Создать зомби/жителя через Bukkit, отключить AI, применить скин через LibsDisguises, повесить NBT-теги. Передвижение по траектории в пролёте, т.к. в бакките нет данного функционала. Для передвижения предлагают использовать BKCommonLib, но проблема в том, что при замене EntityiController'а перестаёт работать setRemoveWhenFarAway (он же же setPersistent).
На Paper у Mob можно получить Pathfinder и послать моба куда нужно. Вряд ли сработает с отключением интеллекта - в зависимости от требуемой ситуации можно обойтись обычной отменой события EntityTargetEvent, либо идти дальше и подчистить задачи.
 
Спустя 1.5 года дошли руки заняться вопросом.
К сожалению, так и не смог заставить работать это дело.

Делал это:
- Создал чистый сервер на Paper 1.16.5, установил туда Citiznes и NBTAPI (последние билды)
- Написал простенький плагин
PHP:
    @EventHandler
    private void on(PlayerCommandPreprocessEvent event) {
        if (!event.getMessage().equalsIgnoreCase("/nbttest")) return;
        event.setCancelled(true);
        NPC selectedNPC = CitizensAPI.getDefaultNPCSelector().getSelected(event.getPlayer());
        if(selectedNPC == null) {
            event.getPlayer().sendMessage("NPC не выбран");
            return;
        }
        NBTEntity nbt = new NBTEntity(selectedNPC.getEntity());
        NBTCompound compound = new NBTContainer("{HandItems:[{Count:1,id:iron_sword},{}]}");
        nbt.mergeCompound(compound);
        event.getPlayer().sendMessage("Применили NBT");
    }
- Зашёл на сервер, создал NPC командой /npc create test
- Выполнил команду /nbttest
- Получил ответ "Применили NBT", однако меч у руке не появился. Моделька NPC осталась без изменений

Что я делаю не так?
Непись со скином это обычный Player же. Можно выдать предмет обычным способом как игроку.
 
На Paper у Mob можно получить Pathfinder и послать моба куда нужно. Вряд ли сработает с отключением интеллекта - в зависимости от требуемой ситуации можно обойтись обычной отменой события EntityTargetEvent, либо идти дальше и подчистить задачи.
Да, возможность задавать путь движения, наконец, появилась в API. И мы это активно используем. Так что вопрос про передвижение и в целом интеллект уже можно считать неактуальным. Сейчас из проблем осталась лишь невозможность кастомизировать внешний вид сущностям из Citizens. Хотя, кажется, я могу использовать вариант с баккитовскими сущностями вместо Citizens. Чуть позже это проверю.

Непись со скином это обычный Player же. Можно выдать предмет обычным способом как игроку.
Возможно и так, но я хочу делать это именно посредством задания NBT. NBT у нас подгружается из конфигов. Но, как уже писал выше, это не работает так, как я хочу. Вижу пока единственную альтернативу - парсить NBT самостоятельно и делать выдачу параметров каждому отдельному мобу: игрокам элементы брони, эндерменам блок у руке, овцам цвет шерсти и так далее. Но это слишком ресурсозатратно.
 
Последнее редактирование:
игрокам элементы брони, эндерменам блок у руке, овцам цвет шерсти и так далее. Но это слишком ресурсозатратно.
Это все делается через ведроапи. Такое чувство, что ты только вчера начал ведро изучать.
 
Это все делается через ведроапи. Такое чувство, что ты только вчера начал ведро изучать.
Для мобов, созданных через Citizens, бесполезно пытаться применять NBT. Я это пробовал делать через NBTAPI, выше об этом рассказано. В самом бакките, кстати, до сих пор нет способа применять NBT из строки на моба. Только сеттерами менять отдельные характеристики, но нереально сделать поддержку всех мобов и обновлять это с выходом новых версий. Да и потом NBT в виде строки - это универсальный и удобный формат. И я хочу его придерживаться.

А вот вариант отказа от Citizens и перехода на Bukkit AI + LibsDisguises вполне реален в связи с появлением апи для работы с интеллектом (в т.ч. навигацией). В 1.13.2 его ещё не было, в 1.16.5 уже есть.
Скоро буду это пробовать
 
Последнее редактирование:
Для мобов, созданных через Citizens, бесполезно пытаться применять NBT. Я это пробовал делать через NBTAPI, выше об этом рассказано. В самом бакките, кстати, до сих пор нет способа применять NBT из строки на моба. Только сеттерами менять отдельные характеристики, но нереально сделать поддержку всех мобов и обновлять это с выходом новых версий. Да и потом NBT в виде строки - это универсальный и удобный формат. И я хочу его придерживаться.

А вот вариант отказа от Citizens и перехода на Bukkit AI + LibsDisguises вполне реален в связи с появлением апи для работы с интеллектом (в т.ч. навигацией). В 1.13.2 его ещё не было, в 1.16.5 уже есть.
Скоро буду это пробовать
Что там обновлять то? Ведро апи стабилен от версии к версии. Только в переходе на 1.13 были изменения значительные. И то это касалось предметов в основном и чанков. А вот нмс как раз таки совсем не стабильный.
 
Что там обновлять то? Ведро апи стабилен от версии к версии. Только в переходе на 1.13 были изменения значительные.
Добавляются новые мобы, у старых новые характеристики, а старые устаревают. Это происходит постоянно. При переходе на новую версию я не хочу тратить время на обновление всего этого. Не хочу вводить новых параметров в конфиг, после чего им ещё и документацию писать.
Хочу, чтобы люди использовали уже готовые генераторы NBT, которые обновляются чужими руками и ощутимо быстрее
 
А в чем проблема использовать мобов с LibsDisguises?
Похоже, что ни в чём. Просто словил тупняк из-за того, что не перечитал собственную же тему.
Сейчас уже отказался от Citizens, и всё работает.

Единственное - сложновато было переводить навигацию с Citizens на Bukkit.
Пара интересных ссылок по ИИ, если кому надо:
https://papermc.io/javadocs/paper/1.16/com/destroystokyo/paper/entity/ai/VanillaGoal.html
https://pastebin.com/QE4qEC1s

Вот такое чудо появилось в 1.15. Тему создавал ещё на 1.13, когда данного апи не существовало. Прям ощущается прогресс.

Спасибо всем, кто помогал!
 
Последнее редактирование:
Статус
Закрыто для дальнейших ответов.
Назад
Верх