Войти или зарегистрироваться

Помогите Событие выдачи игроку опыта

CraftCoder

Старожил
Пользователь
Баллы
108
Имя в Minecraft
CraftCoderr
Как отследить событие выдачи игроку опыта командой /xp или модами(думаю в модах xp выдается таким же образом что и команда /xp)? Если слушать PlayerExpChangeEvent то при подбирании сфер опыта срабатывает, а при команде /xp не срабатывает.
 
Костыльный способ: перезаписывать всех игроков своими, наследующими правильных, и с перезаписанным setExp().
 
Костыльный способ: перезаписывать всех игроков своими, наследующими правильных, и с перезаписанным setExp().
Таким образом в метод setExp добавить вызов эвента PlayerExpChangeEvent? Как-то слишком костыльно... Может еще как-то можно?
 
@CraftCoder
Я бы не сказал, что это костыльно. Лично на мой взгляд, это должно было быть добавлено изначально в setExp()
Другой вариант - только слушать раз в тик сколько было/сколько стало опыта и самому создавать PlayerExpChangeEvent (а лучше - аналог, чтобы с родным событием не путать).
 
@CraftCoder
Я бы не сказал, что это костыльно. Лично на мой взгляд, это должно было быть добавлено изначально в setExp()
Другой вариант - только слушать раз в тик сколько было/сколько стало опыта и самому создавать PlayerExpChangeEvent (а лучше - аналог, чтобы с родным событием не путать).
Если это не костыльно, то можно пожалуйста код, а то я понял что вы имеете в виду, а как сделать не понял.
 
Java:
    @EventHandler
    public void onExpCmd(PlayerCommandPreprocessEvent e) {
        if(e.getMessage().startsWith("/xp")) {
            Bukkit.getPluginManager().callEvent(new PlayerExpChangeEvent(e.getPlayer(), /*номер аргумента*/));
        }
    }
 
Java:
    @EventHandler
    public void onExpCmd(PlayerCommandPreprocessEvent e) {
        if(e.getMessage().startsWith("/xp")) {
            Bukkit.getPluginManager().callEvent(new PlayerExpChangeEvent(e.getPlayer(), /*номер аргумента*/));
        }
    }
это мне не подходит, т.к. мод кастом нпс, скорее всего тоже выдает методом setExp и если я просто буду слушать команду xp, то мне это не поможет.
 
это мне не подходит, т.к. мод кастом нпс, скорее всего тоже выдает методом setExp и если я просто буду слушать команду xp, то мне это не поможет.
Я пока тогда не знаю, чем помочь. По-любому что-то с командами делать надо будет. Попробуй пакеты, штоле.
 
Я пока тогда не знаю, чем помочь. По-любому что-то с командами делать надо будет. Попробуй пакеты, штоле.
Ну какие пакеты то?
Нормальный способ же предложили - шедулером сверять значения опыта игрока прошлое и предыдущее и кинуть эвент в случае различия.
 
Где это предложили? :D Или я слепой?
Тут:
@CraftCoder
Я бы не сказал, что это костыльно. Лично на мой взгляд, это должно было быть добавлено изначально в setExp()
Другой вариант - только слушать раз в тик сколько было/сколько стало опыта и самому создавать PlayerExpChangeEvent (а лучше - аналог, чтобы с родным событием не путать).
 
Слушать раз в тик сколько было/сколько стало опыта и самому создавать PlayerExpChangeEvent (а лучше — аналог, чтобы с родным событием не путать).
Отличный вариант, плюс если требуемая реализация не требует супер-мгновенности, то замедлить до 1 тика в секунду или реже.
 
Отличный вариант, плюс если требуемая реализация не требует супер-мгновенности, то замедлить до 1 тика в секунду или реже.
Чем чаще проверка, тем точнее результат и отсутствие возможности куда нибудь спустить опыт.
Асинхронный ежетиковый шедулер тут в самый раз, хотя бросаемые эвенты получатся тоже асинхронные...
 
@Den_Abr
В асинхронном шедулере смысла нет - тут нет такой нагрузки, что тормозило бы основной поток.
Тут другой момент. Если создавать именно событие PlayerExpChangeEvent, то можно столкнуться с тем, что оно будет дублироваться.
Т.е. будет вызываться родное событие, а потом то, которое создаем мы. Соответственно это нужно тоже учитывать.
 
Конечная нагрузка это та, которая будет в теле вызываемого события, поэтому программист его "тела" должен решать, какие действия предпринимать синхронно, а какие отпускать в параллель. Так что я согласен с fromgate. А насчёт количества тиков в запланированном шедулере — можно вынести int в конфиг (config.yml/internal.events.onExpChange.granularity) и подбирать в зависимости от конкретной обстановки.
 
Мега-идея - в методе setExp и т.д вызывать эвент. Правда, для этого чутка перелопатить классы придется, но ничего страшного :D
 
Назад
Верх