Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

Помогите Как извлечь ник игрока, если он - entity?

LaoTheLizard

Старожил
Пользователь
Баллы
103
Есть такая строка:
Код:
Broadcast.append(ChatColor.RED).append(target.getType().getName());
где target - Entity.

Если target - это моб, то строка извлекает мне его название (например, "Chicken") , но когда target является игроком, то результат уже слово "null".

Если написать так:
Код:
Broadcast.append(ChatColor.RED).append(target.getType().name());
то результат - "PLAYER".

Точно такой же результат, если написать так:
Код:
Broadcast.append(ChatColor.RED).append(target.getType());

Как мне извлечь ник игрока?
 
Есть такая строка:
Код:
Broadcast.append(ChatColor.RED).append(target.getType().getName());
где target - Entity.

Если target - это моб, то строка извлекает мне его название (например, "Chicken") , но когда target является игроком, то результат уже слово "null".

Если написать так:
Код:
Broadcast.append(ChatColor.RED).append(target.getType().name());
то результат - "PLAYER".

Точно такой же результат, если написать так:
Код:
Broadcast.append(ChatColor.RED).append(target.getType());

Как мне извлечь ник игрока?
Для этого нужно target привести к типу Player, там есть метод getName()
 
Den_Abr, понятно.
Сначала было так:
Код:
Entity target = getTarget(player);

И далее по коду все обращения к target обрабатывались нормально.

Я сделал, следуя твоему совету - и согласно моего скудного разумения - так:
Код:
if(getTarget(player) instanceof Player){
                        Player target = (Player) getTarget(player);
                    } else {
                        Entity target = getTarget(player);}

И все строки с участием target, что следуют ниже, теперь пишут ошибку:
target cannot be resolved to a variable

Проблема в том, что изначально объект может быть либо игроком, либо мобом.
Что я делаю не так?
 
Den_Abr, понятно.
Сначала было так:
Код:
Entity target = getTarget(player);

И далее по коду все обращения к target обрабатывались нормально.

Я сделал, следуя твоему совету - и согласно моего скудного разумения - так:
Код:
if(getTarget(player) instanceof Player){
                        Player target = (Player) getTarget(player);
                    } else {
                        Entity target = getTarget(player);}

И все строки с участием target, что следуют ниже, теперь пишут ошибку:


Проблема в том, что изначально объект может быть либо игроком, либо мобом.
Что я делаю не так?
Что за переменная player? Откуда берётся она?
 
Den_Abr, она берется отсюда:
Код:
 @SuppressWarnings("rawtypes")
    public static Entity getTarget(Player player)
{
    if(player == null)
        throw new AssertionError();
    Entity target = null;
    double targetDistanceSquared = 0.0D;
    Vector l = player.getEyeLocation().toVector();
    Vector n = player.getLocation().getDirection().normalize();
    double cos45 = Math.cos(0.78539816339744828D);
    for(Iterator iterator = player.getWorld().getEntitiesByClass(org.bukkit.entity.LivingEntity.class).iterator(); iterator.hasNext();)
    {
        LivingEntity other = (LivingEntity)iterator.next();
        if(other != player && (target == null || targetDistanceSquared > other.getLocation().distanceSquared(player.getLocation())))
        {
            Vector t = other.getLocation().add(0.0D, 1.0D, 0.0D).toVector().subtract(l);
            if(n.clone().crossProduct(t).lengthSquared() < 1.0D && t.normalize().dot(n) >= cos45)
            {
                target = other;
                targetDistanceSquared = target.getLocation().distanceSquared(player.getLocation());
            }
        }
    }

    return target;
}
Этот кусок я нагло спёр из другого плагина. И если не пытаться сделать то, что я сейчас пытаюсь сделать, то он работает. Может, тут что-то тоже нужно переделать?
 
