309 lines
14 KiB
Java
309 lines
14 KiB
Java
/*
|
|
* Copyright (c) 2017 univento.eu - All rights reserved
|
|
* You are not allowed to use, distribute or modify this code
|
|
*/
|
|
|
|
package eu.univento.core.api.npc;
|
|
|
|
import com.mojang.authlib.GameProfile;
|
|
import com.mojang.authlib.properties.Property;
|
|
import eu.univento.core.Core;
|
|
import eu.univento.core.api.player.CustomPlayer;
|
|
import lombok.Getter;
|
|
import net.minecraft.server.v1_12_R1.*;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.block.BlockFace;
|
|
import org.bukkit.craftbukkit.v1_12_R1.CraftServer;
|
|
import org.bukkit.craftbukkit.v1_12_R1.CraftWorld;
|
|
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
|
|
import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack;
|
|
import org.bukkit.entity.*;
|
|
import org.bukkit.scheduler.BukkitRunnable;
|
|
import org.bukkit.scheduler.BukkitTask;
|
|
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
|
|
/**
|
|
* @author Ploxh4D, joethei
|
|
* @version 1.0
|
|
*/
|
|
public class NPC extends EntityPlayer {
|
|
|
|
@Getter private static List<NPC> npcs = new LinkedList<>();
|
|
|
|
public static NPC spawn(CustomPlayer p, GameProfile profile, Location location) {
|
|
GameProfile npcProfile = new GameProfile(profile.getId(), profile.getName());
|
|
for(Map.Entry<String, Property> properties : profile.getProperties().entries()) npcProfile.getProperties().put(properties.getKey(), properties.getValue());
|
|
NPC npc = new NPC(((CraftServer)Bukkit.getServer()).getServer(), ((CraftWorld)p.getWorld()).getHandle(), npcProfile, new PlayerInteractManager(((CraftWorld)p.getWorld()).getHandle()), p, location.getBlockX(), location.getBlockZ());
|
|
npcProfile.getProperties().put("npc", new Property("npc", "npc"));
|
|
npcs.add(npc);
|
|
return npc;
|
|
}
|
|
|
|
public CustomPlayer detect;
|
|
public PacketPlayOutNamedEntitySpawn packet;
|
|
public int x;
|
|
public int z;
|
|
public String message;
|
|
public EntityPlayer player;
|
|
private BukkitTask task;
|
|
|
|
public NPC(final MinecraftServer minecraftserver, final WorldServer worldserver, final GameProfile gameprofile, final PlayerInteractManager playerinteractmanager, final Player player, final int x, final int z) {
|
|
super(minecraftserver, worldserver, gameprofile, playerinteractmanager);
|
|
CustomPlayer p = CustomPlayer.getPlayer(player);
|
|
this.detect = null;
|
|
this.x = 0;
|
|
this.z = 0;
|
|
this.message = "";
|
|
this.detect = p;
|
|
this.x = x;
|
|
this.z = z;
|
|
try {
|
|
final NetworkManager netManager = new NPCNetworkManager(EnumProtocolDirection.SERVERBOUND);
|
|
netManager.setPacketListener(this.playerConnection = new NPCPlayerConnection(((CraftServer) Bukkit.getServer()).getServer(), netManager, this));
|
|
} catch (Exception e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
this.setSneaking(this.detect.isSneaking());
|
|
this.setSprinting(this.detect.isSprinting());
|
|
this.getBukkitEntity().setCanPickupItems(this.detect.getCanPickupItems());
|
|
final Location l = this.detect.getLocation();
|
|
l.setX(l.getX() + x);
|
|
l.setZ(l.getZ() + z);
|
|
for (int i = 0; i < 500; ++i) {
|
|
if (l.getBlock().getRelative(BlockFace.DOWN, i).getType() != Material.AIR && l.getBlock().getRelative(BlockFace.DOWN, i).getType().isSolid()) {
|
|
l.setY(l.getY() - (i - 1));
|
|
i = 500;
|
|
}
|
|
}
|
|
for (int i = 0; i < 500; ++i) {
|
|
if (l.getBlock().getRelative(BlockFace.UP, i).getType() != Material.AIR && l.getBlock().getRelative(BlockFace.UP, i).getType().isSolid()) {
|
|
l.setY(l.getY() + (i + 1));
|
|
}
|
|
if (l.getBlock().getRelative(BlockFace.UP, i + 1).getType() == Material.AIR) {
|
|
i = 500;
|
|
}
|
|
}
|
|
this.setLocation(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch());
|
|
if (!l.getBlock().getRelative(BlockFace.UP, 0).getType().isSolid() && !l.getBlock().getRelative(BlockFace.UP, 1).getType().isSolid()) {
|
|
this.enderTeleportTo(l.getX(), l.getY(), l.getZ());
|
|
}
|
|
this.packet = new PacketPlayOutNamedEntitySpawn(this);
|
|
this.runPlayerUpdate();
|
|
p.sendPacket(this.packet);
|
|
this.fauxSleeping = true;
|
|
this.player = this;
|
|
|
|
new BukkitRunnable() {
|
|
|
|
@Override
|
|
public void run() {
|
|
for(NPC npc : npcs) {
|
|
PacketPlayOutEntityHeadRotation headRotationPacket = new PacketPlayOutEntityHeadRotation(npc.getBukkitEntity().getHandle(), getCompressedAngle(detect.getEyeLocation().getYaw()));
|
|
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(npc.getBukkitEntity().getHandle());
|
|
PacketPlayOutEntityMetadata metadataPacket = new PacketPlayOutEntityMetadata(npc.getId(), npc.getDataWatcher(), true);
|
|
for(CustomPlayer player : Core.getOnlinePlayers()) {
|
|
player.sendPacket(headRotationPacket);
|
|
player.sendPacket(teleportPacket);
|
|
player.sendPacket(metadataPacket);
|
|
}
|
|
}
|
|
}
|
|
}.runTaskTimerAsynchronously(Core.getInstance(), 0L, 0L);
|
|
}
|
|
|
|
private byte getCompressedAngle(float value) {
|
|
return (byte) (value * 256.0F / 360F);
|
|
}
|
|
|
|
public void remove() {
|
|
if (npcs.contains(this)) {
|
|
npcs.remove(this);
|
|
}
|
|
this.task.cancel();
|
|
for (CustomPlayer players : Core.getOnlinePlayers()) {
|
|
final PacketPlayOutEntityDestroy teleport = new PacketPlayOutEntityDestroy(player.getId());
|
|
players.sendPacket(teleport);
|
|
}
|
|
}
|
|
|
|
public void setMessage(final String message) {
|
|
this.message = message;
|
|
}
|
|
|
|
public void runPlayerUpdate() {
|
|
this.task = new BukkitRunnable() {
|
|
public void run() {
|
|
if (detect != null) {
|
|
if (Bukkit.getPlayerExact(detect.getName()) != null) {
|
|
if (!getBukkitEntity().isDead()) {
|
|
setSneaking(detect.isSneaking());
|
|
setSprinting(detect.isSprinting());
|
|
EnumItemSlot[] values;
|
|
for (int length = (values = EnumItemSlot.values()).length, j = 0; j < length; ++j) {
|
|
final EnumItemSlot slot = values[j];
|
|
final PacketPlayOutEntityEquipment equip = new PacketPlayOutEntityEquipment(getBukkitEntity().getEntityId(), slot, getEquip(slot));
|
|
for (CustomPlayer players : Core.getOnlinePlayers()) {
|
|
players.sendPacket(equip);
|
|
}
|
|
}
|
|
final Location l = detect.getLocation();
|
|
l.setX(l.getX() + x);
|
|
l.setZ(l.getZ() + z);
|
|
for (int i = 0; i < 500; ++i) {
|
|
if (l.getBlock().getRelative(BlockFace.DOWN, i).getType() != Material.AIR && l.getBlock().getRelative(BlockFace.DOWN, i).getType().isSolid()) {
|
|
l.setY(l.getY() - (i - 1));
|
|
i = 500;
|
|
}
|
|
}
|
|
for (int i = 0; i < 500; ++i) {
|
|
if (l.getBlock().getRelative(BlockFace.UP, i).getType() != Material.AIR && l.getBlock().getRelative(BlockFace.UP, i).getType().isSolid()) {
|
|
l.setY(l.getY() + (i + 1));
|
|
}
|
|
if (l.getBlock().getRelative(BlockFace.UP, i + 1).getType() == Material.AIR) {
|
|
i = 500;
|
|
}
|
|
}
|
|
if (!l.getBlock().getRelative(BlockFace.UP, 0).getType().isSolid() && !l.getBlock().getRelative(BlockFace.UP, 1).getType().isSolid()) {
|
|
enderTeleportTo(l.getX(), l.getY(), l.getZ());
|
|
}
|
|
NPC.access$0(NPC.this, l.getYaw(), l.getPitch());
|
|
aK = l.getYaw();
|
|
aL = l.getYaw();
|
|
getBukkitEntity().setCanPickupItems(detect.getCanPickupItems());
|
|
} else {
|
|
this.cancel();
|
|
}
|
|
} else {
|
|
this.cancel();
|
|
}
|
|
} else {
|
|
this.cancel();
|
|
}
|
|
}
|
|
|
|
private ItemStack getEquip(final EnumItemSlot slot) {
|
|
switch (slot) {
|
|
case MAINHAND: return CraftItemStack.asNMSCopy(detect.getInventory().getItemInMainHand());
|
|
case OFFHAND: return CraftItemStack.asNMSCopy(detect.getInventory().getItemInOffHand());
|
|
case FEET: return CraftItemStack.asNMSCopy(detect.getInventory().getBoots());
|
|
case LEGS: return CraftItemStack.asNMSCopy(detect.getInventory().getLeggings());
|
|
case CHEST: return CraftItemStack.asNMSCopy(detect.getInventory().getChestplate());
|
|
case HEAD: return CraftItemStack.asNMSCopy(detect.getInventory().getHelmet());
|
|
default: return null;
|
|
}
|
|
}
|
|
}.runTaskTimer(Core.getInstance(), 0L, 0L);
|
|
}
|
|
|
|
public boolean damageEntity(final DamageSource damagesource, final float f) {
|
|
if (damagesource.getEntity().getBukkitEntity().getType() == EntityType.ARROW) {
|
|
final Arrow a = (Arrow) damagesource.getEntity().getBukkitEntity();
|
|
if (a.getShooter() != null) {
|
|
if (a.getShooter() instanceof Player) {
|
|
final Player shooter = (Player) a.getShooter();
|
|
if (this.detect != null && !shooter.getName().equals(this.detect.getName())) {
|
|
this.playEffect();
|
|
this.remove();
|
|
shooter.sendMessage(this.message);
|
|
if (npcs.contains(this)) {
|
|
npcs.remove(this);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
this.remove();
|
|
}
|
|
}
|
|
if (damagesource.getEntity().getBukkitEntity().getType() == EntityType.SNOWBALL) {
|
|
final Snowball a2 = (Snowball) damagesource.getEntity().getBukkitEntity();
|
|
if (a2.getShooter() != null) {
|
|
if (a2.getShooter() instanceof Player) {
|
|
final Player shooter = (Player) a2.getShooter();
|
|
if (this.detect != null && !shooter.getName().equals(this.detect.getName())) {
|
|
this.playEffect();
|
|
this.remove();
|
|
shooter.sendMessage(this.message);
|
|
if (npcs.contains(this)) {
|
|
npcs.remove(this);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
this.remove();
|
|
}
|
|
}
|
|
if (damagesource.getEntity().getBukkitEntity().getType() == EntityType.EGG) {
|
|
final Egg a3 = (Egg) damagesource.getEntity().getBukkitEntity();
|
|
if (a3.getShooter() != null) {
|
|
if (a3.getShooter() instanceof Player) {
|
|
final Player shooter = (Player) a3.getShooter();
|
|
if (this.detect != null && !shooter.getName().equals(this.detect.getName())) {
|
|
this.playEffect();
|
|
this.remove();
|
|
shooter.sendMessage(this.message);
|
|
if (npcs.contains(this)) {
|
|
npcs.remove(this);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
this.remove();
|
|
}
|
|
}
|
|
if (damagesource.getEntity().getBukkitEntity().getType() == EntityType.FIREBALL) {
|
|
final Fireball a4 = (Fireball) damagesource.getEntity().getBukkitEntity();
|
|
if (a4.getShooter() != null) {
|
|
if (a4.getShooter() instanceof Player) {
|
|
final Player shooter = (Player) a4.getShooter();
|
|
if (this.detect != null && !shooter.getName().equals(this.detect.getName())) {
|
|
this.playEffect();
|
|
this.remove();
|
|
shooter.sendMessage(this.message);
|
|
if (npcs.contains(this)) {
|
|
npcs.remove(this);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
this.remove();
|
|
}
|
|
}
|
|
if (damagesource.getEntity().getBukkitEntity().getType() == EntityType.PLAYER && this.detect != null && !damagesource.getEntity().getName().equals(this.detect.getName())) {
|
|
this.playEffect();
|
|
this.remove();
|
|
final Player damager = (Player) damagesource.getEntity().getBukkitEntity();
|
|
damager.sendMessage(this.message);
|
|
if (npcs.contains(this)) {
|
|
npcs.remove(this);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public void playEffect() {
|
|
this.remove();
|
|
for (final Player all : Bukkit.getOnlinePlayers()) {
|
|
final Location l = this.getBukkitEntity().getLocation();
|
|
float i = 0.3f;
|
|
for (int a = 0; a <= 5; ++a) {
|
|
i = i + 0.3f;
|
|
final PacketPlayOutWorldParticles particle = new PacketPlayOutWorldParticles(EnumParticle.CLOUD, true, (float) l.getX(), (float) l.getY() + i, (float) l.getZ(), 0.0f, 0.0f, 0.0f, 0.0f, 10);
|
|
((CraftPlayer) all).getHandle().playerConnection.sendPacket(particle);
|
|
}
|
|
}
|
|
}
|
|
|
|
public Player getPlayer() {
|
|
return this.detect;
|
|
}
|
|
|
|
static /* synthetic */ void access$0(final NPC npc, final float n, final float n2) {
|
|
npc.setYawPitch(n, n2);
|
|
}
|
|
} |