package mhfc.net.common.ai.general;
import java.util.Objects;
import mhfc.net.common.entity.type.EntityMHFCBase;
import mhfc.net.common.util.world.WorldHelper;
import net.minecraft.entity.Entity;
import net.minecraft.util.Vec3;
public class TargetTurnHelper {
private EntityMHFCBase<?> entity;
private Vec3 targetPoint;
private float maxTurnSpeed;
private boolean isUpdating;
public TargetTurnHelper(EntityMHFCBase<?> controlledEntity) {
this.entity = Objects.requireNonNull(controlledEntity);
}
/**
* Sets the target point for turns to the position given by the vector
*/
public void updateTargetPoint(Vec3 vector) {
if (vector == null) {
return;
}
isUpdating = true;
this.targetPoint = vector.addVector(0, 0, 0);
}
/**
* Sets the target point for turns to the given position
*/
public void updateTargetPoint(double x, double y, double z) {
isUpdating = true;
this.targetPoint = Vec3.createVectorHelper(x, y, z);
}
/**
* Sets the entity as a target for turning
*/
public void updateTargetPoint(Entity entity) {
if (entity == null) {
return;
}
isUpdating = true;
this.targetPoint = Vec3.createVectorHelper(entity.posX, entity.posY, entity.posZ);
}
/**
* Controls the maximum turn rate. Negative values will get defaulted to 0
*/
public void updateTurnSpeed(float maxTurnSpeed) {
isUpdating = true;
this.maxTurnSpeed = maxTurnSpeed > 0 ? maxTurnSpeed : 0;
}
public void forceUpdate() {
isUpdating = true;
}
public boolean isUpdating() {
return isUpdating;
}
/**
* <b> Do not call this yourself. </b><br>
* Performs the update and resets the update status to false. This means you have to set something (target point,
* speed) or call {@link TargetTurnHelper#forceUpdate()} each entity update. This then gets called last from
* EntityMHFCBase in {@link EntityMHFCBase#updateAITick()}, so before the Minecraft default helpers are called.
*/
public void onUpdateTurn() {
if (!isUpdating) {
return;
}
isUpdating = false;
if (targetPoint == null) {
return;
}
Vec3 entityPos = WorldHelper.getEntityPositionVector(entity);
Vec3 vecToTarget = entityPos.subtract(targetPoint);
float newYaw = AIUtils.modifyYaw(entity.getLookVec(), vecToTarget.normalize(), maxTurnSpeed);
if (!Float.isNaN(newYaw)) {
entity.rotationYaw = newYaw;
}
// CLEANUP Figure out a way to send the updates to the client cleanly
entity.addVelocity(10e-4, 0, 10e-4);
}
}