Den_Abr, она берется отсюда:
Код:
 @SuppressWarnings("rawtypes")
    public static Entity getTarget(Player player)
{
    if(player == null)
        throw new AssertionError();
    Entity target = null;
    double targetDistanceSquared = 0.0D;
    Vector l = player.getEyeLocation().toVector();
    Vector n = player.getLocation().getDirection().normalize();
    double cos45 = Math.cos(0.78539816339744828D);
    for(Iterator iterator = player.getWorld().getEntitiesByClass(org.bukkit.entity.LivingEntity.class).iterator(); iterator.hasNext();)
    {
        LivingEntity other = (LivingEntity)iterator.next();
        if(other != player && (target == null || targetDistanceSquared > other.getLocation().distanceSquared(player.getLocation())))
        {
            Vector t = other.getLocation().add(0.0D, 1.0D, 0.0D).toVector().subtract(l);
            if(n.clone().crossProduct(t).lengthSquared() < 1.0D && t.normalize().dot(n) >= cos45)
            {
                target = other;
                targetDistanceSquared = target.getLocation().distanceSquared(player.getLocation());
            }
        }
    }

    return target;
}
Этот кусок я нагло спёр из другого плагина. И если не пытаться сделать то, что я сейчас пытаюсь сделать, то он работает. Может, тут что-то тоже нужно переделать?
А зачем что-то определять, когда можно просто сделать player.getName()
 
Den_Abr, не понял вопроса.
Что сделать-то нужно? Куда и что написать/исправить?
 
Den_Abr, не понял вопроса.
Что сделать-то нужно? Куда и что написать/исправить?
Код:
if(getTarget(player) instanceof Player){
                        Player target = (Player) getTarget(player);
                    } else {
                        Entity target = getTarget(player);}
Код, честно говоря, бредовый. Зачем преобразовывать в игрока преобразованного в сущность игрока?
Имя можно получить сразу из переменной player
 
Den_Abr, я понимаю, о чем ты, но не знаю, как переменную вытащить из одного блока и использовать в другом.

Здесь речь об атакующем и о его цели. player - атакующий. А мне нужен ник цели (если у цели есть ник).
 
Последнее редактирование:
Den_Abr, я понимаю, о чем ты, но не знаю, как переменную вытащить из одного блока и использовать в другом.

Здесь речь об атакующем и о его цели. player - атакующий. А мне нужен ник цели (если у цели есть ник).
Есть эвент специальный - EntityDamageByEntityEvent
 
Den_Abr, да, есть. Но в данной ситуации он не подходит. Потому что здесь энтити-цель не атакуется энтити-атакующим, с точки зрения эвентов. Плагин осуществляет вызов молнии атакующим в место, где стоит цель. Сам плагин работает, но я хочу, чтобы при атаке выводилось сообщение типа "Петя Васечкин призывает силы небесные и молнией поражает Васю Петечкина". Исходя из в-начале-мною-изложенного, если ударить молнией в моба - выводится (это уже работает) сообщение "Петя Васечкин призвал силы небесные и молнией поражает <название моба>. Остается лишь одна задача: сделать, в случае, если молния бьет не в моба, а в игрока, чтобы в фразе вместо <название моба> был <ник игрока>.
 
Тогда так можно
Код:
// тут у нас переменная target, тип Entity
if(target instanceof Player) {
Player p = (Player) target;
// делаем с p всё, что нужно
} else {
делаем с target всё, что нужно
}
 
Den_Abr, спасибо большое, теперь всё работает, как надо.

Есть ещё вопрос:
Когда появляется надпись про моба, она выглядит так: "Петя Васечкин бьет молнией в Enderman". Я могу изобрести велосипед и сделать подмену всех названий мобов вручную, но, я так думаю, там где-то есть готовое решение, обращающееся к некоторых константам прямо в файл из папки lang, что внутри CraftBukkit.jar? Как к ним обратиться?

