1. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Помогите Пропадает информация в Entity

Тема в разделе "Разработка плагинов для новичков", создана пользователем Loltik, 20 дек 2023.

Статус темы:
Закрыта.
  1. Автор темы
    Loltik

    Loltik Активный участник Пользователь

    Баллы:
    61
    Сохраняю данные MetaData или getPersistentDataContainer в сущность, итог один. Работает, но если игрок уйдёт из чанка с боссом или умрёт рядом с ним, то MetaData или getPersistentDataContainer будет очищено.

    Есть ли замена или способы решения проблемы?

    Paper 1.19.4, Java
     
  2. OJIEKCAHDP

    OJIEKCAHDP Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    OJIEKCAHDP
    Подозреваю, что моб просто исчезает. Поставь тут значение true -> setRemoveWhenFarAway
     
  3. Автор темы
    Loltik

    Loltik Активный участник Пользователь

    Баллы:
    61
    Он же наоборот удаляться будет?
     
  4. Автор темы
    Loltik

    Loltik Активный участник Пользователь

    Баллы:
    61
    Пока-что проблема не решена, я попробовал setRemoveWhenFarAway true и false.
     
  5. Автор темы
    Loltik

    Loltik Активный участник Пользователь

    Баллы:
    61
    Код спавна босса:

     
  6. mirrerror

    mirrerror Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    mirrerror
    попробуй сначала мету устанавливать, а потом использовать методы на боссе
     
  7. Dymeth

    Dymeth Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Метадата не сохраняется на диск, сохраняется только персистент дата контейнер.

    Проблема у тебя не в сохранении персистент даты, а в сохранении моба на диск.
    Ядро в принципе не сохраняет на диск враждебных мобов. Поэтому на всяких фермах на мобов применяют бирку.
    Чтобы моб принудительно сохранялся на диск - используй entity.setPersistent(true).

    Но после этого ты, скорее всего, столкнешься с другой проблемой - дублирование мобов. Ядро будет загружать старого моба с датой, а ты своим кодом будешь спаунить ещё одного, нового. Что с этим делать - решай сам
     
  8. Автор темы
    Loltik

    Loltik Активный участник Пользователь

    Баллы:
    61
    А есть ли замена способу? entity.setPersistent(true) вроде пробовал не помогло, но сейчас ещё раз проверю.
     
  9. Автор темы
    Loltik

    Loltik Активный участник Пользователь

    Баллы:
    61
    Я проверил, он не дублирует, но Metadata всё равно пропадает. Сейчас попробую персистент дата контейнер
     
  10. Автор темы
    Loltik

    Loltik Активный участник Пользователь

    Баллы:
    61
    Такая же ситуация. Ничего не сохраняется и не дублируется при выходе из чанка на некоторое время.
     
  11. Dymeth

    Dymeth Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Убедись, что у тебя действительно одна и та же сущность каждый раз. Для этого можно просто UUID отобразить где-либо.
    И покажи код, где у тебя вызывается спаун сущности
     
  12. Автор темы
    Loltik

    Loltik Активный участник Пользователь

    Баллы:
    61
    Код спавна.

    Сейчас проверю по UUID
     
  13. Автор темы
    Loltik

    Loltik Активный участник Пользователь

    Баллы:
    61
    UUID не меняется, кстати ты мне подсказал одну идею. Возможно сейчас проверю, вдруг сработает.
     
  14. Dymeth

    Dymeth Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Я бы рекомендовал для начала привести порядок в код. Сейчас всё в куче, очень легко запутаться, что-то упустить или перепутать. Я, честно говоря, поначалу я вообще не понял, что происходит в коде. Чуть привёл в порядок, стало яснее.

    Но до сих пор некоторые моменты непонятны - например, где вызывается метод spawnBoss2()? Разны ли String id и boss.getId()? Существует несколько методов спауна боссов? Чем они отличаются между собой? Они между собой не конфликтуют из-за общих мап? Например, из-за "get3.add(id);".
    Вопросы риторические, отвечать не нужно, главное разберись сам.

    Короче говоря, скорее всего, проблема у тебя не в сохранении persistent data container, а именно в логике твоего кода. Либо метод не вызывается, либо вызывается не для той сущности, либо не в нужный момент, либо ты ошибся при выводе UUID, либо что-то ещё. Тем более отрефакторить будет полезно, если у тебя больше одного вида боссов.

    Сам по себе persistent data container работает идеально, если с ядром всё в порядке. Поэтому убедись, что у тебя последний билд Paper для 1.19.4.

    - Удалил явную загрузку чанка. Ядро само сделает это при необходимости
    - В шедулере удалил проверку if(boss2 != null), поскольку переменная никогда не будет нулл
    - Мапу boss переименовал в bossEntities, а переменную boss2 просто в boss
    - Мапу bossBar переименовал в bossBars, а переменную bossBar1 просто в bossBar
    - Переименовал остальные локальные переменные метода, чтобы увеличить читабельность
    - Заменил некоторые устаревшие методы Paper API на актуальные
    - Разделил код на логические методы
    PHP:
    public void spawnBoss2() {
        
    this.damageList null;

        
    String configBossId getRandomBossConfigId();

        
    Boss boss Configs.MAIN_CONFIG.getBossById(configBossId);

        
    String randomBossId boss.getId() + random.nextInt(1000000);
        
    this.getLogger().warning(randomBossId);

        
    LivingEntity bossEntity this.createBossEntity(bossconfigBossId);
        
    this.displayBossEntity(bossbossEntity);
        
    this.applyBossSpheres(bossbossEntityconfigBossIdrandomBossId);

        
    bossEntity.getPersistentDataContainer().set(keyPersistentDataType.STRINGrandomBossId);

        
    bossEntities.put(bossEntityboss);
        
    get2.add(bossEntity.getCustomName());
        
    get3.add(configBossId);

        
    BossBar bossBar this.createBossBar(bossbossEntity);
        
    bossBars.put(randomBossIdbossBar);

        
    BukkitTask task this.getServer().getScheduler().runTaskTimer(thisthis::broadcastBossStatus0L40L);
        
    tasks.put(randomBossIdtask);
    }

    private 
    String getRandomBossConfigId() {
        return 
    this.options[this.random.nextInt(this.options.length)].replace("\"""");
    }

    private 
    LivingEntity createBossEntity(Boss bossString configBossId) {
        
    LivingEntity bossEntity = (LivingEntityboss.getLocation().getWorld().spawnEntity(boss.getLocation(), boss.getType());

        
    this.applyAttributes(bossEntitybossconfigBossId);

        
    bossEntity.setCanPickupItems(false);
        
    bossEntity.setCustomName(boss.getName());
        
    bossEntity.setRemoveWhenFarAway(false);
        
    bossEntity.setCustomNameVisible(true);
        
    bossEntity.setGlowing(true);
        
    bossEntity.setPersistent(true);

        if (
    bossEntity instanceof Zombie zombie) {
            
    zombie.setAdult();
        }

        return 
    bossEntity;
    }

    private 
    void applyAttributes(LivingEntity bossEntityBoss bossString configBossId) {
        
    YamlConfiguration configuration ConfigManager.of("settings.yml").getYamlConfiguration();

        
    AttributeInstance speed bossEntity.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED);
        if (
    speed != null) {
            
    speed.addModifier(new AttributeModifier(
                    
    "GENERIC_MOVEMENT_SPEED",
                    
    speed.getBaseValue() * configuration.getInt("bosses." configBossId ".move"),
                    
    AttributeModifier.Operation.ADD_NUMBER
            
    ));
        }

        
    AttributeInstance maxHealth bossEntity.getAttribute(Attribute.GENERIC_MAX_HEALTH);
        if (
    maxHealth != null) {
            
    double health boss.getHealth();
            
    maxHealth.setBaseValue(health);
            
    bossEntity.setHealth(health);
        }

        
    AttributeInstance damage bossEntity.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE);
        if (
    damage != null) {
            
    damage.setBaseValue(damage.getBaseValue() * configuration.getInt("bosses." configBossId ".damage"));
        }
    }

    private 
    void applyBossSpheres(Boss bossLivingEntity bossEntityString configBossIdString randomBossId) {
        if (
    configuration.getBoolean("bosses." configBossId ".spheres") == true) {
            
    Spheres(bossEntityboss.getName(), randomBossId);
        }
    }

    private 
    BossBar createBossBar(Boss bossLivingEntity bossEntity) {
        
    BossBar bar Bukkit.createBossBar(ColorHelper.colorize(
                
    Configs.MAIN_CONFIG.getBossbar()
                        .
    replace("%name%"boss.getName())
                        .
    replace("%health%"String.valueOf(Math.round(bossEntity.getHealth())))
        ), 
    boss.getColor(), BarStyle.SEGMENTED_12, new BarFlag[0]);

        
    bar.setVisible(true);
        
    bar.setProgress(1.0D);

        
    Bukkit.getOnlinePlayers().forEach(bar::addPlayer);
        return 
    bar;
    }

    private 
    void displayBossEntity(Boss bossLivingEntity bossEntity) {
        
    Location location bossEntity.getLocation();
        
    World world location.getWorld();

        
    world.spawnParticle(Particle.CRIT,
                
    location501110.1);
        
    world.spawnParticle(Particle.ENCHANTMENT_TABLE,
                
    location301110.1);
        
    world.spawnParticle(Particle.FIREWORKS_SPARK,
                
    location201110.1);

        for (
    Player player Bukkit.getOnlinePlayers()) {
            
    Lang.SPAWNED.send(player,
                    new 
    Pair("%id%"boss.getId()),
                    new 
    Pair("%name%"boss.getName())
            );
        }
    }

    private 
    void broadcastBossStatus() {
        
    Server server Bukkit.getServer();

        List<
    Map.Entry<StringInteger>> damageList Handler.getSortedDamageList();
        for (
    int index 0index damageList.size(); index++) {
            
    Map.Entry<StringIntegerentry damageList.get(index);

            
    String playerName entry.getKey();
            
    Player player server.getPlayer(playerName);
            if (
    player == null) continue;

            
    int damage entry.getValue();

            
    Component actionBar Component.text(
                    
    Configs.MAIN_CONFIG.getActionBar()
                            .
    replace("%index%"String.valueOf(index 1))
                            .
    replace("%max%"String.valueOf(damageList.size()))
                            .
    replace("%damage%"String.valueOf(damage))
            );
            
    player.sendActionBar(actionBar);
        }
    }

    И на будущее - код вставлять лучше вот так:
    upload_2023-12-22_16-24-12.png
    В качестве языка выбирай PHP, у него лучше всего подсветка. Получится так же, как под мои спойлером
     
    Последнее редактирование: 22 дек 2023
  15. Автор темы
    Loltik

    Loltik Активный участник Пользователь

    Баллы:
    61
    У меня Purpur. Я сейчас попробую, кое-что сделать, может заработает.
     
  16. Автор темы
    Loltik

    Loltik Активный участник Пользователь

    Баллы:
    61
    Отдельное спасибо, за исправление кода.
     
  17. Автор темы
    Loltik

    Loltik Активный участник Пользователь

    Баллы:
    61
    Возможно проблема в моём ядре. Но я решил проблему другим путём, чтобы он проверял по UUID, а не Metadata и получал сущность через UUID. Спасибо, что решил подсказать как решить проблему, сказав проверить через UUID. Я просто совсем уже забыл про это.

    Спасибо, что помог.

    Тема закрыта.
     
Статус темы:
Закрыта.

Поделиться этой страницей