Untitled
package me.hiro3.seismicsenseav; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.wrappers.*; import com.google.common.collect.Lists; import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; import com.projectkorra.projectkorra.ability.EarthAbility; import it.unimi.dsi.fastutil.ints.IntArrayList; import org.bukkit.*; import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; import org.joml.Quaternionf; import org.joml.Vector3f; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.UUID; public class UtilityMethods { public static void sendTextDisplay(Player p, Location loc, String text, double yaw, double pitch, long lifetime) { PacketContainer spawnPacket = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY); int entityId = Integer.MAX_VALUE / 2 + new Random().nextInt(Integer.MAX_VALUE / 2); spawnPacket.getIntegers().write(0, entityId); spawnPacket.getUUIDs().write(0, UUID.randomUUID()); spawnPacket.getEntityTypeModifier().write(0, EntityType.TEXT_DISPLAY); float scaleVal = 1f; Quaternionf qt = new Quaternionf().rotateLocalX((float) Math.toRadians(pitch)).rotateLocalY((float) Math.toRadians(yaw)); spawnPacket.getDoubles() .write(0, loc.getX()) .write(1, loc.getY() + (1-scaleVal) / 2f) .write(2, loc.getZ()); PacketContainer glowPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); glowPacket.getModifier().writeDefaults(); WrappedChatComponent wcc = WrappedChatComponent.fromText(text); glowPacket.getIntegers().write(0, entityId); List<WrappedDataValue> glowValue = Lists.newArrayList( new WrappedDataValue(11, WrappedDataWatcher.Registry.get(Vector3f.class), new Vector3f(1f, 1f, 1f).mul(scaleVal)), new WrappedDataValue(12, WrappedDataWatcher.Registry.get(Quaternionf.class), qt), new WrappedDataValue(22, WrappedDataWatcher.Registry.getChatComponentSerializer(), wcc.getHandle()) ); glowPacket.getDataValueCollectionModifier().write(0, glowValue); ProtocolLibrary.getProtocolManager().sendServerPacket(p, spawnPacket); ProtocolLibrary.getProtocolManager().sendServerPacket(p, glowPacket); Bukkit.getScheduler().scheduleSyncDelayedTask(ProjectKorra.plugin, () -> { PacketContainer destroyPacket = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY); destroyPacket.getModifier().write(0, new IntArrayList(new int[]{entityId})); ProtocolLibrary.getProtocolManager().sendServerPacket(p, destroyPacket); }, lifetime); } //add color for 1.20.4 public static void sendGlowingBlock(Player p, Location loc, float scale, long lifetime) { sendGlowingBlock(p, loc, null, null, scale, lifetime); } public static void sendGlowingBlock(Player p, Location loc, Color color, float scale, long lifetime) { sendGlowingBlock(p, loc, null, color, scale, lifetime); } /* * Give floor center of the block. The method will handle the Y height according to the given scale. */ public static void sendGlowingBlock(Player p, Location loc, Material type, Color color, float scale, long lifetime) { //SPAWN PACKET PacketContainer spawnPacket = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY); int entityId = Integer.MAX_VALUE / 2 + new Random().nextInt(Integer.MAX_VALUE / 2); spawnPacket.getIntegers().write(0, entityId); spawnPacket.getUUIDs().write(0, UUID.randomUUID()); spawnPacket.getEntityTypeModifier().write(0, EntityType.BLOCK_DISPLAY); float scaleVal = Math.max(0, Math.min(scale, 0.999f)); spawnPacket.getDoubles() .write(0, loc.getX()) .write(1, loc.getY() + (1-scaleVal) / 2f) .write(2, loc.getZ()); //GLOW PACKET PacketContainer glowPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); glowPacket.getModifier().writeDefaults(); BlockData data = type == null ? loc.getBlock().getBlockData() : type.createBlockData(); WrappedBlockData wbd = WrappedBlockData.createData(data); int finalColor = color == null ? data.getMapColor().asRGB() : color.asRGB(); glowPacket.getIntegers().write(0, entityId); List<WrappedDataValue> glowValue = Lists.newArrayList( new WrappedDataValue(0, WrappedDataWatcher.Registry.get(Byte.class), (byte) (0x60)), new WrappedDataValue(11, WrappedDataWatcher.Registry.get(Vector3f.class), new Vector3f(-1f, 0f, -1f).mul(scaleVal / 2f)), new WrappedDataValue(12, WrappedDataWatcher.Registry.get(Vector3f.class), new Vector3f(1f, 1f, 1f).mul(scaleVal)), new WrappedDataValue(22, WrappedDataWatcher.Registry.get(Integer.class), finalColor), new WrappedDataValue(23, WrappedDataWatcher.Registry.getBlockDataSerializer(false), wbd.getHandle()) ); glowPacket.getDataValueCollectionModifier().write(0, glowValue); ProtocolLibrary.getProtocolManager().sendServerPacket(p, spawnPacket); ProtocolLibrary.getProtocolManager().sendServerPacket(p, glowPacket); Bukkit.getScheduler().scheduleSyncDelayedTask(ProjectKorra.plugin, () -> { PacketContainer destroyPacket = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY); destroyPacket.getModifier().write(0, new IntArrayList(new int[]{entityId})); ProtocolLibrary.getProtocolManager().sendServerPacket(p, destroyPacket); }, lifetime); } public static void sendGlowingRotatingBlock(Player p, Location loc, Material type, Color color, Vector scale, double yaw, double pitch, long lifetime) { //SPAWN PACKET PacketContainer spawnPacket = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY); int entityId = Integer.MAX_VALUE / 2 + new Random().nextInt(Integer.MAX_VALUE / 2); spawnPacket.getIntegers().write(0, entityId); spawnPacket.getUUIDs().write(0, UUID.randomUUID()); spawnPacket.getEntityTypeModifier().write(0, EntityType.BLOCK_DISPLAY); spawnPacket.getDoubles() .write(0, loc.getX()) .write(1, loc.getY()) .write(2, loc.getZ()); //METADATA PACKET PacketContainer glowPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); glowPacket.getModifier().writeDefaults(); BlockData data = type == null ? loc.getBlock().getBlockData() : type.createBlockData(); WrappedBlockData wbd = WrappedBlockData.createData(data); int finalColor = color == null ? data.getMapColor().asRGB() : color.asRGB(); Quaternionf qt = new Quaternionf().rotateLocalX((float) pitch).rotateLocalY((float) yaw); glowPacket.getIntegers().write(0, entityId); List<WrappedDataValue> glowValue = Lists.newArrayList( new WrappedDataValue(0, WrappedDataWatcher.Registry.get(Byte.class), (byte) (0x60)), new WrappedDataValue(11, WrappedDataWatcher.Registry.get(Vector3f.class), centerDisplayOffset(pitch, yaw, scale, 1)),//new Vector3f(-1f, 0f, -1f).mul(scaleVal / 2f)), new WrappedDataValue(12, WrappedDataWatcher.Registry.get(Vector3f.class), scale.toVector3f()),//new Vector3f(1f, 1f, 1f).mul(scaleVal)), new WrappedDataValue(13, WrappedDataWatcher.Registry.get(Quaternionf.class), qt), new WrappedDataValue(22, WrappedDataWatcher.Registry.get(Integer.class), finalColor),//Color.WHITE.getRGB()),//color), new WrappedDataValue(23, WrappedDataWatcher.Registry.getBlockDataSerializer(false), wbd.getHandle()) ); glowPacket.getDataValueCollectionModifier().write(0, glowValue); ProtocolLibrary.getProtocolManager().sendServerPacket(p, spawnPacket); ProtocolLibrary.getProtocolManager().sendServerPacket(p, glowPacket); Bukkit.getScheduler().scheduleSyncDelayedTask(ProjectKorra.plugin, () -> { PacketContainer destroyPacket = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY); destroyPacket.getModifier().write(0, new IntArrayList(new int[]{entityId})); ProtocolLibrary.getProtocolManager().sendServerPacket(p, destroyPacket); }, lifetime); } public static void sendDisplayBlock(Player p, DisplayData displayData) { sendSpawnPacket(p, displayData); sendMetadataPacket(p, displayData); } public static void sendSpawnPacket(Player p, DisplayData displayData) { PacketContainer spawnPacket = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY); spawnPacket.getIntegers().write(0, displayData.entityId); spawnPacket.getUUIDs().write(0, UUID.randomUUID()); spawnPacket.getEntityTypeModifier().write(0, EntityType.BLOCK_DISPLAY); Location loc = displayData.location; spawnPacket.getDoubles() .write(0, loc.getX()) .write(1, loc.getY()) .write(2, loc.getZ()); ProtocolLibrary.getProtocolManager().sendServerPacket(p, spawnPacket); Bukkit.getScheduler().scheduleSyncDelayedTask(ProjectKorra.plugin, () -> { PacketContainer destroyPacket = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY); destroyPacket.getModifier().write(0, new IntArrayList(new int[]{displayData.entityId})); ProtocolLibrary.getProtocolManager().sendServerPacket(p, destroyPacket); }, displayData.lifetime); } public static void sendMetadataPacket(Player p, DisplayData displayData) { PacketContainer metadataPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); metadataPacket.getModifier().writeDefaults(); metadataPacket.getIntegers().write(0, displayData.entityId); List<WrappedDataValue> metadataValue = new ArrayList<>(); metadataValue.add(new WrappedDataValue(0, WrappedDataWatcher.Registry.get(Byte.class), (byte) (0x60))); metadataValue.add(new WrappedDataValue(11, WrappedDataWatcher.Registry.get(Vector3f.class), displayData.centerDisplayOffset)); metadataValue.add(new WrappedDataValue(12, WrappedDataWatcher.Registry.get(Vector3f.class), displayData.scale)); if (displayData.qt != null) metadataValue.add(new WrappedDataValue(13, WrappedDataWatcher.Registry.get(Quaternionf.class), displayData.qt)); metadataValue.add(new WrappedDataValue(22, WrappedDataWatcher.Registry.get(Integer.class), displayData.color)); metadataValue.add(new WrappedDataValue(23, WrappedDataWatcher.Registry.getBlockDataSerializer(false), displayData.wbd.getHandle())); metadataPacket.getDataValueCollectionModifier().write(0, metadataValue); ProtocolLibrary.getProtocolManager().sendServerPacket(p, metadataPacket); } public static Vector3f centerDisplayOffset(double pitch, double yaw, Vector scale, int mode) { //mode 0: stick rotation //mode 1: central rotation mode = Math.min(1, Math.max(0, mode)); Vector vector = new Vector(0.5 * scale.getX(), 0.5 * scale.getY(), 0.5 * scale.getZ() * mode); double oldX = vector.getX(); double oldY = vector.getY(); double oldZ = vector.getZ(); vector.setY(oldY * Math.cos(pitch) - oldZ * Math.sin(pitch)); vector.setZ(oldY * Math.sin(pitch) + oldZ * Math.cos(pitch)); oldY = vector.getY(); oldZ = vector.getZ(); vector.setX(oldX * Math.cos(yaw) + oldZ * Math.sin(yaw)); vector.setZ(-oldX * Math.sin(yaw) + oldZ * Math.cos(yaw)); return vector.multiply(-1).toVector3f(); } public static void setGlowing(Player sendPacketPlayer, LivingEntity glowingEntity, boolean glow) { PacketContainer packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA); packet.getIntegers().write(0, glowingEntity.getEntityId()); Byte md = WrappedDataWatcher.getEntityWatcher(glowingEntity).getByte(0); Byte mask = (byte) (glow ? 0x40 : 0); md = (byte) (md | mask); List<WrappedDataValue> values = Lists.newArrayList( new WrappedDataValue(0, WrappedDataWatcher.Registry.get(Byte.class), md)); packet.getDataValueCollectionModifier().write(0, values); ProtocolLibrary.getProtocolManager().sendServerPacket(sendPacketPlayer, packet); } public static void sendPulse(Player player, Location center, double maxRadius, int step, int angleIncrease) { new BukkitRunnable() { double angle; double radius = 0; double speed = maxRadius/step; @Override public void run() { if (radius >= maxRadius) { Bukkit.getScheduler().cancelTask(getTaskId()); return; } radius += speed; for(int i = 0; i <= 360; i+=angleIncrease) { angle = Math.toRadians(i); double x = radius * Math.cos(angle); double z = radius * Math.sin(angle); center.add(x, 0, z); if (GeneralMethods.isSolid(center.getBlock())) UtilityMethods.sendGlowingBlock(player, center, 0.1f, 1); center.subtract(x, 0, z); } } }.runTaskTimer(ProjectKorra.plugin, 0, 1); } public static void sendRotatingPulse(Player player, Location center, double radius, int step, int angleIncrease) { double radiusIncrease = radius / step; double angleIncreaseRad = Math.toRadians(angleIncrease); new BukkitRunnable() { double r = 0; @Override public void run() { if (r >= radius) { Bukkit.getScheduler().cancelTask(getTaskId()); return; } for (int i = 0; i < 360; i+= angleIncrease) { double angle = Math.toRadians(i); double x = r * Math.cos(angle); double z = r * Math.sin(angle); double c = Math.cos(angleIncreaseRad); double d = r * Math.sqrt( (1 - c) / (1 + c) ); double stickLength = 2 * d; Vector scale = new Vector(0.2, 0.2, stickLength); double yaw = -angle; double pitch = 0; center.add(x, 0, z); DisplayData dd = new DisplayData( center, null, null, scale, yaw, pitch, true, 2 ); sendDisplayBlock(player, dd); center.subtract(x, 0, z); } r += radiusIncrease; } }.runTaskTimer(ProjectKorra.plugin, 0, 1); } public static void sendPulseImproved(Player player, Location center, double maxRadius, int step, int angleIncrease) { Vector startingVector = new Vector(maxRadius/step, 0, 0); Location startingLocation = center; ArrayList<Location> l = new ArrayList<Location>(); ArrayList<Vector> d = new ArrayList<Vector>(); for (int i = 0; i < 360; i += angleIncrease) { l.add(startingLocation.clone()); d.add(UtilityMethods.rotateVectorAroundY(startingVector, i)); } new BukkitRunnable() { int tick = 0; @Override public void run() { if (tick >= step) { Bukkit.getScheduler().cancelTask(getTaskId()); return; } for (int i = 0; i < l.size(); i++) { if (GeneralMethods.isSolid(l.get(i).getBlock())) { UtilityMethods.sendGlowingBlock(player, l.get(i), 0.1f, 1); } if (GeneralMethods.isSolid(l.get(i).getBlock().getRelative(BlockFace.UP))) { l.get(i).add(0, 1, 0); } else { l.get(i).add(d.get(i)); if (GeneralMethods.isSolid(l.get(i).getBlock().getRelative(BlockFace.UP))) { l.get(i).add(0, 1, 0); } else { l.set(i, UtilityMethods.getFloor(player, l.get(i))); } } } tick++; } }.runTaskTimer(ProjectKorra.plugin, 0, 1); } public static Vector rotateVectorAroundY(Vector vector, double degrees) { double rad = Math.toRadians(degrees); double currentX = vector.getX(); double currentZ = vector.getZ(); double cosine = Math.cos(rad); double sine = Math.sin(rad); return new Vector((cosine * currentX - sine * currentZ), vector.getY(), (sine * currentX + cosine * currentZ)); } public static Location getFloor(Player player, Location loc) { Location f = loc.clone(); double sqrMaxHeight = 30 * 30; while (!GeneralMethods.isSolid(loc.getBlock()) && loc.distanceSquared(f) < sqrMaxHeight) { loc.add(0, -1, 0); } return loc; } public static class DisplayData { public int entityId; public int lifetime; public Location location; public Vector3f centerDisplayOffset; public Vector3f scale; public Quaternionf qt; public int color; public WrappedBlockData wbd; public DisplayData(Location loc, Material type, Color color, Vector scale, double yaw, double pitch, boolean rotateFromCenter, int lifetime) { this.entityId = Integer.MAX_VALUE / 2 + new Random().nextInt(Integer.MAX_VALUE / 2); this.lifetime = lifetime; this.location = loc; int mode = rotateFromCenter ? 1 : 0; this.scale = scale.toVector3f(); if (yaw != 0 || pitch != 0) { this.centerDisplayOffset = centerDisplayOffset(pitch, yaw, scale, mode); this.qt = new Quaternionf().rotateLocalX((float) pitch).rotateLocalY((float) yaw); } else { this.centerDisplayOffset = new Vector3f( (float) (-scale.getX() / 2.), (float) (-scale.getY() / 2.), (float) (-scale.getZ() / 2.) * mode ); this.qt = null; } BlockData data = type == null ? loc.getBlock().getBlockData() : type.createBlockData(); this.color = color == null ? data.getMapColor().asRGB() : color.asRGB(); this.wbd = WrappedBlockData.createData(data); } } }
Leave a Comment