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

  • Автор темы Автор темы 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);
        }
    } 
 
}

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