package de.domisum.animulusapi.npc.task.tasks.movement;

import de.domisum.animulusapi.npc.task.NPCTask;
import de.domisum.animulusapi.npc.task.NPCTaskSlot;
import de.domisum.auxiliumapi.util.java.annotations.APIUsage;
import org.bukkit.Location;

@APIUsage
public class NPCTaskLookTowards extends NPCTask
{

	// CONSTANTS
	private static NPCTaskSlot[] USED_TASK_SLOTS = new NPCTaskSlot[] {NPCTaskSlot.HEAD_ROTATION};

	private static final float TOLERANCE = 1;
	private static final float BASE_SPEED = 10; // degrees per tick

	// PROPERTIES
	private float targetYaw;
	private float targetPitch;
	private double speedMultiplier;


	// -------
	// CONSTRUCTOR
	// -------
	@APIUsage
	public NPCTaskLookTowards(float targetYaw, float targetPitch)
	{
		this(targetYaw, targetPitch, 1);
	}

	@APIUsage
	public NPCTaskLookTowards(float targetYaw, float targetPitch, double speedMultiplier)
	{
		super();

		this.targetYaw = (targetYaw%360+360)%360;
		this.targetPitch = targetPitch;
		this.speedMultiplier = speedMultiplier;
	}


	// -------
	// GETTERS
	// -------
	@Override
	public NPCTaskSlot[] USED_TASK_SLOTS()
	{
		return USED_TASK_SLOTS;
	}


	// -------
	// EXECUTION
	// -------
	@Override
	protected void onStart()
	{

	}

	@Override
	protected boolean onUpdate()
	{
		Location currentLocation = this.npc.getLocation();

		float dYaw = (this.targetYaw-currentLocation.getYaw())%360;
		if(dYaw < 0)
			dYaw += 360;
		if(dYaw > 180)
			dYaw -= 360;

		float dPitch = this.targetPitch-currentLocation.getPitch();

		if(Math.abs(dYaw)+Math.abs(dPitch) < TOLERANCE)
			return false;

		float stepDYaw = getClampedDelta(dYaw);
		float stepDPitch = getClampedDelta(dPitch);

		this.npc.setYawPitch(currentLocation.getYaw()+stepDYaw, currentLocation.getPitch()+stepDPitch);
		return true;
	}

	private float getClampedDelta(float value)
	{
		return (float) ((value < 0 ? -1 : 1)*Math.min(Math.abs(value), BASE_SPEED*this.speedMultiplier));
	}


	@Override
	protected void onCancel()
	{

	}

}

@@ -184,38 +184,138 @@
 api.
-util.java.annotations.APIUsage
+data.container.Duo;%0Aimport de.domisum.auxiliumapi.util.java.annotations.APIUsage;%0Aimport de.domisum.auxiliumapi.util.math.MathUtil
 ;%0Aim
@@ -1424,199 +1424,156 @@
 ();%0A
-%0A
 %09%09
-float dYaw = (this.targetYaw-currentLocation.getYaw())%25360;%0A%09%09if(dYaw %3C 0)%0A%09%09%09dYaw += 360;%0A%09%09if(dYaw %3E 180)%0A%09%09%09dYaw -= 360;%0A%0A%09%09float dPitch = this.targetPitch-currentLocation.getPitch(
+Duo%3CFloat, Float%3E stepYawAndPitch = getStepYawAndPitch(currentLocation, this.targetYaw, this.targetPitch,%0A%09%09%09%09BASE_SPEED*this.speedMultiplier
 );%0A%0A
+%0A
 %09%09if
@@ -1582,20 +1582,33 @@
 ath.abs(
-dYaw
+stepYawAndPitch.a
 )+Math.a
@@ -1610,22 +1610,33 @@
 ath.abs(
+stepYawAn
 dPitch
+.b
 ) %3C TOLE
@@ -1664,96 +1664,8 @@
 e;%0A%0A
-%09%09float stepDYaw = getClampedDelta(dYaw);%0A%09%09float stepDPitch = getClampedDelta(dPitch);%0A
 %0A%09%09t
@@ -1717,12 +1717,21 @@
 step
-D
 Yaw
+AndPitch.a
 , cu
@@ -1763,14 +1763,21 @@
 step
-D
+YawAnd
 Pitch
+.b
 );%0A%09
@@ -1797,202 +1797,575 @@
 %0A%09%7D%0A
+%09
 %0A%09
-private float getClampedDelta(float value)%0A%09%7B%0A%09%09return (float) ((value %3C 0 ? -1 : 1)*Math.min(Math.abs(value), BASE_SPEED*this.speedMultiplier));%0A%09%7D%0A%0A%0A%09@Override%0A%09protected void onCancel()%0A%09%7B%0A
+@Override%0A%09protected void onCancel()%0A%09%7B%0A%0A%09%7D%0A%0A%0A%09// -------%0A%09// UTIL%0A%09// -------%0A%09@APIUsage%0A%09public static Duo%3CFloat, Float%3E getStepYawAndPitch(Location currentLocation, float targetYaw, float targetPitch, double speed)%0A%09%7B%0A%09%09float dYaw = (targetYaw-currentLocation.getYaw())%25360;%0A%09%09if(dYaw %3C 0)%0A%09%09%09dYaw += 360;%0A%09%09if(dYaw %3E 180)%0A%09%09%09dYaw -= 360;%0A%0A%09%09float dPitch = targetPitch-currentLocation.getPitch();%0A%0A%09%09float stepDYaw = (float) MathUtil.clampAbs(dYaw, speed);%0A%09%09float stepDPitch = (float) MathUtil.clampAbs(dPitch, speed);%0A%09%09return new Duo%3C%3E(stepDYaw, stepDPitch);
 %0A%09%7D%0A

Split look towards task into modules