diff --git a/README.md b/README.md index 2d3d833..1481012 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,32 @@ This plugin adds additional visual and audial details to blacksmiths while they are working, so it's easier to see if they are working or not. It is recommended to put a mace or other hammer-like item in the NPC's off-hand for full -effect. \ No newline at end of file +effect. + +## FAQ + +### Citizens lookclose makes NPC rotate weirdly + +It has been found that with some options, lookclose can still be used. An example of a working lookclose setup is: +`/npc lookclose --linkedbody false --disablewhennavigating true --perplayer true --range 3 --targetnpcs false --headonly true --linkedbody false -r false` +Some other options might work as well, but a lot of options won't, as it messes with manual NPC rotation. Keep that in +mind. + +### NPCs teleport part of the way while walking to or from a crafting station + +This behavior is inevitable. As Citizens pathing is not very accurate (as described in Citizens' FAQ), the NPC must be +teleported to end up in the correct spot. + +## Commands + +| Command | Options | Description | +|-------------------------------------|--------------------------------------------------------------------------|----------------------------------------------------------------------------------------------| +| /reload (/blacksmithvisuals:reload) | | Reloads the plugin | +| /setNPCPosition | idle, netherite-workstation, reforging-workstation, crafting-workstation | Sets an idle or working position for an NPC to the current location of the executing player. | + +## Permissions + +| Permission | Description | +|-------------------------------|---------------------------------------------| +| blacksmithvisuals.reload | Gives access to the reload command | +| blacksmithvisuals.setposition | Gives access to the /setNPCPosition command | \ No newline at end of file diff --git a/src/main/java/net/knarcraft/blacksmithvisuals/listener/BlacksmithListener.java b/src/main/java/net/knarcraft/blacksmithvisuals/listener/BlacksmithListener.java index 5ab082e..1706e8a 100644 --- a/src/main/java/net/knarcraft/blacksmithvisuals/listener/BlacksmithListener.java +++ b/src/main/java/net/knarcraft/blacksmithvisuals/listener/BlacksmithListener.java @@ -5,6 +5,7 @@ import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.events.PacketContainer; import net.citizensnpcs.api.npc.NPC; +import net.citizensnpcs.trait.LookClose; import net.knarcraft.blacksmith.event.ActionStartEvent; import net.knarcraft.blacksmith.event.BlacksmithReforgeFailEvent; import net.knarcraft.blacksmith.event.BlacksmithReforgeStartEvent; @@ -27,11 +28,15 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.scheduler.BukkitScheduler; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.HashMap; +import java.util.Map; import java.util.Random; +import java.util.UUID; import java.util.logging.Level; /** @@ -41,6 +46,7 @@ public class BlacksmithListener implements Listener { private final Random random; private final ConfigurationManager configurationManager; + private final Map oldLookRanges; /** * Instantiates a new blacksmith listener @@ -50,6 +56,7 @@ public class BlacksmithListener implements Listener { public BlacksmithListener(@NotNull ConfigurationManager configurationManager) { this.random = new Random(); this.configurationManager = configurationManager; + this.oldLookRanges = new HashMap<>(); } @EventHandler @@ -101,6 +108,11 @@ public class BlacksmithListener implements Listener { NPC npc = event.getNpc(); long delay = moveToWorkingPosition(npc, NPCPosition.getFromMaterial(event.getCraftingStation())); + if (npc.hasTrait(LookClose.class)) { + LookClose trait = npc.getTraitNullable(LookClose.class); + this.oldLookRanges.put(npc.getUniqueId(), trait.getRange()); + trait.setRange(0); + } long finishTime = event.getActionDurationTicks() - (2 * delay); scheduler.scheduleSyncDelayedTask(instance, () -> startWorkAnimation(npc.getEntity(), @@ -130,6 +142,14 @@ public class BlacksmithListener implements Listener { return; } + if (npc.hasTrait(LookClose.class)) { + LookClose trait = npc.getTraitNullable(LookClose.class); + Double oldRange = oldLookRanges.remove(npc.getUniqueId()); + if (oldRange != null) { + trait.setRange(oldRange); + } + } + Bukkit.getScheduler().scheduleSyncDelayedTask(BlacksmithVisuals.getInstance(), () -> npc.getEntity().teleport(targetLocation), getWalkTime(npc.getEntity().getLocation(), targetLocation)); npc.getNavigator().setTarget(targetLocation); @@ -165,13 +185,16 @@ public class BlacksmithListener implements Listener { npc.getName() + " is unreachable!"); return 0; } + Location finalTargetLocation = targetLocation; // Move NPC using Citizens path-finding - npc.getNavigator().setTarget(targetLocation); + Location current = npc.getEntity().getLocation().clone(); + npc.teleport(current.setDirection(targetLocation.toVector().subtract(current.toVector())), PlayerTeleportEvent.TeleportCause.PLUGIN); + + Bukkit.getScheduler().scheduleSyncDelayedTask(BlacksmithVisuals.getInstance(), () -> npc.getNavigator().setTarget(finalTargetLocation), 2); // Teleport the NPC tp get it in the exact final location long walkTime = getWalkTime(npc.getEntity().getLocation(), targetLocation); - Location finalTargetLocation = targetLocation; Bukkit.getScheduler().scheduleSyncDelayedTask(BlacksmithVisuals.getInstance(), () -> npc.getEntity().teleport(finalTargetLocation), walkTime); return walkTime; diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index bd25ce0..a99a4da 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -31,5 +31,5 @@ permissions: description: Allows reloading the plugin default: false blacksmithvisuals.setposition: - description: Allows use of the /setIdlePosition and /setWorkingPosition commands + description: Allows use of the /setNPCPosition command default: false \ No newline at end of file