package com.github.shynixn.astraledit.bukkit.logic.business.nms.v1_12_R1; import com.github.shynixn.astraledit.api.bukkit.business.entity.PacketArmorstand; import com.github.shynixn.astraledit.bukkit.logic.business.nms.NMSRegistry; import com.github.shynixn.astraledit.bukkit.logic.lib.ItemStackBuilder; import net.minecraft.server.v1_12_R1.*; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.craftbukkit.v1_12_R1.CraftWorld; import org.bukkit.craftbukkit.v1_12_R1.entity.CraftArmorStand; import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Player; import org.bukkit.util.EulerAngle; import java.util.Set; /** * Copyright 2017 Shynixn * <p> * Do not remove this header! * <p> * Version 1.0 * <p> * MIT License * <p> * Copyright (c) 2017 * <p> * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * <p> * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * <p> * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ public class DisplayArmorstand implements PacketArmorstand { private Player player; private final EntityArmorStand armorStand; private int storedId; private byte storedData; private Set<Player> watchers; /** * Initializes the armorstand * * @param player player * @param location location * @param id id * @param data data * @param watchers watchers */ public DisplayArmorstand(Player player, Location location, int id, byte data, Set<Player> watchers) { super(); this.watchers = watchers; this.player = player; this.armorStand = new EntityArmorStand(((CraftWorld) player.getWorld()).getHandle()); final NBTTagCompound compound = new NBTTagCompound(); compound.setBoolean("invulnerable", true); compound.setBoolean("Invisible", true); compound.setBoolean("PersistenceRequired", true); compound.setBoolean("NoBasePlate", true); this.armorStand.a(compound); this.armorStand.setLocation(location.getX(), location.getY(), location.getZ(), 0, 0); this.storedId = id; this.storedData = data; ItemStackBuilder stackBuilder = new ItemStackBuilder(Material.getMaterial(id), 1, data); this.getCraftEntity().setHelmet(stackBuilder.build()); this.getCraftEntity().setBodyPose(new EulerAngle(3.15, 0, 0)); this.getCraftEntity().setLeftLegPose(new EulerAngle(3.15, 0, 0)); this.getCraftEntity().setRightLegPose(new EulerAngle(3.15, 0, 0)); this.getCraftEntity().setGlowing(true); if (((ArmorStand) this.armorStand.getBukkitEntity()).getHelmet().getType() == Material.AIR) { stackBuilder = new ItemStackBuilder(Material.SKULL_ITEM, 1, (short) 3); if (id == Material.WATER.getId() || id == Material.STATIONARY_WATER.getId()) { stackBuilder.setSkin(NMSRegistry.WATER_HEAD); } else if (id == Material.LAVA.getId() || id == Material.STATIONARY_LAVA.getId()) { stackBuilder.setSkin(NMSRegistry.LAVA_HEAD); } else { stackBuilder.setSkin(NMSRegistry.NOT_FOUND); } ((ArmorStand) this.armorStand.getBukkitEntity()).setHelmet(stackBuilder.build()); } } /** * Spawns the armorstand */ @Override public void spawn() { final PacketPlayOutSpawnEntityLiving packetSpawn = new PacketPlayOutSpawnEntityLiving(this.armorStand); final PacketPlayOutEntityEquipment packetHead = new PacketPlayOutEntityEquipment(this.armorStand.getId(), EnumItemSlot.HEAD, CraftItemStack.asNMSCopy(((ArmorStand) this.armorStand.getBukkitEntity()).getHelmet())); this.sendPacket(packetSpawn); this.sendPacket(packetHead); } /** * Teleports the armorstand to the given location * * @param location location */ @Override public void teleport(Location location) { this.armorStand.setPositionRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); final PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(this.armorStand); this.sendPacket(teleportPacket); } /** * Removes the armorstand */ @Override public void remove() { final PacketPlayOutEntityDestroy destroyPacket = new PacketPlayOutEntityDestroy(this.armorStand.getId()); this.sendPacket(destroyPacket); } /** * Returns the location of the armorstand * * @return location */ @Override public Location getLocation() { return this.armorStand.getBukkitEntity().getLocation(); } /** * Sets the pose of * * @param angle angle */ @Override public void setHeadPose(EulerAngle angle) { ((ArmorStand) this.armorStand.getBukkitEntity()).setHeadPose(angle); final PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(this.armorStand.getId(), this.armorStand.getDataWatcher(), true); this.sendPacket(packet); } /** * Returns the pose of the head * * @return angle */ @Override public EulerAngle getHeadPose() { return ((ArmorStand) this.armorStand.getBukkitEntity()).getHeadPose(); } /** * Returns the stored block id * * @return id */ @Override public int getStoredBlockId() { return this.storedId; } /** * Sets the stored block id * * @param id id */ @Override public void setStoreBlockId(int id) { this.storedId = id; } /** * Returns the stored block data * * @return data */ @Override public byte getStoredBlockData() { return this.storedData; } /** * Sets the stored block data * * @param data data */ @Override public void setStoredBlockData(byte data) { this.storedData = data; } /** * Sends the packet * * @param packet packet */ private void sendPacket(Packet<?> packet) { this.sendPacket(packet, this.player); for (final Player player : this.watchers) { this.sendPacket(packet, player); } } /** * Sends the packet * * @param player player * @param packet packet */ private void sendPacket(Packet<?> packet, Player player) { ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); } /** * Returns the craftArmorstand * * @return stand */ private CraftArmorStand getCraftEntity() { return (CraftArmorStand) this.armorStand.getBukkitEntity(); } /** * Closes this resource, relinquishing any underlying resources. * This method is invoked automatically on objects managed by the * {@code try}-with-resources statement. * * @throws Exception if this resource cannot be closed */ @Override public void close() throws Exception { this.remove(); this.watchers = null; this.player = null; } }