NPCLib/api/src/main/java/net/jitse/npclib/internal/SimpleNPC.java

210 lines
5.6 KiB
Java
Raw Normal View History

2018-04-26 13:52:49 +02:00
/*
* Copyright (c) 2018 Jitse Boonstra
*/
2019-08-03 13:47:12 +02:00
package net.jitse.npclib.internal;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import net.jitse.npclib.NPCLib;
import net.jitse.npclib.api.NPC;
import net.jitse.npclib.api.events.NPCHideEvent;
import net.jitse.npclib.api.events.NPCShowEvent;
import net.jitse.npclib.api.skin.Skin;
2018-04-26 13:52:49 +02:00
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
2018-04-26 13:52:49 +02:00
import java.util.*;
2019-08-03 13:47:12 +02:00
public abstract class SimpleNPC implements NPC, PacketHandler {
2018-04-26 13:52:49 +02:00
protected final UUID uuid = UUID.randomUUID();
protected final int entityId = Integer.MAX_VALUE - NPCManager.getAllNPCs().size();
2019-08-03 13:47:12 +02:00
protected final String name = uuid.toString().replace("-", "").substring(0, 10);
protected final GameProfile gameProfile = new GameProfile(uuid, name);
2018-04-26 13:52:49 +02:00
2019-08-03 13:47:12 +02:00
protected final List<String> lines;
2018-04-26 13:52:49 +02:00
private final Set<UUID> shown = new HashSet<>();
private final Set<UUID> autoHidden = new HashSet<>();
2019-08-03 13:47:12 +02:00
protected double cosFOV = Math.cos(Math.toRadians(60));
2018-04-26 13:52:49 +02:00
2019-08-03 13:47:12 +02:00
protected NPCLib instance;
2018-04-26 13:52:49 +02:00
protected Location location;
2019-08-03 13:47:12 +02:00
protected Skin skin;
2018-04-26 13:52:49 +02:00
2019-08-03 13:47:12 +02:00
public SimpleNPC(NPCLib instance, List<String> lines) {
this.instance = instance;
this.lines = lines == null ? Collections.emptyList() : lines;
2018-04-26 13:52:49 +02:00
NPCManager.add(this);
}
2019-08-03 13:47:12 +02:00
protected GameProfile generateGameProfile(UUID uuid, String name) {
GameProfile gameProfile = new GameProfile(uuid, name);
if (skin != null) {
2019-08-03 13:47:12 +02:00
gameProfile.getProperties().get("textures").clear();
gameProfile.getProperties().get("textures").add(new Property(skin.getValue(), skin.getSignature()));
}
return gameProfile;
}
2019-08-03 13:47:12 +02:00
public NPCLib getInstance() {
return instance;
}
2019-08-03 13:47:12 +02:00
@Override
public String getId() {
return name;
}
@Override
public NPC setSkin(Skin skin) {
this.skin = skin;
return this;
}
@Override
2018-04-26 13:52:49 +02:00
public void destroy() {
2018-05-06 23:34:55 +02:00
destroy(true);
}
public void destroy(boolean scheduler) {
2018-04-26 13:52:49 +02:00
NPCManager.remove(this);
// Destroy NPC for every player that is still seeing it.
for (UUID uuid : shown) {
if (autoHidden.contains(uuid)) {
continue;
}
2018-05-06 23:34:55 +02:00
hide(Bukkit.getPlayer(uuid), true, scheduler);
2018-04-26 13:52:49 +02:00
}
}
public void disableFOV() {
this.cosFOV = 0; // Or equals Math.cos(1/2 * Math.PI).
}
public void setFOV(double fov) {
2019-08-03 13:47:12 +02:00
this.cosFOV = Math.cos(Math.toRadians(fov));
}
2018-04-26 13:52:49 +02:00
public Set<UUID> getShown() {
return shown;
}
public Set<UUID> getAutoHidden() {
return autoHidden;
}
2019-08-03 13:47:12 +02:00
@Override
2018-04-26 13:52:49 +02:00
public Location getLocation() {
return location;
}
public int getEntityId() {
return entityId;
}
2019-08-03 13:47:12 +02:00
@Override
public boolean isShown(Player player) {
2018-04-26 13:52:49 +02:00
return shown.contains(player.getUniqueId()) && !autoHidden.contains(player.getUniqueId());
}
2019-08-03 13:47:12 +02:00
@Override
public NPC setLocation(Location location) {
this.location = location;
2019-08-03 13:47:12 +02:00
return this;
}
2019-08-03 13:47:12 +02:00
@Override
public NPC create() {
createPackets();
2019-08-03 13:47:12 +02:00
return this;
}
2018-04-26 13:52:49 +02:00
2019-08-03 13:47:12 +02:00
@Override
2018-04-26 13:52:49 +02:00
public void show(Player player) {
show(player, false);
}
public void show(Player player, boolean auto) {
2019-08-03 13:47:12 +02:00
NPCShowEvent event = new NPCShowEvent(this, player, auto);
Bukkit.getServer().getPluginManager().callEvent(event);
2018-04-26 13:52:49 +02:00
if (event.isCancelled()) {
return;
}
if (!canSeeNPC(player)) {
if (!auto) {
shown.add(player.getUniqueId());
}
autoHidden.add(player.getUniqueId());
return;
}
2018-04-26 13:52:49 +02:00
if (auto) {
sendShowPackets(player);
} else {
2019-08-03 13:47:12 +02:00
if (isShown(player)) {
2018-04-26 13:52:49 +02:00
throw new RuntimeException("Cannot call show method twice.");
}
if (shown.contains(player.getUniqueId())) {
return;
}
2018-04-26 13:52:49 +02:00
shown.add(player.getUniqueId());
2019-08-03 13:47:12 +02:00
if (player.getWorld().equals(location.getWorld()) && player.getLocation().distance(location)
<= instance.getAutoHideDistance()) {
2018-04-26 13:52:49 +02:00
sendShowPackets(player);
} else {
autoHidden.add(player.getUniqueId());
2018-04-26 13:52:49 +02:00
}
}
}
private boolean canSeeNPC(Player player) {
Vector dir = location.toVector().subtract(player.getEyeLocation().toVector()).normalize();
return dir.dot(player.getLocation().getDirection()) >= cosFOV;
}
2019-08-03 13:47:12 +02:00
@Override
2018-04-26 13:52:49 +02:00
public void hide(Player player) {
2018-05-06 23:34:55 +02:00
hide(player, false, true);
2018-04-26 13:52:49 +02:00
}
2018-05-06 23:34:55 +02:00
public void hide(Player player, boolean auto, boolean scheduler) {
2019-08-03 13:47:12 +02:00
NPCHideEvent event = new NPCHideEvent(this, player, auto);
Bukkit.getServer().getPluginManager().callEvent(event);
2018-04-26 13:52:49 +02:00
if (event.isCancelled()) {
return;
}
if (auto) {
2018-05-06 23:34:55 +02:00
sendHidePackets(player, scheduler);
2018-04-26 13:52:49 +02:00
} else {
if (!shown.contains(player.getUniqueId())) {
throw new RuntimeException("Cannot call hide method without calling NPC#show.");
}
shown.remove(player.getUniqueId());
2019-08-03 13:47:12 +02:00
if (player.getWorld().equals(location.getWorld()) && player.getLocation().distance(location)
<= instance.getAutoHideDistance()) {
2018-05-06 23:34:55 +02:00
sendHidePackets(player, scheduler);
2018-04-26 13:52:49 +02:00
} else {
autoHidden.remove(player.getUniqueId());
2018-04-26 13:52:49 +02:00
}
}
}
}