Хостинг серверов Minecraft playvds.com
  1. Вы находитесь в русском сообществе Bukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на русский язык плагины наших собратьев из других стран.
    Скрыть объявление

Помогите Как правильно выяснить что на игрока не светит солнце?

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

  1. Автор темы
    Mr_RoboMan

    Mr_RoboMan Старожил Пользователь

    Баллы:
    123
    Делаю что-то типо вампира, игрок должен гореть на солнце (и еще там пара эффектов) но только если он не спрятан где-то (дом/пещера/любое непрозрачное покрытие) как можно это красиво выяснить?
     
  2. Хостинг MineCraft
    <
  3. Автор темы
    Mr_RoboMan

    Mr_RoboMan Старожил Пользователь

    Баллы:
    123
    И еще, как правильно выяснить время суток?
    Правилен такой код, или же не совсем точен?
    Код:
    public static TimeOfDay getTimeOfDay(World world) {
            Long time = world.getTime();
            if (time >= 2000 && time <= 10000) return TimeOfDay.DAY;
            if (time >= 10000 && time <= 13000) return TimeOfDay.EVENING;
            if (time >= 13000 && time <= 22000) return TimeOfDay.NIGHT;
            if (time >= 22000 && time <= 2000) return TimeOfDay.MORNING;
            return null;
        }
     
  4. Dereku

    Dereku Старожил

    Баллы:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    Можно сделать костыльно - брать блок под игроком и проверять его свет. Правда, упираться будет в блоки, которые сами являются источником света.
     
  5. Автор темы
    Mr_RoboMan

    Mr_RoboMan Старожил Пользователь

    Баллы:
    123
    Ээ... Как-т слишком костыльн...
     
  6. CoolBoy

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

    Баллы:
    96
    Skype:
    thecoolboy2070
    Имя в Minecraft:
    CoolBoy
    Насколько я знаю, существует некий диапазон света от 0 до 14. Только солнечный свет может дать 14. Свет других блоков даёт от 13 и меньше. Остаётся брать блок игрока (я бы не стал брать блок на котором стоит игрок, я бы делал так - player.getLocation().getBlock().add(0, 2, 0); что вернёт нам блок на уровне головы игрока.) Дальше можно просто брать освещённость этого блока и если = 14 - поджигать игрока. Опять же, с освещением работал всего один раз, могу ошибаться.
     
  7. Dereku

    Dereku Старожил

    Баллы:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    И он бывает только от 6000 до 12000 суточных тиков.
     
  8. CoolBoy

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

    Баллы:
    96
    Skype:
    thecoolboy2070
    Имя в Minecraft:
    CoolBoy
    Так и думал что вы меня поправите. Хм... и каким тогда образом можно определить - от солнца этот свет, или от факела / лампы / любого другого светящегося предмета?
     
  9. Dereku

    Dereku Старожил

    Баллы:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    Да хрен его знает.
     
  10. Автор темы
    Mr_RoboMan

    Mr_RoboMan Старожил Пользователь

    Баллы:
    123
    Хм, поправьте меня если я не правильно вас обоих понял,
    получается самый яркий солнечный свет (14) бывает только с 6000 до 12000 суточных тиков,
    тогда, я могу считать именно этот промежуток "днем" и только в этот промежуток времени проверять, надо ли игроку гореть, и если освещенность блока = 14 то сжигать игрока.. А собственно как получить освещение блока?
    Например тут:
    Это должно вернуть блок воздуха (ведь это блок на уровне головы, т.е. кроме воздуха там ничего быть не может), и как мне получить освещенность(и можно ли это вообще сделать для блока воздуха(и можно ли вообще блок воздуха считать блоком? XD))?
     
  11. CoolBoy

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

    Баллы:
    96
    Skype:
    thecoolboy2070
    Имя в Minecraft:
    CoolBoy
    Готов вас удивить - блок воздуха является блоком и даже может иметь метадату. Получить свет от блока воздуха не так уж и сложно:
    Код:
       Block block = player.getWorld().getLocation().getBlock().add(0, 2, 0);
       BlockFace block_face = block.getBlockFace(BlockFace.UP);
       int level = block_face.getLightLevel();
    
    Как всегда без IDE, поэтому могут быть ошибки. Скорее всего у метода blockFace нельзя взять lightLevel.
    Также могут быть грамматические ошибки в названии методов / ошибки синтаксиса.
     
    Последнее редактирование: 21 апр 2016
  12. Автор темы
    Mr_RoboMan

    Mr_RoboMan Старожил Пользователь

    Баллы:
    123
    Я удивлен :D
    Почему-то всегда думал что блока воздуха как такового не существует - просто пустое место..
    Буду знать, благодарю))
    Пока-что буду тестировать, отпишусь как проверю все)[DOUBLEPOST=1461309651,1461258750][/DOUBLEPOST]В общем, проверка на солнце работает как надо, но теперь я пытаюсь выяснить как правильно получить время суток...
    Итак, сутки в майне = 20 минут = 20*60(секунд)*20(тиков) = 24000 тиков.
    День = 10 минут = 10*60(секунд)*20(тиков) = 12000 тиков.
    Вечер = 1,5 минут = 1.5*60(секунд)*20(тиков) = 1800 тиков.
    Ночь = 7 минут = 7*60(секунд)*20(тиков) = 8400 тиков.
    Утро = 1,5 минут = 1.5*60(секунд)*20(тиков) = 1800.
    День начинается с 0 тиков, т.е. сразу с 0, значит сначало идет день 0-12000, потом идет вечер 12000-13800, потом идет ночь 13800-22200, потом идет утро 22200-24000...

    Я все правильно сказал, или где-то я не прав?[DOUBLEPOST=1461310402][/DOUBLEPOST]Стоп... Я понял свою ошибку... Я просто пытался этим же методом выяснить светит ли на игрока солнце утром и вечером XD
    Думаю это почти невозможно, поэтому оставлю горение только днем)[DOUBLEPOST=1461310485][/DOUBLEPOST]
    Вот возникает вопрос только тут...
    Разве я ошибся в расчета выше? Разве не от 0 до 12000 суточных тиков? Или я не правильно понял систему отсчета тиков в майне?
     
  13. CoolBoy

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

    Баллы:
    96
    Skype:
    thecoolboy2070
    Имя в Minecraft:
    CoolBoy
    Дело в том, что в твоём методе (смотришь день сейчас или нет и если день вызывать горение) игрок будет гореть даже в зданиях и под землёй. Тогда нужно смотреть освещение блоков и если <10 тушить игрока. Также если игрок <120 (ну или со скольки там море начинается) блоков по y -> тушить игрока. Но опять же - это теория. На практике нужно проводить огромное количество тестов.
     
  14. Автор темы
    Mr_RoboMan

    Mr_RoboMan Старожил Пользователь

    Баллы:
    123
    Я решил не запариваться, сделал вот так, вроде все работает как надо)
    Код:
    public static boolean needDayBurn(Player player) {
            if (player.getInventory().getHelmet() != null) return false;
            if (player.getGameMode() == GameMode.CREATIVE) return false;
            Block block1 = player.getLocation().add(0, 1, 0).getBlock();
            if (block1.getType() == Material.WATER || block1.getType() == Material.STATIONARY_WATER) return false;
            Block block = player.getLocation().getBlock();
            if (block.getType() == Material.WATER || block.getType() == Material.STATIONARY_WATER) return false;
            return block1.getLightLevel() >= 14;
        }
    Код:
    public void addEffects() {
            for (Player p : Bukkit.getOnlinePlayers()) {
                try {
                    if (!GoodAPI.isOnAuth(p)) {
                        ServerFile playerFile = ServerFile.getInstance(p.getUniqueId().toString(), ServerFile.ServerFileType.PLAYER);
                        if (playerFile.isSet("RACE")) {
                            Biome biome = p.getLocation().getWorld().getBiome((int) p.getLocation().getX(), (int) p.getLocation().getZ());
                            Race race = Race.valueOf(playerFile.getString("RACE"));
                            if (race.getBiome().toString().equals(biome.toString()))
                                for (PotionEffect effect : race.getEffects()) p.addPotionEffect(effect);
                            if (race.burnAtDay() && GoodAPI.needDayBurn(p)) {
                                p.setFireTicks(23);
                                p.removePotionEffect(PotionEffectType.WEAKNESS);
                                p.removePotionEffect(PotionEffectType.SLOW);
                                p.removePotionEffect(PotionEffectType.BLINDNESS);
                                p.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, 63, 1), true);
                                p.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 63, 2), true);
                                p.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 63, 3), true);
                            }
    
                        }
                    }
                } catch (Exception e) {
                    Main.standardCatchException(e, p);
                }
            }
        }
    Код:
    public void activate() {
            Bukkit.getScheduler().runTaskTimer(Main.JP, this::addEffects, 20L, 20L);
        }
    [DOUBLEPOST=1461312315,1461311779][/DOUBLEPOST]То-есть я решил вообще не проверять время суток, а проверять освещение, ведь освещение 14 может быть только от солнца :D
     
  15. Dereku

    Dereku Старожил

    Баллы:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    Есть какой то метод, который говорит, видит ли этот блок небо или нет. Вот его и можно юзать.
     
  16. Автор темы
    Mr_RoboMan

    Mr_RoboMan Старожил Пользователь

    Баллы:
    123
    Да мне в принципе вполне подходит вариант поджигать игрока чекая освещение блока на уровне его головы...
    Если 14 - поджигать, если нет - значит он не под солнцем!
     
  17. CoolBoy

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

    Баллы:
    96
    Skype:
    thecoolboy2070
    Имя в Minecraft:
    CoolBoy
    Тебе посоветовали более точные методы :)
     
  18. Автор темы
    Mr_RoboMan

    Mr_RoboMan Старожил Пользователь

    Баллы:
    123
    Ну... Я не вижу минусов у того который уже использую :)
     
  19. CoolBoy

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

    Баллы:
    96
    Skype:
    thecoolboy2070
    Имя в Minecraft:
    CoolBoy
    Ещё про лаву не забудьте =)
     
  20. Автор темы
    Mr_RoboMan

    Mr_RoboMan Старожил Пользователь

    Баллы:
    123
    Ладно... Убедили, протестил - огонь обходит мою проверку (но не факелы - факелы имеют уровень света 13)..
    Но как сделать лучше я не понял...[DOUBLEPOST=1461334604,1461329468][/DOUBLEPOST]Решение:
    Код:
    return block1.getLightFromSky() >= 15;
     

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