Makes some lookclose situations work, and updates documentation
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				KnarCraft/BlacksmithVisuals/pipeline/head This commit looks good
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	KnarCraft/BlacksmithVisuals/pipeline/head This commit looks good
				
			This commit is contained in:
		
							
								
								
									
										28
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								README.md
									
									
									
									
									
								
							@@ -3,3 +3,31 @@
 | 
				
			|||||||
This plugin adds additional visual and audial details to blacksmiths while they are working, so it's easier to see if
 | 
					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
 | 
					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.
 | 
					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 <positionType>      | 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 |
 | 
				
			||||||
@@ -5,6 +5,7 @@ import com.comphenix.protocol.ProtocolLibrary;
 | 
				
			|||||||
import com.comphenix.protocol.ProtocolManager;
 | 
					import com.comphenix.protocol.ProtocolManager;
 | 
				
			||||||
import com.comphenix.protocol.events.PacketContainer;
 | 
					import com.comphenix.protocol.events.PacketContainer;
 | 
				
			||||||
import net.citizensnpcs.api.npc.NPC;
 | 
					import net.citizensnpcs.api.npc.NPC;
 | 
				
			||||||
 | 
					import net.citizensnpcs.trait.LookClose;
 | 
				
			||||||
import net.knarcraft.blacksmith.event.ActionStartEvent;
 | 
					import net.knarcraft.blacksmith.event.ActionStartEvent;
 | 
				
			||||||
import net.knarcraft.blacksmith.event.BlacksmithReforgeFailEvent;
 | 
					import net.knarcraft.blacksmith.event.BlacksmithReforgeFailEvent;
 | 
				
			||||||
import net.knarcraft.blacksmith.event.BlacksmithReforgeStartEvent;
 | 
					import net.knarcraft.blacksmith.event.BlacksmithReforgeStartEvent;
 | 
				
			||||||
@@ -27,11 +28,15 @@ import org.bukkit.entity.Entity;
 | 
				
			|||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
import org.bukkit.event.EventHandler;
 | 
					import org.bukkit.event.EventHandler;
 | 
				
			||||||
import org.bukkit.event.Listener;
 | 
					import org.bukkit.event.Listener;
 | 
				
			||||||
 | 
					import org.bukkit.event.player.PlayerTeleportEvent;
 | 
				
			||||||
import org.bukkit.scheduler.BukkitScheduler;
 | 
					import org.bukkit.scheduler.BukkitScheduler;
 | 
				
			||||||
import org.jetbrains.annotations.NotNull;
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
import org.jetbrains.annotations.Nullable;
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.HashMap;
 | 
				
			||||||
 | 
					import java.util.Map;
 | 
				
			||||||
import java.util.Random;
 | 
					import java.util.Random;
 | 
				
			||||||
 | 
					import java.util.UUID;
 | 
				
			||||||
import java.util.logging.Level;
 | 
					import java.util.logging.Level;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -41,6 +46,7 @@ public class BlacksmithListener implements Listener {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private final Random random;
 | 
					    private final Random random;
 | 
				
			||||||
    private final ConfigurationManager configurationManager;
 | 
					    private final ConfigurationManager configurationManager;
 | 
				
			||||||
 | 
					    private final Map<UUID, Double> oldLookRanges;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Instantiates a new blacksmith listener
 | 
					     * Instantiates a new blacksmith listener
 | 
				
			||||||
@@ -50,6 +56,7 @@ public class BlacksmithListener implements Listener {
 | 
				
			|||||||
    public BlacksmithListener(@NotNull ConfigurationManager configurationManager) {
 | 
					    public BlacksmithListener(@NotNull ConfigurationManager configurationManager) {
 | 
				
			||||||
        this.random = new Random();
 | 
					        this.random = new Random();
 | 
				
			||||||
        this.configurationManager = configurationManager;
 | 
					        this.configurationManager = configurationManager;
 | 
				
			||||||
 | 
					        this.oldLookRanges = new HashMap<>();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler
 | 
					    @EventHandler
 | 
				
			||||||
@@ -101,6 +108,11 @@ public class BlacksmithListener implements Listener {
 | 
				
			|||||||
        NPC npc = event.getNpc();
 | 
					        NPC npc = event.getNpc();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        long delay = moveToWorkingPosition(npc, NPCPosition.getFromMaterial(event.getCraftingStation()));
 | 
					        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);
 | 
					        long finishTime = event.getActionDurationTicks() - (2 * delay);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        scheduler.scheduleSyncDelayedTask(instance, () -> startWorkAnimation(npc.getEntity(),
 | 
					        scheduler.scheduleSyncDelayedTask(instance, () -> startWorkAnimation(npc.getEntity(),
 | 
				
			||||||
@@ -130,6 +142,14 @@ public class BlacksmithListener implements Listener {
 | 
				
			|||||||
            return;
 | 
					            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(), () ->
 | 
					        Bukkit.getScheduler().scheduleSyncDelayedTask(BlacksmithVisuals.getInstance(), () ->
 | 
				
			||||||
                npc.getEntity().teleport(targetLocation), getWalkTime(npc.getEntity().getLocation(), targetLocation));
 | 
					                npc.getEntity().teleport(targetLocation), getWalkTime(npc.getEntity().getLocation(), targetLocation));
 | 
				
			||||||
        npc.getNavigator().setTarget(targetLocation);
 | 
					        npc.getNavigator().setTarget(targetLocation);
 | 
				
			||||||
@@ -165,13 +185,16 @@ public class BlacksmithListener implements Listener {
 | 
				
			|||||||
                    npc.getName() + " is unreachable!");
 | 
					                    npc.getName() + " is unreachable!");
 | 
				
			||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        Location finalTargetLocation = targetLocation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Move NPC using Citizens path-finding
 | 
					        // 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
 | 
					        // Teleport the NPC tp get it in the exact final location
 | 
				
			||||||
        long walkTime = getWalkTime(npc.getEntity().getLocation(), targetLocation);
 | 
					        long walkTime = getWalkTime(npc.getEntity().getLocation(), targetLocation);
 | 
				
			||||||
        Location finalTargetLocation = targetLocation;
 | 
					 | 
				
			||||||
        Bukkit.getScheduler().scheduleSyncDelayedTask(BlacksmithVisuals.getInstance(), () ->
 | 
					        Bukkit.getScheduler().scheduleSyncDelayedTask(BlacksmithVisuals.getInstance(), () ->
 | 
				
			||||||
                npc.getEntity().teleport(finalTargetLocation), walkTime);
 | 
					                npc.getEntity().teleport(finalTargetLocation), walkTime);
 | 
				
			||||||
        return walkTime;
 | 
					        return walkTime;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,5 +31,5 @@ permissions:
 | 
				
			|||||||
    description: Allows reloading the plugin
 | 
					    description: Allows reloading the plugin
 | 
				
			||||||
    default: false
 | 
					    default: false
 | 
				
			||||||
  blacksmithvisuals.setposition:
 | 
					  blacksmithvisuals.setposition:
 | 
				
			||||||
    description: Allows use of the /setIdlePosition and /setWorkingPosition commands
 | 
					    description: Allows use of the /setNPCPosition command
 | 
				
			||||||
    default: false
 | 
					    default: false
 | 
				
			||||||
		Reference in New Issue
	
	Block a user