2020-04-13 19:57:20 +02:00
|
|
|
package net.citizensnpcs.trait;
|
|
|
|
|
2023-02-14 22:36:51 +01:00
|
|
|
import java.util.Iterator;
|
2022-11-13 09:02:17 +01:00
|
|
|
import java.util.List;
|
2022-12-11 14:28:39 +01:00
|
|
|
import java.util.Map;
|
2023-02-14 22:36:51 +01:00
|
|
|
import java.util.Map.Entry;
|
2022-12-11 14:28:39 +01:00
|
|
|
import java.util.Set;
|
|
|
|
import java.util.UUID;
|
2022-12-27 07:22:27 +01:00
|
|
|
import java.util.stream.Collectors;
|
2020-04-13 19:57:20 +02:00
|
|
|
|
2021-01-20 15:10:47 +01:00
|
|
|
import org.bukkit.Bukkit;
|
2020-04-13 19:57:20 +02:00
|
|
|
import org.bukkit.GameMode;
|
|
|
|
import org.bukkit.Location;
|
2022-12-27 07:22:27 +01:00
|
|
|
import org.bukkit.entity.EntityType;
|
2020-04-13 19:57:20 +02:00
|
|
|
import org.bukkit.entity.LivingEntity;
|
|
|
|
import org.bukkit.entity.Player;
|
|
|
|
import org.bukkit.metadata.MetadataValue;
|
|
|
|
import org.bukkit.potion.PotionEffectType;
|
|
|
|
|
2022-11-13 09:02:17 +01:00
|
|
|
import com.google.common.collect.Lists;
|
2022-12-11 14:28:39 +01:00
|
|
|
import com.google.common.collect.Maps;
|
|
|
|
import com.google.common.collect.Sets;
|
2022-11-13 09:02:17 +01:00
|
|
|
|
2020-04-13 19:57:20 +02:00
|
|
|
import net.citizensnpcs.Settings.Setting;
|
|
|
|
import net.citizensnpcs.api.CitizensAPI;
|
2021-01-20 15:10:47 +01:00
|
|
|
import net.citizensnpcs.api.event.NPCLookCloseChangeTargetEvent;
|
2020-04-13 19:57:20 +02:00
|
|
|
import net.citizensnpcs.api.persistence.Persist;
|
|
|
|
import net.citizensnpcs.api.trait.Trait;
|
|
|
|
import net.citizensnpcs.api.trait.TraitName;
|
|
|
|
import net.citizensnpcs.api.util.DataKey;
|
2022-12-11 14:28:39 +01:00
|
|
|
import net.citizensnpcs.trait.RotationTrait.PacketRotationSession;
|
2020-04-13 19:57:20 +02:00
|
|
|
import net.citizensnpcs.util.NMS;
|
|
|
|
import net.citizensnpcs.util.Util;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Persists the /npc lookclose metadata
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
@TraitName("lookclose")
|
2022-11-28 16:10:50 +01:00
|
|
|
public class LookClose extends Trait implements Toggleable {
|
2021-02-04 02:51:02 +01:00
|
|
|
@Persist("disablewhilenavigating")
|
|
|
|
private boolean disableWhileNavigating = Setting.DISABLE_LOOKCLOSE_WHILE_NAVIGATING.asBoolean();
|
2020-04-13 19:57:20 +02:00
|
|
|
@Persist("enabled")
|
|
|
|
private boolean enabled = Setting.DEFAULT_LOOK_CLOSE.asBoolean();
|
|
|
|
@Persist
|
|
|
|
private boolean enableRandomLook = Setting.DEFAULT_RANDOM_LOOK_CLOSE.asBoolean();
|
2023-01-01 17:24:11 +01:00
|
|
|
@Persist("headonly")
|
|
|
|
private boolean headOnly;
|
2023-05-01 18:50:50 +02:00
|
|
|
@Persist("linkedbody")
|
|
|
|
private boolean linkedBody;
|
2020-04-13 19:57:20 +02:00
|
|
|
private Player lookingAt;
|
2022-12-11 14:28:39 +01:00
|
|
|
@Persist("perplayer")
|
|
|
|
private boolean perPlayer;
|
2020-04-13 19:57:20 +02:00
|
|
|
@Persist
|
2023-03-12 15:29:41 +01:00
|
|
|
private int randomLookDelay = Setting.DEFAULT_RANDOM_LOOK_DELAY.asTicks();
|
2020-04-13 19:57:20 +02:00
|
|
|
@Persist
|
2022-04-13 05:14:37 +02:00
|
|
|
private float[] randomPitchRange = { 0, 0 };
|
2020-04-13 19:57:20 +02:00
|
|
|
@Persist
|
2022-11-13 09:02:17 +01:00
|
|
|
private boolean randomSwitchTargets;
|
|
|
|
@Persist
|
2020-04-13 19:57:20 +02:00
|
|
|
private float[] randomYawRange = { 0, 360 };
|
|
|
|
private double range = Setting.DEFAULT_LOOK_CLOSE_RANGE.asDouble();
|
|
|
|
@Persist("realisticlooking")
|
|
|
|
private boolean realisticLooking = Setting.DEFAULT_REALISTIC_LOOKING.asBoolean();
|
2022-12-11 14:28:39 +01:00
|
|
|
private final Map<UUID, PacketRotationSession> sessions = Maps.newHashMapWithExpectedSize(4);
|
2020-04-13 19:57:20 +02:00
|
|
|
private int t;
|
2022-12-27 07:22:27 +01:00
|
|
|
@Persist("targetnpcs")
|
|
|
|
private boolean targetNPCs;
|
2020-04-13 19:57:20 +02:00
|
|
|
|
|
|
|
public LookClose() {
|
|
|
|
super("lookclose");
|
|
|
|
}
|
|
|
|
|
2021-01-25 14:30:07 +01:00
|
|
|
private boolean canSee(Player player) {
|
2021-04-04 05:31:43 +02:00
|
|
|
if (player == null || !player.isValid())
|
|
|
|
return false;
|
2021-01-25 14:30:07 +01:00
|
|
|
return realisticLooking && npc.getEntity() instanceof LivingEntity
|
|
|
|
? ((LivingEntity) npc.getEntity()).hasLineOfSight(player)
|
2021-04-07 08:26:07 +02:00
|
|
|
: true;
|
2021-01-25 14:30:07 +01:00
|
|
|
}
|
|
|
|
|
2020-04-13 19:57:20 +02:00
|
|
|
/**
|
2020-04-15 21:04:42 +02:00
|
|
|
* Returns whether the target can be seen. Will use realistic line of sight if {@link #setRealisticLooking(boolean)}
|
|
|
|
* is true.
|
2020-04-13 19:57:20 +02:00
|
|
|
*/
|
|
|
|
public boolean canSeeTarget() {
|
2021-01-25 14:30:07 +01:00
|
|
|
return canSee(lookingAt);
|
2020-04-13 19:57:20 +02:00
|
|
|
}
|
|
|
|
|
2021-02-04 02:51:02 +01:00
|
|
|
public boolean disableWhileNavigating() {
|
|
|
|
return disableWhileNavigating;
|
|
|
|
}
|
|
|
|
|
2020-04-13 19:57:20 +02:00
|
|
|
/**
|
|
|
|
* Finds a new look-close target
|
|
|
|
*/
|
|
|
|
public void findNewTarget() {
|
2022-12-11 14:28:39 +01:00
|
|
|
if (perPlayer) {
|
|
|
|
lookingAt = null;
|
2023-05-03 19:51:48 +02:00
|
|
|
RotationTrait rotationTrait = npc.getOrAddTrait(RotationTrait.class);
|
2022-12-11 14:28:39 +01:00
|
|
|
Set<UUID> seen = Sets.newHashSet();
|
2023-05-03 19:51:48 +02:00
|
|
|
for (Player player : getNearbyPlayers()) {
|
2022-12-11 14:28:39 +01:00
|
|
|
PacketRotationSession session = sessions.get(player.getUniqueId());
|
|
|
|
if (session == null) {
|
2023-01-01 17:24:11 +01:00
|
|
|
sessions.put(player.getUniqueId(),
|
2023-05-03 19:51:48 +02:00
|
|
|
session = rotationTrait.createPacketSession(
|
|
|
|
rotationTrait.getGlobalParameters().clone().linkedBody(linkedBody)
|
|
|
|
.headOnly(headOnly).uuidFilter(player.getUniqueId()).persist(true)));
|
2022-12-11 14:28:39 +01:00
|
|
|
}
|
|
|
|
session.getSession().rotateToFace(player);
|
|
|
|
seen.add(player.getUniqueId());
|
|
|
|
}
|
2023-02-14 22:36:51 +01:00
|
|
|
for (Iterator<Entry<UUID, PacketRotationSession>> iterator = sessions.entrySet().iterator(); iterator
|
|
|
|
.hasNext();) {
|
|
|
|
Entry<UUID, PacketRotationSession> entry = iterator.next();
|
|
|
|
if (!seen.contains(entry.getKey())) {
|
|
|
|
entry.getValue().end();
|
|
|
|
iterator.remove();
|
|
|
|
}
|
2022-12-11 14:28:39 +01:00
|
|
|
}
|
2023-01-01 11:43:41 +01:00
|
|
|
return;
|
2022-12-11 14:28:39 +01:00
|
|
|
} else if (sessions.size() > 0) {
|
|
|
|
for (PacketRotationSession session : sessions.values()) {
|
|
|
|
session.end();
|
|
|
|
}
|
|
|
|
sessions.clear();
|
|
|
|
}
|
2022-11-13 09:02:17 +01:00
|
|
|
if (lookingAt != null && !isValid(lookingAt)) {
|
|
|
|
NPCLookCloseChangeTargetEvent event = new NPCLookCloseChangeTargetEvent(npc, lookingAt, null);
|
|
|
|
Bukkit.getPluginManager().callEvent(event);
|
|
|
|
if (event.getNewTarget() != null && isValid(event.getNewTarget())) {
|
|
|
|
lookingAt = event.getNewTarget();
|
|
|
|
} else {
|
|
|
|
lookingAt = null;
|
|
|
|
}
|
|
|
|
}
|
2021-01-20 15:10:47 +01:00
|
|
|
Player old = lookingAt;
|
2022-11-13 09:02:17 +01:00
|
|
|
if (lookingAt != null) {
|
|
|
|
if (randomSwitchTargets && t <= 0) {
|
2022-12-11 14:28:39 +01:00
|
|
|
List<Player> options = getNearbyPlayers();
|
2022-11-13 09:02:17 +01:00
|
|
|
if (options.size() > 0) {
|
|
|
|
lookingAt = options.get(Util.getFastRandom().nextInt(options.size()));
|
|
|
|
t = randomLookDelay;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2023-07-08 15:43:23 +02:00
|
|
|
double min = Double.MAX_VALUE;
|
2023-06-25 15:58:09 +02:00
|
|
|
Location npcLoc = npc.getStoredLocation();
|
2022-12-27 07:22:27 +01:00
|
|
|
for (Player player : getNearbyPlayers()) {
|
2023-06-25 15:58:09 +02:00
|
|
|
double dist = player.getLocation().distance(npcLoc);
|
2023-11-05 13:58:37 +01:00
|
|
|
if (dist > min) {
|
2022-11-13 09:02:17 +01:00
|
|
|
continue;
|
2023-11-05 13:58:37 +01:00
|
|
|
}
|
2022-11-13 09:02:17 +01:00
|
|
|
min = dist;
|
|
|
|
lookingAt = player;
|
|
|
|
}
|
2020-04-13 19:57:20 +02:00
|
|
|
}
|
2021-01-20 15:10:47 +01:00
|
|
|
if (old != lookingAt) {
|
|
|
|
NPCLookCloseChangeTargetEvent event = new NPCLookCloseChangeTargetEvent(npc, old, lookingAt);
|
|
|
|
Bukkit.getPluginManager().callEvent(event);
|
2023-11-05 13:58:37 +01:00
|
|
|
if (lookingAt != event.getNewTarget() && event.getNewTarget() != null && !isValid(event.getNewTarget()))
|
2021-01-23 03:52:53 +01:00
|
|
|
return;
|
2021-01-20 15:10:47 +01:00
|
|
|
lookingAt = event.getNewTarget();
|
|
|
|
}
|
2020-04-13 19:57:20 +02:00
|
|
|
}
|
|
|
|
|
2022-12-11 14:28:39 +01:00
|
|
|
private List<Player> getNearbyPlayers() {
|
|
|
|
List<Player> options = Lists.newArrayList();
|
2023-06-25 15:58:09 +02:00
|
|
|
Location npcLoc = npc.getStoredLocation();
|
2022-12-27 07:22:27 +01:00
|
|
|
Iterable<Player> nearby = targetNPCs
|
|
|
|
? npc.getEntity().getNearbyEntities(range, range, range).stream()
|
2023-06-25 15:58:09 +02:00
|
|
|
.filter(e -> e.getType() == EntityType.PLAYER && e.getWorld() == npcLoc.getWorld())
|
2022-12-27 07:22:27 +01:00
|
|
|
.map(e -> (Player) e).collect(Collectors.toList())
|
2023-06-25 15:58:09 +02:00
|
|
|
: CitizensAPI.getLocationLookup().getNearbyPlayers(npcLoc, range);
|
2022-12-27 07:22:27 +01:00
|
|
|
for (Player player : nearby) {
|
2023-11-05 13:58:37 +01:00
|
|
|
if (player == lookingAt || !targetNPCs && CitizensAPI.getNPCRegistry().getNPC(player) != null) {
|
2022-12-11 14:28:39 +01:00
|
|
|
continue;
|
2023-11-05 13:58:37 +01:00
|
|
|
}
|
|
|
|
if (player.getLocation().getWorld() != npcLoc.getWorld() || isInvisible(player)) {
|
2022-12-11 14:28:39 +01:00
|
|
|
continue;
|
2023-11-05 13:58:37 +01:00
|
|
|
}
|
2022-12-11 14:28:39 +01:00
|
|
|
options.add(player);
|
|
|
|
}
|
|
|
|
return options;
|
|
|
|
}
|
|
|
|
|
2020-10-07 13:16:41 +02:00
|
|
|
public int getRandomLookDelay() {
|
|
|
|
return randomLookDelay;
|
|
|
|
}
|
|
|
|
|
|
|
|
public float[] getRandomLookPitchRange() {
|
|
|
|
return randomPitchRange;
|
|
|
|
}
|
|
|
|
|
|
|
|
public float[] getRandomLookYawRange() {
|
|
|
|
return randomYawRange;
|
|
|
|
}
|
|
|
|
|
|
|
|
public double getRange() {
|
|
|
|
return range;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Player getTarget() {
|
|
|
|
return lookingAt;
|
|
|
|
}
|
|
|
|
|
2022-04-24 13:22:55 +02:00
|
|
|
public boolean isEnabled() {
|
|
|
|
return enabled;
|
|
|
|
}
|
|
|
|
|
2023-01-01 17:24:11 +01:00
|
|
|
public boolean isHeadOnly() {
|
|
|
|
return headOnly;
|
|
|
|
}
|
|
|
|
|
2021-01-20 10:34:24 +01:00
|
|
|
private boolean isInvisible(Player player) {
|
|
|
|
return player.getGameMode() == GameMode.SPECTATOR || player.hasPotionEffect(PotionEffectType.INVISIBILITY)
|
2021-01-25 14:30:07 +01:00
|
|
|
|| isPluginVanished(player) || !canSee(player);
|
2021-01-20 10:34:24 +01:00
|
|
|
}
|
|
|
|
|
2020-04-13 19:57:20 +02:00
|
|
|
private boolean isPluginVanished(Player player) {
|
|
|
|
for (MetadataValue meta : player.getMetadata("vanished")) {
|
2023-11-05 13:58:37 +01:00
|
|
|
if (meta.asBoolean())
|
2020-04-13 19:57:20 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-10-07 13:16:41 +02:00
|
|
|
public boolean isRandomLook() {
|
|
|
|
return enableRandomLook;
|
|
|
|
}
|
|
|
|
|
2021-01-23 03:52:53 +01:00
|
|
|
private boolean isValid(Player entity) {
|
|
|
|
return entity.isOnline() && entity.isValid() && entity.getWorld() == npc.getEntity().getWorld()
|
2023-06-25 15:58:09 +02:00
|
|
|
&& entity.getLocation().distance(npc.getStoredLocation()) <= range && !isInvisible(entity);
|
2021-01-23 03:52:53 +01:00
|
|
|
}
|
|
|
|
|
2020-04-13 19:57:20 +02:00
|
|
|
@Override
|
|
|
|
public void load(DataKey key) {
|
|
|
|
range = key.getDouble("range");
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Enables/disables the trait
|
|
|
|
*/
|
|
|
|
public void lookClose(boolean lookClose) {
|
|
|
|
enabled = lookClose;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDespawn() {
|
2021-01-20 15:10:47 +01:00
|
|
|
NPCLookCloseChangeTargetEvent event = new NPCLookCloseChangeTargetEvent(npc, lookingAt, null);
|
|
|
|
Bukkit.getPluginManager().callEvent(event);
|
2021-01-23 03:52:53 +01:00
|
|
|
if (event.getNewTarget() != null && isValid(event.getNewTarget())) {
|
|
|
|
lookingAt = event.getNewTarget();
|
|
|
|
} else {
|
|
|
|
lookingAt = null;
|
|
|
|
}
|
2020-04-13 19:57:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private void randomLook() {
|
2020-06-12 18:18:59 +02:00
|
|
|
float pitch = isEqual(randomPitchRange) ? randomPitchRange[0]
|
2022-12-11 14:28:39 +01:00
|
|
|
: Util.getFastRandom().doubles(randomPitchRange[0], randomPitchRange[1]).iterator().next().floatValue();
|
2020-06-12 18:18:59 +02:00
|
|
|
float yaw = isEqual(randomYawRange) ? randomYawRange[0]
|
2022-12-11 14:28:39 +01:00
|
|
|
: Util.getFastRandom().doubles(randomYawRange[0], randomYawRange[1]).iterator().next().floatValue();
|
|
|
|
npc.getOrAddTrait(RotationTrait.class).getPhysicalSession().rotateToHave(yaw, pitch);
|
2020-04-13 19:57:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void run() {
|
2023-04-27 12:55:42 +02:00
|
|
|
if (!npc.isSpawned()) {
|
|
|
|
lookingAt = null;
|
2020-04-13 19:57:20 +02:00
|
|
|
return;
|
2023-04-27 12:55:42 +02:00
|
|
|
}
|
2022-04-19 09:20:59 +02:00
|
|
|
if (enableRandomLook) {
|
|
|
|
if (!npc.getNavigator().isNavigating() && lookingAt == null && t <= 0) {
|
|
|
|
randomLook();
|
|
|
|
t = randomLookDelay;
|
|
|
|
}
|
2020-04-13 19:57:20 +02:00
|
|
|
}
|
2022-11-13 09:02:17 +01:00
|
|
|
t--;
|
|
|
|
|
2023-11-05 13:58:37 +01:00
|
|
|
if (!enabled || npc.getNavigator().isNavigating() && disableWhileNavigating()) {
|
2023-04-27 12:55:42 +02:00
|
|
|
lookingAt = null;
|
2022-04-19 09:20:59 +02:00
|
|
|
return;
|
2023-04-27 12:55:42 +02:00
|
|
|
}
|
2022-11-13 09:02:17 +01:00
|
|
|
findNewTarget();
|
2022-04-19 09:20:59 +02:00
|
|
|
|
2023-05-29 17:40:53 +02:00
|
|
|
if (npc.getNavigator().isNavigating() || npc.getNavigator().isPaused()) {
|
2020-04-13 19:57:20 +02:00
|
|
|
npc.getNavigator().setPaused(lookingAt != null);
|
|
|
|
}
|
2021-01-25 14:30:48 +01:00
|
|
|
if (lookingAt == null)
|
|
|
|
return;
|
2022-04-24 13:22:55 +02:00
|
|
|
|
2023-01-01 17:24:11 +01:00
|
|
|
RotationTrait rot = npc.getOrAddTrait(RotationTrait.class);
|
|
|
|
rot.getGlobalParameters().headOnly(headOnly);
|
2023-05-01 18:50:50 +02:00
|
|
|
rot.getGlobalParameters().linkedBody(linkedBody);
|
2023-01-01 17:24:11 +01:00
|
|
|
rot.getPhysicalSession().rotateToFace(lookingAt);
|
2022-11-13 09:02:17 +01:00
|
|
|
|
2021-01-25 14:30:48 +01:00
|
|
|
if (npc.getEntity().getType().name().equals("SHULKER")) {
|
2022-02-20 14:56:51 +01:00
|
|
|
boolean wasSilent = npc.getEntity().isSilent();
|
|
|
|
npc.getEntity().setSilent(true);
|
2023-06-25 15:58:09 +02:00
|
|
|
NMS.setPeekShulker(npc.getEntity(),
|
|
|
|
100 - 4 * (int) Math.floor(npc.getStoredLocation().distanceSquared(lookingAt.getLocation())));
|
2022-02-20 14:56:51 +01:00
|
|
|
npc.getEntity().setSilent(wasSilent);
|
2020-04-13 19:57:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void save(DataKey key) {
|
|
|
|
key.setDouble("range", range);
|
|
|
|
}
|
|
|
|
|
2021-02-04 02:51:02 +01:00
|
|
|
public void setDisableWhileNavigating(boolean set) {
|
|
|
|
disableWhileNavigating = set;
|
|
|
|
}
|
2023-01-01 17:24:11 +01:00
|
|
|
|
|
|
|
public void setHeadOnly(boolean headOnly) {
|
|
|
|
this.headOnly = headOnly;
|
|
|
|
}
|
2023-05-01 18:50:50 +02:00
|
|
|
|
|
|
|
public void setLinkedBody(boolean linkedBody) {
|
|
|
|
this.linkedBody = linkedBody;
|
|
|
|
}
|
2021-02-04 02:51:02 +01:00
|
|
|
|
2022-12-11 14:28:39 +01:00
|
|
|
public void setPerPlayer(boolean perPlayer) {
|
|
|
|
this.perPlayer = perPlayer;
|
|
|
|
}
|
|
|
|
|
2020-04-13 19:57:20 +02:00
|
|
|
/**
|
2020-04-15 21:04:42 +02:00
|
|
|
* Enables random looking - will look at a random {@link Location} every so often if enabled.
|
2020-04-13 19:57:20 +02:00
|
|
|
*/
|
|
|
|
public void setRandomLook(boolean enableRandomLook) {
|
|
|
|
this.enableRandomLook = enableRandomLook;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the delay between random looking in ticks
|
|
|
|
*/
|
|
|
|
public void setRandomLookDelay(int delay) {
|
2023-11-05 13:58:37 +01:00
|
|
|
randomLookDelay = delay;
|
2020-04-13 19:57:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setRandomLookPitchRange(float min, float max) {
|
2023-11-05 13:58:37 +01:00
|
|
|
randomPitchRange = new float[] { min, max };
|
2020-04-13 19:57:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setRandomLookYawRange(float min, float max) {
|
2023-11-05 13:58:37 +01:00
|
|
|
randomYawRange = new float[] { min, max };
|
2020-04-13 19:57:20 +02:00
|
|
|
}
|
|
|
|
|
2022-11-13 09:02:17 +01:00
|
|
|
public void setRandomlySwitchTargets(boolean randomSwitchTargets) {
|
|
|
|
this.randomSwitchTargets = randomSwitchTargets;
|
|
|
|
}
|
|
|
|
|
2020-04-13 19:57:20 +02:00
|
|
|
/**
|
|
|
|
* Sets the maximum range in blocks to look at other Entities
|
|
|
|
*/
|
2023-07-29 17:26:02 +02:00
|
|
|
public void setRange(double range) {
|
|
|
|
this.range = range;
|
2020-04-13 19:57:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-04-15 21:04:42 +02:00
|
|
|
* Enables/disables realistic looking (using line of sight checks). More computationally expensive.
|
2020-04-13 19:57:20 +02:00
|
|
|
*/
|
|
|
|
public void setRealisticLooking(boolean realistic) {
|
2023-11-05 13:58:37 +01:00
|
|
|
realisticLooking = realistic;
|
2020-04-13 19:57:20 +02:00
|
|
|
}
|
|
|
|
|
2022-12-27 07:22:27 +01:00
|
|
|
public void setTargetNPCs(boolean target) {
|
2023-11-05 13:58:37 +01:00
|
|
|
targetNPCs = target;
|
2022-12-27 07:22:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean targetNPCs() {
|
|
|
|
return targetNPCs;
|
|
|
|
}
|
|
|
|
|
2020-04-13 19:57:20 +02:00
|
|
|
@Override
|
|
|
|
public boolean toggle() {
|
|
|
|
enabled = !enabled;
|
|
|
|
return enabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return "LookClose{" + enabled + "}";
|
|
|
|
}
|
|
|
|
|
2020-10-07 13:16:41 +02:00
|
|
|
public boolean useRealisticLooking() {
|
|
|
|
return realisticLooking;
|
|
|
|
}
|
|
|
|
|
2022-04-19 09:20:59 +02:00
|
|
|
private static boolean isEqual(float[] array) {
|
|
|
|
return Math.abs(array[0] - array[1]) < 0.001;
|
|
|
|
}
|
2012-02-03 10:20:48 +01:00
|
|
|
}
|