diff --git a/main/pom.xml b/main/pom.xml
index 006f2df5e..a2a195690 100644
--- a/main/pom.xml
+++ b/main/pom.xml
@@ -113,7 +113,7 @@
net.byteflux
- libby-bukkit
+ libby-bukkit
1.1.5
diff --git a/main/src/main/java/net/citizensnpcs/Citizens.java b/main/src/main/java/net/citizensnpcs/Citizens.java
index 15cd69549..4fcae7f40 100644
--- a/main/src/main/java/net/citizensnpcs/Citizens.java
+++ b/main/src/main/java/net/citizensnpcs/Citizens.java
@@ -29,6 +29,8 @@
import net.byteflux.libby.BukkitLibraryManager;
import net.byteflux.libby.Library;
+import net.byteflux.libby.LibraryManager;
+import net.byteflux.libby.logging.LogLevel;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.CitizensPlugin;
@@ -284,10 +286,11 @@ public TraitFactory getTraitFactory() {
}
private void loadMavenLibraries() {
- BukkitLibraryManager lib = new BukkitLibraryManager(this);
+ Messaging.log("Downloading libraries, please wait...");
+ LibraryManager lib = new BukkitLibraryManager(this);
lib.addMavenCentral();
+ lib.setLogLevel(LogLevel.WARN);
// Unfortunately, transitive dependency management is not supported in this library.
- // TODO: consider using eclipse aether to resolve dependencies
lib.loadLibrary(Library.builder().groupId("ch{}ethz{}globis{}phtree").artifactId("phtree").version("2.5.0")
.relocate("ch{}ethz{}globis{}phtree", "clib{}phtree").build());
lib.loadLibrary(Library.builder().groupId("net{}sf{}trove4j").artifactId("trove4j").version("3.0.3")
diff --git a/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java b/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java
index 28103fbe4..73345fd45 100644
--- a/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java
+++ b/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java
@@ -1288,7 +1288,7 @@ public void list(CommandContext args, CommandSender sender, NPC npc, @Flag("owne
@Command(
aliases = { "npc" },
- usage = "lookclose --range [range] -r[ealistic looking] --randomlook [true|false] --randompitchrange [min,max] --randomyawrange [min,max]",
+ usage = "lookclose --range [range] -r[ealistic looking] --randomlook [true|false] --randomswitchtargets [true|false] --randompitchrange [min,max] --randomyawrange [min,max] --disablewhennavigating [true|false]",
desc = "Toggle whether a NPC will look when a player is near",
modifiers = { "lookclose", "look", "rotate" },
min = 1,
@@ -1298,7 +1298,8 @@ public void list(CommandContext args, CommandSender sender, NPC npc, @Flag("owne
public void lookClose(CommandContext args, CommandSender sender, NPC npc,
@Flag({ "randomlook", "rlook" }) Boolean randomlook, @Flag("range") Double range,
@Flag("randomlookdelay") Integer randomLookDelay, @Flag("randomyawrange") String randomYaw,
- @Flag("randompitchrange") String randomPitch) throws CommandException {
+ @Flag("randompitchrange") String randomPitch, @Flag("randomswitchtargets") Boolean randomSwitchTargets,
+ @Flag("disablewhennavigating") Boolean disableWhenNavigating) throws CommandException {
boolean toggle = true;
LookClose trait = npc.getOrAddTrait(LookClose.class);
if (randomlook != null) {
@@ -1307,6 +1308,18 @@ public void lookClose(CommandContext args, CommandSender sender, NPC npc,
npc.getName());
toggle = false;
}
+ if (randomSwitchTargets) {
+ trait.setRandomlySwitchTargets(randomSwitchTargets);
+ Messaging.sendTr(sender, randomSwitchTargets ? Messages.LOOKCLOSE_RANDOM_TARGET_SWITCH_ENABLED
+ : Messages.LOOKCLOSE_RANDOM_TARGET_SWITCH_DISABLED, npc.getName());
+ toggle = false;
+ }
+ if (disableWhenNavigating != null) {
+ trait.setDisableWhileNavigating(disableWhenNavigating);
+ Messaging.sendTr(sender, disableWhenNavigating ? Messages.LOOKCLOSE_DISABLE_WHEN_NAVIGATING
+ : Messages.LOOKCLOSE_ENABLE_WHEN_NAVIGATING, npc.getName());
+ toggle = false;
+ }
if (range != null) {
trait.setRange(range);
Messaging.sendTr(sender, Messages.LOOKCLOSE_RANGE_SET, range);
diff --git a/main/src/main/java/net/citizensnpcs/trait/LookClose.java b/main/src/main/java/net/citizensnpcs/trait/LookClose.java
index e6e56ead3..7b4d1ece0 100644
--- a/main/src/main/java/net/citizensnpcs/trait/LookClose.java
+++ b/main/src/main/java/net/citizensnpcs/trait/LookClose.java
@@ -1,5 +1,6 @@
package net.citizensnpcs.trait;
+import java.util.List;
import java.util.Random;
import org.bukkit.Bukkit;
@@ -11,6 +12,8 @@
import org.bukkit.metadata.MetadataValue;
import org.bukkit.potion.PotionEffectType;
+import com.google.common.collect.Lists;
+
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.command.CommandConfigurable;
@@ -43,6 +46,8 @@ public class LookClose extends Trait implements Toggleable, CommandConfigurable
@Persist
private float[] randomPitchRange = { 0, 0 };
@Persist
+ private boolean randomSwitchTargets;
+ @Persist
private float[] randomYawRange = { 0, 360 };
private double range = Setting.DEFAULT_LOOK_CLOSE_RANGE.asDouble();
@Persist("realisticlooking")
@@ -87,20 +92,50 @@ public boolean disableWhileNavigating() {
* Finds a new look-close target
*/
public void findNewTarget() {
- double min = range;
+ 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;
+ }
+ }
+
Player old = lookingAt;
- for (Entity entity : npc.getEntity().getNearbyEntities(range, range, range)) {
- if (!(entity instanceof Player))
- continue;
- Player player = (Player) entity;
- Location location = player.getLocation(CACHE_LOCATION);
- if (location.getWorld() != NPC_LOCATION.getWorld())
- continue;
- double dist = location.distance(NPC_LOCATION);
- if (dist > min || CitizensAPI.getNPCRegistry().getNPC(entity) != null || isInvisible(player))
- continue;
- min = dist;
- lookingAt = player;
+ if (lookingAt != null) {
+ if (randomSwitchTargets && t <= 0) {
+ List options = Lists.newArrayList();
+ for (Entity entity : npc.getEntity().getNearbyEntities(range, range, range)) {
+ if (entity == lookingAt || !(entity instanceof Player)
+ || CitizensAPI.getNPCRegistry().getNPC(entity) != null) {
+ continue;
+ }
+ Player player = (Player) entity;
+ if (player.getLocation().getWorld() != NPC_LOCATION.getWorld() || isInvisible(player))
+ continue;
+ options.add(player);
+ }
+ if (options.size() > 0) {
+ lookingAt = options.get(Util.getFastRandom().nextInt(options.size()));
+ t = randomLookDelay;
+ }
+ }
+ } else {
+ double min = range;
+ for (Entity entity : npc.getEntity().getNearbyEntities(range, range, range)) {
+ if (!(entity instanceof Player))
+ continue;
+ Player player = (Player) entity;
+ Location location = player.getLocation(CACHE_LOCATION);
+ if (location.getWorld() != NPC_LOCATION.getWorld())
+ continue;
+ double dist = location.distance(NPC_LOCATION);
+ if (dist > min || CitizensAPI.getNPCRegistry().getNPC(entity) != null || isInvisible(player))
+ continue;
+ min = dist;
+ lookingAt = player;
+ }
}
if (old != lookingAt) {
@@ -202,10 +237,10 @@ public void run() {
if (!npc.getNavigator().isNavigating() && lookingAt == null && t <= 0) {
randomLook();
t = randomLookDelay;
- } else {
- t--;
}
}
+ t--;
+
if (!enabled)
return;
@@ -213,9 +248,7 @@ public void run() {
return;
npc.getEntity().getLocation(NPC_LOCATION);
- if (tryInvalidateTarget()) {
- findNewTarget();
- }
+ findNewTarget();
if (npc.getNavigator().isNavigating()) {
npc.getNavigator().setPaused(lookingAt != null);
@@ -225,6 +258,7 @@ public void run() {
return;
Util.faceEntity(npc.getEntity(), lookingAt);
+
if (npc.getEntity().getType().name().equals("SHULKER")) {
boolean wasSilent = npc.getEntity().isSilent();
npc.getEntity().setSilent(true);
@@ -265,6 +299,10 @@ public void setRandomLookYawRange(float min, float max) {
this.randomYawRange = new float[] { min, max };
}
+ public void setRandomlySwitchTargets(boolean randomSwitchTargets) {
+ this.randomSwitchTargets = randomSwitchTargets;
+ }
+
/**
* Sets the maximum range in blocks to look at other Entities
*/
@@ -290,21 +328,6 @@ public String toString() {
return "LookClose{" + enabled + "}";
}
- private boolean tryInvalidateTarget() {
- if (lookingAt == null)
- return true;
- if (!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;
- }
- }
- return lookingAt == null;
- }
-
public boolean useRealisticLooking() {
return realisticLooking;
}
diff --git a/main/src/main/java/net/citizensnpcs/util/Messages.java b/main/src/main/java/net/citizensnpcs/util/Messages.java
index c45202a67..84c06665e 100644
--- a/main/src/main/java/net/citizensnpcs/util/Messages.java
+++ b/main/src/main/java/net/citizensnpcs/util/Messages.java
@@ -208,10 +208,14 @@ public class Messages {
public static final String LOADED_ECONOMY = "citizens.economy.loaded";
public static final String LOADING_SUB_PLUGIN = "citizens.sub-plugins.load";
public static final String LOCALE_NOTIFICATION = "citizens.notifications.locale";
+ public static final String LOOKCLOSE_DISABLE_WHEN_NAVIGATING = "citizens.commands.npc.lookclose.disable-when-navigating";
+ public static final String LOOKCLOSE_ENABLE_WHEN_NAVIGATING = "citizens.commands.npc.lookclose.enable-when-navigating";
public static final String LOOKCLOSE_RANDOM_DELAY_SET = "citizens.commands.npc.lookclose.random-look-delay-set";
public static final String LOOKCLOSE_RANDOM_PITCH_RANGE_SET = "citizens.commands.npc.lookclose.random-pitch-range-set";
public static final String LOOKCLOSE_RANDOM_SET = "citizens.commands.npc.lookclose.random-set";
public static final String LOOKCLOSE_RANDOM_STOPPED = "citizens.commands.npc.lookclose.random-stopped";
+ public static final String LOOKCLOSE_RANDOM_TARGET_SWITCH_DISABLED = "citizens.commands.npc.lookclose.random-target-switch-disabled";
+ public static final String LOOKCLOSE_RANDOM_TARGET_SWITCH_ENABLED = "citizens.commands.npc.lookclose.random-target-switch-enabled";
public static final String LOOKCLOSE_RANDOM_YAW_RANGE_SET = "citizens.commands.npc.lookclose.random-yaw-range-set";
public static final String LOOKCLOSE_RANGE_SET = "citizens.commands.npc.lookclose.range-set";
public static final String LOOKCLOSE_REALISTIC_LOOK_SET = "citizens.commands.npc.lookclose.rl-set";
diff --git a/main/src/main/resources/messages_en.properties b/main/src/main/resources/messages_en.properties
index 90fc795a0..86d7dccf4 100644
--- a/main/src/main/resources/messages_en.properties
+++ b/main/src/main/resources/messages_en.properties
@@ -148,6 +148,10 @@ citizens.commands.npc.lookclose.random-set=[[{0}]] will now randomly look around
citizens.commands.npc.lookclose.random-stopped=[[{0}]] will no longer randomly look around.
citizens.commands.npc.lookclose.error-random-range=Invalid range [[{0}]]. Use the format `min,max`.
citizens.commands.npc.lookclose.set=[[{0}]] will now rotate when players are nearby.
+citizens.commands.npc.lookclose.enable-when-navigating=[[{0}]] will now look close when navigating.
+citizens.commands.npc.lookclose.disable-when-navigating=[[{0}]] will no longer look close when navigating.
+citizens.commands.npc.lookclose.random-target-switch-enabled=[[{0}]] will now randomly switch targets depending on the random look delay.
+citizens.commands.npc.lookclose.random-target-switch-disabled=[[{0}]] will no longer randomly switch targets.
citizens.commands.npc.lookclose.stopped=[[{0}]] will no longer rotate when players are nearby.
citizens.commands.npc.metadata.set=[[{0}]] set to [[{1}]].
citizens.commands.npc.metadata.unset=Removed [[{0}]] from [[{1}]].