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);
}
}
}
Но второй код просто подсвечивал игроков всегда и для всех.
В общем, мне нужна помощь: что мне нужно написать чтобы моя задумка работала?