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}]].