И ещё вопрос:
Когда я компилирую свой собственный JAR, эклипс выдает мне ошибку:
JAR creation failed. See details for additional information. Resource is out of sync with the file system: '/BoomStick/plugin.yml'.
Мне приходится снимать галочку с plugin.yml, компилировать без него, а потом вручную JAR засовывать его.
Я порылся в интернете насчет этой ошибки, но так и не понял, в чем проблема.
 
И ещё вопрос:
Когда я компилирую свой собственный JAR, эклипс выдает мне ошибку: Мне приходится снимать галочку с plugin.yml, компилировать без него, а потом вручную JAR засовывать его.
Я порылся в интернете насчет этой ошибки, но так и не понял, в чем проблема.
Обнови проект(F5)
Есть ещё вопрос:
Когда появляется надпись про моба, она выглядит так: "Петя Васечкин бьет молнией в Enderman". Я могу изобрести велосипед и сделать подмену всех названий мобов вручную, но, я так думаю, там где-то есть готовое решение, обращающееся к некоторых константам прямо в файл из папки lang, что внутри CraftBukkit.jar? Как к ним обратиться?
Нормальных методов нет, проще самому переводить.
 
Den_Abr, едрён-батон, как же всё просто оказалось! Я думал, проект обновляется, когда я его сохраняю и - уж тем более - при закрытии-открытии эклипса.
Для того, чтобы народ не убивали молниями прямо на их территории - ведь это работает даже сквозь стекло и заборы - я выдал всем флаг Lightning в WorldGuard. Теперь возникла новая дилемма: если пытаться ударить молнией под флаг - молния просто не возникнет, но плата за молнию снимется и в чат выйдет сообщение, что, дескать, такой-то игрок ударил такого-то игрока молнией.
Понимаю, что нужно проверить наличие флага Lightning на координатах target. Нашел эту тему: http://www.rubukkit.org/threads/Нужно-проверить-наличие-флага.45136/ , здесь автор темы послан сюда: http://wiki.sk89q.com/wiki/WorldGuard/Regions/API
Почитал, но не понял, как должен выглядеть конечный код блока.

В общем, сейчас это выглядит так:
Код:
                                              Location targetLoc = target.getLocation();
                                                                                                                                          
                                              if(getWorldGuard().???.???.???) == ???
, где ??? - то, что я не знаю, как должно выглядеть.

По моему разумению, нужно определить, если ли в месте локации регион, а потом проверить наличие у региона нужного флага. Но как это сделать?
 
Последнее редактирование:
Вызывай эвент LightningStrikeEvent, если флаг есть, WG его отменит.
 
Для меня звучит сложно. Если я вызову этот флаг, то как я, в случае отмены молнии, сделаю так, чтобы события, которые я определил в блоке (там, кстати, обрабатывается OnPlayerInteract), который мы обсуждали выше (снятие с игрока level, с предмета - durability, выход в чат сообщения "Петя ударил Ваню"), не случились?
 
if(event.isCancelled())
return; // прекраитить выполнение метода
 
Den_Abr, я честно попробовал, но, видимо, как-то не так.
В общем, вот весь плагин целиком. Закомментированы тут как раз те строки, которыми я пытался обработать отмену молнии. И те строки, где я пытался наладить контакт с WG.
 

Вложения:

  • BoomStick.zip
    BoomStick.zip
    Размер файла
    2,7 КБ
    Просмотров
    4
Den_Abr, я честно попробовал, но, видимо, как-то не так.
В общем, вот весь плагин целиком. Закомментированы тут как раз те строки, которыми я пытался обработать отмену молнии. И те строки, где я пытался наладить контакт с WG.
Код:
ApplicableRegionSet set = WGBukkit.getRegionManager(world).getApplicableRegions(location);

if(set.size() > 0 && !set.allows(DefaultFlag.LIGHTNING)) {    // проверяем, что тут есть регионы и не разрешены молнии
// делаем что-то и заканчиваем
    return;
}
 

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

Назад
Верх