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

Помогите Подсветка игрока при взгляде на него

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

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

    laaanov Активный участник

    Баллы:
    61
    Имя в Minecraft:
    laaanov
    Добрый день. Я полный профан в написании плагинов, но недавно появилась потребность в написании подобного плагина:
    При наводке курсора на игрока, его модель должна быть подсвечена только для игрока, на которого он смотрит. Так же, когда игрок отводит прицел от другого игрока - обводка должна быть убрана.

    Изначально мне посоветовали написать подобный код:

    Код:
    import org.bukkit.Bukkit;
    import org.bukkit.entity.Player;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.util.Vector;
    import net.minecraft.server.v1_12_R1.PacketPlayOutEntityEffect;
    import org.bukkit.Location;
    import java.util.*;
    import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
    import net.minecraft.server.v1_12_R1.MobEffect;
    import net.minecraft.server.v1_12_R1.MobEffectList;
    
    
    public class Main extends JavaPlugin {
        public static void glowPlayer(Player who, Player whom) { //подсветка
            int entityId = whom.getEntityId();
            PacketPlayOutEntityEffect packet = new PacketPlayOutEntityEffect(entityId, new MobEffect(MobEffectList.fromId(24)));
            ((CraftPlayer)who).getHandle().playerConnection.sendPacket(packet);
        }
      
        public Player tracePlayer(Player who, int distance) { //получаем игрока, на которого  смотрим
             Location loc = who.getLocation();
             Player whom = null;
             List<Player> players = getNearbyPlayers(loc, distance);
             Vector v = who.getLocation().getDirection();
             for (Player p : players) {
                 if (p.getLocation().toVector().equals(v)) {
                     whom = p;
                     break;
                 }
             }
             return whom;
         }
    
        public static List<Player> getNearbyPlayers(Location location, int distance) { //код, который я обычно использую
            List<Player> list = new ArrayList<Player>();                                                 //для получения ближайших игроков
            for (Player p : Bukkit.getServer().getOnlinePlayers())
                if (p.getLocation().distance(location) <= distance)
                    list.add(p);
            return list;
    
        }
    }
    Но он просто не работал (не подсвечивал игроков). Обратившись на зарубежный ресурс, у меня вышел подобный код:

    Код:
    import org.apache.commons.lang.reflect.FieldUtils;
    import org.bukkit.Bukkit;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.event.player.PlayerQuitEvent;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.util.Vector;
    import net.minecraft.server.v1_12_R1.PacketPlayOutEntityMetadata;
    
    import org.bukkit.Location;
    import java.util.*;
    import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
    
    import net.minecraft.server.v1_12_R1.DataWatcher;
    import net.minecraft.server.v1_12_R1.EntityPlayer;
    
    
    public class Main extends JavaPlugin implements Listener {
     
        public static void glowPlayer(Player glowingPlayer, Player sendPacketPlayer, boolean glow) {
            try {
                EntityPlayer entityPlayer = ((CraftPlayer) glowingPlayer).getHandle();
    
                DataWatcher dataWatcher = entityPlayer.getDataWatcher();
    
                entityPlayer.glowing = glow; // For the update method in EntityPlayer to prevent switching back.
    
                // The map that stores the DataWatcherItems is private within the DataWatcher Object.
                // We need to use Reflection to access it from Apache Commons and change it.
                Map<Integer, DataWatcher.Item<?>> map = (Map<Integer, DataWatcher.Item<?>>) FieldUtils.readDeclaredField(dataWatcher, "d", true);
    
                // Get the 0th index for the BitMask value. http://wiki.vg/Entities#Entity
                @SuppressWarnings("rawtypes")
                DataWatcher.Item item = map.get(0);
                byte initialBitMask = (Byte) item.b(); // Gets the initial bitmask/byte value so we don't overwrite anything.
                byte bitMaskIndex = (byte) 0x40; // The index as specified in wiki.vg/Entities
                if (glow) {
                    item.a((byte) (initialBitMask | 1 << bitMaskIndex));
                } else {
                    item.a((byte) (initialBitMask & ~(1 << bitMaskIndex))); // Inverts the specified bit from the index.
                }
    
                PacketPlayOutEntityMetadata metadataPacket = new PacketPlayOutEntityMetadata(glowingPlayer.getEntityId(), dataWatcher, true);
    
                ((CraftPlayer) sendPacketPlayer).getHandle().playerConnection.sendPacket(metadataPacket);
            } catch (IllegalAccessException e) { // Catch statement necessary for FieldUtils.readDeclaredField()
                e.printStackTrace();
            }
        }
     
        public Player tracePlayer(Player who, int distance) { //getting player, on who we looking
             Location loc = who.getLocation();
             Player whom = null;
             List<Player> players = getNearbyPlayers(loc, distance);
             Vector v = who.getLocation().getDirection();
             for (Player p : players) {
                 if (p.getLocation().toVector().equals(v)) {
                     whom = p;
                     break;
                 }
             }     
             return whom;
         }
    
        public static List<Player> getNearbyPlayers(Location location, int distance) { //getting nearby players
            List<Player> list = new ArrayList<Player>();                           
            for (Player p : Bukkit.getServer().getOnlinePlayers())
                if (p.getLocation().distance(location) <= distance)
                    list.add(p);
            return list;
        }
     
     
        public void onPlayerJoin(PlayerJoinEvent e) {
            for(Player p : Bukkit.getOnlinePlayers()) {
                glowPlayer(e.getPlayer(), p, false);
            }
        }
     
        @EventHandler
        public void onPlayerQuit(PlayerQuitEvent e) {
            for(Player p : Bukkit.getOnlinePlayers()) {
                glowPlayer(e.getPlayer(), p, false);
            }
        } 
     
    }
    Но второй код просто подсвечивал игроков всегда и для всех.
    В общем, мне нужна помощь: что мне нужно написать чтобы моя задумка работала?
     
  2. reZero

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

    Баллы:
    76
    Как вариант, запустить шедулер и проверять на кого смотрит каждый игрок. Если на другого игрока, значит подсвечиваем его. Вроде ничего сложного
     

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