The issue happens with any MoveToBlockGoal, regardless of my code. Nothing in my entity's code seems to effect the navigator so I think my entity's scale or bounding box.
Just in case, here's my entity class code...
package com.shilohthecreator.firsttestmod.entities;
import com.google.common.collect.ImmutableSet;
import com.shilohthecreator.firsttestmod.FirstTestMod;
import com.shilohthecreator.firsttestmod.goals.*;
import com.shilohthecreator.firsttestmod.init.CustomEntityTypes;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.entity.*;
import net.minecraft.entity.ai.goal.*;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.merchant.villager.AbstractVillagerEntity;
import net.minecraft.entity.monster.CreeperEntity;
import net.minecraft.entity.monster.GhastEntity;
import net.minecraft.entity.monster.MonsterEntity;
import net.minecraft.entity.passive.TameableEntity;
import net.minecraft.entity.passive.WolfEntity;
import net.minecraft.entity.passive.horse.AbstractHorseEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.AbstractArrowEntity;
import net.minecraft.entity.projectile.ProjectileHelper;
import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ArmorItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.potion.EffectInstance;
import net.minecraft.potion.Effects;
import net.minecraft.tags.ItemTags;
import net.minecraft.util.*;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import javax.swing.plaf.synth.SynthScrollBarUI;
import java.util.Set;
import java.util.function.Predicate;
public class LavaAnimal extends TameableEntity implements IRangedAttackMob {
private int exampleTimer;
int scanningRange = 12;
int inventorySize = 5;
private final Inventory mainInventory = new Inventory(inventorySize);
public final NonNullList<ItemStack> armorInventory = NonNullList.withSize(4, ItemStack.EMPTY);
public static final Predicate<LivingEntity> TARGET_ENTITIES = (p_213440_0_) -> {
EntityType<?> entitytype = p_213440_0_.getType();
return entitytype == EntityType.SKELETON || entitytype == EntityType.ZOMBIE || entitytype == EntityType.SPIDER;
};
//CREATE BITS OF DATA TO STORE OVER TIME
private static final DataParameter<Integer> ANIMAL_MODE = EntityDataManager.createKey(LavaAnimal.class, DataSerializers.VARINT);
private static final DataParameter<BlockPos> GUARDING_POSITION = EntityDataManager.createKey(LavaAnimal.class, DataSerializers.BLOCK_POS);
private final FollowOwnerGoal followOwner = new FollowOwnerGoal(this, 1.0D, 10.0F, 2.0F, false);
private final MeleeAttackWithSpeedGoal meleeAttackWithSpeedGoal = new MeleeAttackWithSpeedGoal(this, 1.1D, false, 7);
private final RangedVillagerBowAttackGoal rangedVillagerBowAttackGoal = new RangedVillagerBowAttackGoal(this, 0.1f,10, scanningRange, false);
private final WaterAvoidingRandomWalkingGoal waterAvoidRandomWalkingGoal = new WaterAvoidingRandomWalkingGoal(this, 2.00D);
private final MoveToBlockPosGoal moveToBlockPosGoal= new MoveToBlockPosGoal(new BlockPos(BlockPos.ZERO), this, 1.0f,3);
//private final MineNearestBlockGoal mineNearestBlockGoal = new MineNearestBlockGoal(Blocks.STRIPPED_OAK_LOG, this, 1.0f, 8, 4);
//private final MineNearestBlockGoal mineNearestBlockGoal2 = new MineNearestBlockGoal(Blocks.OAK_LOG, this, 1.0f, 8, 4);
private final testNavigatorGoal testNavigatorGoal = new testNavigatorGoal(Blocks.ORANGE_WOOL, this,1.0f,3);
private final NearestAttackableTargetInRangeGoal NATInRangeGoal = new NearestAttackableTargetInRangeGoal<>(this, MonsterEntity.class, false,new BlockPos(BlockPos.ZERO), scanningRange);
private final HurtByTargetNoReinforcementsGoal hurtByTargetNoReinforcementsGoal = new HurtByTargetNoReinforcementsGoal(this);
public LavaAnimal(EntityType<? extends TameableEntity> type, World worldIn) {
super(type, worldIn);
this.enablePersistence();
this.getNavigator().setCanSwim(true);
this.setCanPickUpLoot(true);
}
@Override
public AgeableEntity createChild(AgeableEntity ageable) {
LavaAnimal animal = new LavaAnimal(CustomEntityTypes.LAVA_ANIMAL.get(), this.world);
animal.onInitialSpawn(this.world, this.world.getDifficultyForLocation(new BlockPos(animal)), SpawnReason.BREEDING, (ILivingEntityData) null, (CompoundNBT) null);
//YOU CAN DO STUFF HERE
animal.setGlowing(true);
return animal;
}
@Override
protected void registerGoals(){
super.registerGoals();
this.goalSelector.addGoal(0, new SwimGoal(this));
// this.goalSelector.addGoal(7, new LookAtGoal(this, MonsterEntity.class, 30.0f));
//this.goalSelector.addGoal(7, new LookAtGoal(this, PlayerEntity.class, 10.0f));
//this.goalSelector.addGoal(8, new LookRandomlyGoal(this));
}
@Override
protected void registerAttributes() {
super.registerAttributes();
this.getAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(30.0D);
this.getAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.33D);
this.getAttributes().registerAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(6.0D);
}
@Override
public void livingTick() {
if (this.world.isRemote){
this.exampleTimer = Math.max(0, this.exampleTimer - 1);
}
if (this.getAttackTarget() != null){
this.getAttackTarget().addPotionEffect(new EffectInstance(Effects.GLOWING, 15, 255));
}
if (isSwingInProgress){
this.updateArmSwingProgress();
}
// if (!this.world.isRemote()){
//
// System.out.println("ms " + this.moveStrafing);
// System.out.println("mf " + this.moveForward);
//
// }
super.livingTick();
}
@Override
public void setMoveStrafing(float amount) {
if (getAttackTarget() == null){
this.moveStrafing = 0;
} else {
super.setMoveStrafing(amount);
}
}
/**
* CALLED BY MOB ENTITY IN LIVING TICK WHEN AN ITEM IS DROPPED NEARBY
*/
protected void updateEquipmentIfNeeded(ItemEntity droppedItem) {
//The item on the ground
ItemStack droppedStack = droppedItem.getItem();
//The Slot that it should go in
EquipmentSlotType equipmentslottype = getSlotForItemStack(droppedStack);
//The item we currently have in that slot
ItemStack currentItem = this.getItemStackFromSlot(equipmentslottype);
ItemStack currentItem2 = armorInventory.get(equipmentslottype.getIndex());
//IF THIS IS A KNOWN PIECE OF EQUIPMENT (TOOLS ARMOUR)
if (ItemTags.getCollection().get(new ResourceLocation(FirstTestMod.MOD_ID, "villagertools")).contains(droppedItem.getItem().getItem())){
//Mob Entity has func for this, checks which item does/blocks more damage
boolean newItemIsBetter = this.shouldExchangeEquipment(droppedStack, currentItem, equipmentslottype);
if (newItemIsBetter) {
this.entityDropItem(currentItem, 0.5f);
this.setItemStackToSlot(equipmentslottype, droppedStack);
this.onItemPickup(droppedItem, droppedItem.getItem().getCount());
droppedItem.remove();
armorInventory.set(equipmentslottype.getIndex(),droppedStack);
System.out.println("Setting " + droppedStack.getItem().getRegistryName() + " to replace" + currentItem2.getItem().getRegistryName());
} else {
//PLAY GRUNT SOUND
}
} else {
int emptySlot = -1;
if (!isInventoryFull()){
//LOOK FOR A STACK OF THE SAME ITEM SOMEWHERE
for(int i = 0; i < this.mainInventory.getSizeInventory(); ++i) {
ItemStack itemStackInSlot = mainInventory.getStackInSlot(i);
if (itemStackInSlot.getItem() == droppedStack.getItem() && itemStackInSlot.getCount() < itemStackInSlot.getItem().getItemStackLimit(itemStackInSlot)) {
this.onItemPickup(droppedItem, droppedItem.getItem().getCount());
//INCREASE THE SLOT SIZE BY 1
mainInventory.setInventorySlotContents(i,new ItemStack(itemStackInSlot.getItem(), itemStackInSlot.getCount() + droppedStack.getCount()));
droppedItem.remove();
/*
System.out.println("-----");
System.out.println("There are " + mainInventory.getStackInSlot(i).getCount() + " " + itemStackInSlot.getItem().getRegistryName() + "s in this slot");
System.out.println("is the same item? " + (itemStackInSlot.getItem() == droppedStack.getItem()));
System.out.println("Max stack for this item is "+ itemStackInSlot.getItem().getItemStackLimit(itemStackInSlot));
*/
return;
} else if (itemStackInSlot.isEmpty()) {
emptySlot = i;
}
}
//IF WE FOUND AN EMPTY SLOT PUT IT THERE
if (emptySlot != -1){
this.onItemPickup(droppedItem, droppedItem.getItem().getCount());
//INCREASE THE SLOT SIZE BY 1
mainInventory.setInventorySlotContents(emptySlot,droppedStack);
droppedItem.remove();
return;
}
} else {
//INVENTORY FULL
// PLAY GRUNT SOUND
}
}
}
/**
* Attack the specified entity using a ranged attack.
*/
public void attackEntityWithRangedAttack(LivingEntity target, float distanceFactor) {
ItemStack itemstack = this.findAmmo(this.getHeldItem(ProjectileHelper.getHandWith(this, Items.BOW)));
AbstractArrowEntity abstractarrowentity = this.fireArrow(itemstack, distanceFactor);
if (this.getHeldItemMainhand().getItem() instanceof net.minecraft.item.BowItem)
abstractarrowentity = ((net.minecraft.item.BowItem)this.getHeldItemMainhand().getItem()).customeArrow(abstractarrowentity);
double d0 = target.getPosX() - this.getPosX();
double d1 = target.getPosYHeight(0.3333333333333333D) - abstractarrowentity.getPosY();
double d2 = target.getPosZ() - this.getPosZ();
double d3 = (double) MathHelper.sqrt(d0 * d0 + d2 * d2);
abstractarrowentity.shoot(d0, d1 + d3 * (double)0.2F, d2, 1.6F, (float)(14 - this.world.getDifficulty().getId() * 4));
this.playSound(SoundEvents.ENTITY_SKELETON_SHOOT, 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F));
this.world.addEntity(abstractarrowentity);
}
/**
* Fires an arrow
*/
protected AbstractArrowEntity fireArrow(ItemStack arrowStack, float distanceFactor) {
return ProjectileHelper.fireArrow(this, arrowStack, distanceFactor);
}
@Override
protected void registerData() {
super.registerData();
this.getDataManager().register(ANIMAL_MODE, 0);
this.getDataManager().register(GUARDING_POSITION, BlockPos.ZERO);
}
@Override
public boolean processInteract(PlayerEntity player, Hand hand) {
if (hand == Hand.MAIN_HAND){
this.setTamedBy(player);
if (getAnimalMode() == 1){
setAnimalMode(0);
} else {
setGuardingPosition(this.getPosition());
setAnimalMode(1);
player.world.setBlockState(this.getGuardingPosition().down(), Blocks.RED_WOOL.getDefaultState());
}
}
updateGoalData();
addProperGoalSet();
return true;
}
@Override
public void onCollideWithPlayer(PlayerEntity entityIn) {
super.onCollideWithPlayer(entityIn);
for(int i = 0; i < this.mainInventory.getSizeInventory(); ++i) {
if (!this.mainInventory.getStackInSlot(i).isEmpty()){
this.entityDropItem(this.mainInventory.getStackInSlot(i));
mainInventory.removeStackFromSlot(i);
}
}
}
public void addProperGoalSet(){
if (getAnimalMode() == 0){
//FOLLOW MODE
this.goalSelector.removeGoal(moveToBlockPosGoal);
this.goalSelector.removeGoal(meleeAttackWithSpeedGoal);
this.goalSelector.removeGoal(rangedVillagerBowAttackGoal);
this.targetSelector.removeGoal(NATInRangeGoal);
this.targetSelector.removeGoal(hurtByTargetNoReinforcementsGoal);
this.goalSelector.addGoal(2, testNavigatorGoal);
//this.goalSelector.addGoal(2, mineNearestBlockGoal);
//this.goalSelector.addGoal(3, mineNearestBlockGoal2);
this.goalSelector.addGoal(4, followOwner);
//this.goalSelector.addGoal(5, waterAvoidRandomWalkingGoal);
} else {
//GUARDING MODE
this.goalSelector.removeGoal(followOwner);
// this.goalSelector.removeGoal(mineNearestBlockGoal);
//this.goalSelector.removeGoal(mineNearestBlockGoal2);
//this.goalSelector.removeGoal(waterAvoidRandomWalkingGoal);
this.goalSelector.removeGoal(testNavigatorGoal);
this.targetSelector.addGoal(1, hurtByTargetNoReinforcementsGoal);
this.targetSelector.addGoal(2, NATInRangeGoal);
this.goalSelector.addGoal(2, meleeAttackWithSpeedGoal);
this.goalSelector.addGoal(2,rangedVillagerBowAttackGoal);
this.goalSelector.addGoal(3, moveToBlockPosGoal);
}
}
public void updateGoalData(){
if (getAnimalMode() == 1){
System.out.println("Telling the goals where guarding position is" + getGuardingPosition());
this.moveToBlockPosGoal.setDestinationPos(getGuardingPosition());
this.NATInRangeGoal.setGuardingPos(getGuardingPosition());
} else {
//UPDATE ANY DATA NEEDED FOR FOLLOW MODE
}
}
/**
* Damages armor in each slot by the specified amount.
*/
public void damageArmor(float damage) {
System.out.println("Trying to damage armour");
if (!(damage <= 0.0F)) {
damage = damage / 4.0F;
if (damage < 1.0F) {
damage = 1.0F;
}
for(int i = 0; i < this.armorInventory.size(); ++i) {
ItemStack itemstack = this.armorInventory.get(i);
if (itemstack.getItem() instanceof ArmorItem) {
int j = i;
itemstack.damageItem((int)damage, this, (p_214023_1_) -> {
p_214023_1_.sendBreakAnimation(EquipmentSlotType.fromSlotTypeAndIndex(EquipmentSlotType.Group.ARMOR, j));
});
}
}
}
}
public int getAnimalMode(){return this.getDataManager().get(ANIMAL_MODE);}
public void setAnimalMode(int mode){ this.getDataManager().set(ANIMAL_MODE, mode); }
public void setGuardingPosition(BlockPos pos){this.getDataManager().set(GUARDING_POSITION, pos); }
public BlockPos getGuardingPosition(){return this.getDataManager().get(GUARDING_POSITION);}
public boolean isInventoryFull(){
boolean inventoryFull = true;
//CHECK IF OUR INVENTORY IS FULL
for(int i = 0; i < this.mainInventory.getSizeInventory(); i++) {
if (mainInventory.getStackInSlot(i).isEmpty()){
inventoryFull = false;
}
}
return inventoryFull;
}
public void readAdditional(CompoundNBT compound) {
System.out.println("Im READING with " + this.goalSelector.getRunningGoals() + " goals right now");
super.readAdditional(compound);
System.out.println("Reading Compounds");
//GUARDING POSITION
if (compound.contains("GUARDING_POSITION")){
int[] gpArrray = compound.getIntArray("GUARDING_POSITION");
BlockPos constructedGuardingPos = new BlockPos(gpArrray[0],gpArrray[1],gpArrray[2]);
System.out.println("Found guarding position in here" + constructedGuardingPos);
setGuardingPosition(constructedGuardingPos);
}
//ANIMAL MODE
int mode = compound.getInt("AnimalMode");
setAnimalMode(mode);
System.out.println("We were in mode " + mode);
//INVENTORY
if (compound.contains("Inventory", 10) ){
System.out.println(compound.getList("Inventory", 10).size());
}
ListNBT listnbt = compound.getList("Inventory", 10);
for(int i = 0; i < listnbt.size(); ++i) {
ItemStack itemstack = ItemStack.read(listnbt.getCompound(i));
if (!itemstack.isEmpty()) {
System.out.println("Adding" + itemstack);
this.mainInventory.addItem(itemstack);
}
}
updateGoalData();
addProperGoalSet();
}
public void writeAdditional(CompoundNBT compound){
System.out.println("Im writing with " + this.goalSelector.getRunningGoals().count() + " goals right now");
super.writeAdditional(compound);
System.out.println("Writing Compounds");
//SAVE THE MODE
compound.putInt("AnimalMode", this.getAnimalMode());
//SAVE THE GUARDING POSITION
if (getGuardingPosition() != BlockPos.ZERO){
BlockPos GP = getGuardingPosition();
int[] guardingPosAsArray = {GP.getX(),GP.getY(),GP.getZ()};
compound.putIntArray("GUARDING_POSITION",guardingPosAsArray);
}
//SAVE INVENTORY
ListNBT listnbt = new ListNBT();
for(int i = 0; i < this.mainInventory.getSizeInventory(); ++i) {
ItemStack itemstack = this.mainInventory.getStackInSlot(i);
if (!itemstack.isEmpty()) {
listnbt.add(itemstack.write(new CompoundNBT()));
}
}
compound.put("Inventory", listnbt);
}
}