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

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

Discussion in 'Разработка плагинов для новичков' started by Mr_RoboMan, Apr 21, 2016.

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

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

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

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

    Trophy Points:
    123
    И еще, как правильно выяснить время суток?
    Правилен такой код, или же не совсем точен?
    Code:
    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 Старожил

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

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

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

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

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

    Dereku Старожил

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

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

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

    Dereku Старожил

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

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

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

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

    Trophy Points:
    96
    Skype:
    thecoolboy2070
    Имя в Minecraft:
    CoolBoy
    Готов вас удивить - блок воздуха является блоком и даже может иметь метадату. Получить свет от блока воздуха не так уж и сложно:
    Code:
       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.
    Также могут быть грамматические ошибки в названии методов / ошибки синтаксиса.
     
    Last edited: Apr 21, 2016
  12. Автор темы
    Mr_RoboMan

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

    Trophy Points:
    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 Активный участник Пользователь

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

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

    Trophy Points:
    123
    Я решил не запариваться, сделал вот так, вроде все работает как надо)
    Code:
    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;
        }
    Code:
    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);
                }
            }
        }
    Code:
    public void activate() {
            Bukkit.getScheduler().runTaskTimer(Main.JP, this::addEffects, 20L, 20L);
        }
    [DOUBLEPOST=1461312315,1461311779][/DOUBLEPOST]То-есть я решил вообще не проверять время суток, а проверять освещение, ведь освещение 14 может быть только от солнца :D
     
  15. Dereku

    Dereku Старожил

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

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

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

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

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

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

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

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

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

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

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

Share This Page