Posted July 26, 20223 yr Hello, I'm doing block similar to grindstone from Horse Power and I have a question. How can I change horse navigation to move like this? Now i'm doing it like this: horse.goalSelector.addGoal(0, new HorseWalkGoal(horse)); // at BlockEntity#tick, don't know if it's correct Goal class: public class HorseWalkGoal extends Goal { public final Horse horse; public Path path; public HorseWalkGoal(Horse horse) { this.horse = horse; //points from picture this.path = horse.getNavigation().createPath(Set.of( horse.getLeashHolder().blockPosition().offset(3, -1, 3), //point 1 horse.getLeashHolder().blockPosition().offset(3, -1, -3), //point 2 horse.getLeashHolder().blockPosition().offset(-3, -1, -3), //point 3 horse.getLeashHolder().blockPosition().offset(-3, -1, 3)), 0); //point 4 this.setFlags(EnumSet.of(Flag.MOVE)); } @Override public boolean canUse() { return horse.isLeashed() && this.isValid(); } public boolean isValid() { Optional<HorseCrankBlockEntity> blockentity = horse.level.getBlockEntity(horse.getLeashHolder().blockPosition(), ModBlockEntities.HORSECRANK.get()); return blockentity.isPresent() && blockentity.get().valid; } @Override public void stop() { horse.getNavigation().stop(); } @Override public void tick() { if (this.horse.getNavigation().isDone()) { this.horse.getNavigation().moveTo(this.path, 1.5); } } @Override public boolean requiresUpdateEveryTick() { return true; } @Override public void start() { this.horse.getNavigation().moveTo(this.path, 1.5); } } I guess I use NavigationPath#createPath wrong. But how i must to? Edited July 26, 20223 yr by Kitoglavch
July 26, 20223 yr 2 hours ago, Kitoglavch said: // at BlockEntity#tick, don't know if it's correct Do not add this goal each tick, once is enough 2 hours ago, Kitoglavch said: Hello, I'm doing block similar to grindstone from Horse Power and I have a question. How can I change horse navigation to move like this? Calculate the positions (1, 2, 3, 4, ...) then call PathNavigation#moveTo for the first position, wait until the horse has reached the position then continue with the same logic for the next position and repeat this step until you at the last position Edited July 26, 20223 yr by Luis_ST
July 26, 20223 yr 18 minutes ago, Kitoglavch said: if (this.horse.getNavigation().isDone()) { this.horse.getNavigation().moveTo(this.path, 1.5); } ignore my first post, i think you forgot the ! there?
July 26, 20223 yr Author 11 minutes ago, Luis_ST said: you forgot the ! there? It should be here? I thought this method returns true if navigation has no active path. I think it hepled. But anyway, there is a problem with Path. Horse still act strange and just move to the nearest point https://i.imgur.com/CKTfkWp.mp4 Edited July 26, 20223 yr by Kitoglavch
July 26, 20223 yr 4 minutes ago, Kitoglavch said: I think it hepled. But anyway, there is a problem with Path. Horse still act strange and just move to the nearest point are you sure the positions of the Path are correct and you could use debugger to check how the goal is handled/called Edit: try to place the Horse at a different spot Edited July 26, 20223 yr by Luis_ST
July 26, 20223 yr Author Just now, Luis_ST said: are you sure the positions of the Path are correct i don't know if Path#createPath works as I suppose, but console logs me [BlockPos{x=58, y=-60, z=-457}, BlockPos{x=58, y=-60, z=-451}, BlockPos{x=64, y=-60, z=-457}, BlockPos{x=64, y=-60, z=-451}] from Set<BlockPos>, and it is what should be. 3 minutes ago, Luis_ST said: and you could use debugger to check how the goal is handled/called i put System.out.println in Goal#start, Goal#stop. It should work properly and add new goal once at the same time
July 26, 20223 yr Author 9 minutes ago, Luis_ST said: Edit: try to place the Horse at a different spot https://i.imgur.com/eYOpVZM.mp4
July 26, 20223 yr 47 minutes ago, Kitoglavch said: horse.goalSelector.addGoal(0, new HorseWalkGoal(horse)); // at BlockEntity#tick, don't know if it's correct Maybe this is your issue, try to add only one Goal
July 26, 20223 yr Author The same result. Btw, even using my way, Goal#start is called only once and i don't think it's a problem
July 26, 20223 yr this.horse.getNavigation().moveTo(this.path, 1.5); Is this code in the tick method called, after the Horse is stuck in a corner?
July 26, 20223 yr Author yes. every tick in Goal#tick, so it means in corner this.horse.getNavigation().isDone() returns false
July 26, 20223 yr Author what you mean? this action is called every tick due to "true" in if statement. i didn't understand what should i write in else statement if (!this.horse.getNavigation().isDone()) { // true this.horse.getNavigation().moveTo(this.path, 1.5); }
July 26, 20223 yr when the PathNavigation#isDone returns false in the corner you can try something like this: if (!this.horse.getNavigation().isDone()) { this.horse.getNavigation().moveTo(this.path, 1.5); } else { this.path = // create a new path } you also could try this, if the Path does not work correctly: 1 hour ago, Luis_ST said: Calculate the positions (1, 2, 3, 4, ...) then call PathNavigation#moveTo for the first position, wait until the horse has reached the position then continue with the same logic for the next position and repeat this step until you at the last position
July 27, 20223 yr Author 13 hours ago, Luis_ST said: you also could try this, if the Path does not work correctly: sadly it didn't work. horse did the same 13 hours ago, Luis_ST said: Calculate the positions (1, 2, 3, 4, ...) then call PathNavigation#moveTo for the first position, wait until the horse has reached the position then continue with the same logic for the next position and repeat this step until you at the last position I try this way now, but horse still acts not as supposed to (but much better than it was) public class HorseWalkGoal extends Goal { public final Horse horse; public int goalStatus; public BlockPos horseCrankPos; public static int[][] offsets = new int[][] {{3, -1, 3}, {3, -1, -3}, {-3, -1, -3}, {-3, -1, 3}}; public HorseWalkGoal(Horse horse, BlockPos pos) { this.horse = horse; this.horseCrankPos = pos; this.setFlags(EnumSet.of(Flag.MOVE)); } @Override public boolean canUse() { return this.horse.isLeashed() && this.isValid(); } public boolean isValid() { Optional<HorseCrankBlockEntity> blockentity = this.horse.level.getBlockEntity(this.horseCrankPos, ModBlockEntities.HORSECRANK.get()); return blockentity.isPresent() && blockentity.get().valid; } @Override public void start() { this.horse.getNavigation().stop(); if (this.horse.getNavigation().isDone()) { BlockPos pos = calculatePos(this.horseCrankPos, goalStatus); this.horse.getNavigation().moveTo(pos.getX(), pos.getY(), pos.getZ(), 1.5); } } @Override public void stop() { this.horse.getNavigation().stop(); } @Override public void tick() { if (this.horse.getNavigation().isDone()) { this.incrementGoalStatus(); BlockPos pos = calculatePos(this.horseCrankPos, goalStatus); this.horse.getNavigation().moveTo(pos.getX(), pos.getY(), pos.getZ(), 1.5); } } private void incrementGoalStatus() { this.goalStatus = (this.goalStatus + 1) % 4; } private BlockPos calculatePos(BlockPos pos, int goalStatus) { return pos.offset(offsets[goalStatus][0], offsets[goalStatus][1], offsets[goalStatus][2]); } @Override public boolean requiresUpdateEveryTick() { return true; } } https://i.imgur.com/GGC5tG7.mp4 Edited July 27, 20223 yr by Kitoglavch
July 27, 20223 yr Author Maybe anyone know some mods that can help me to understand how to work with PathNavigation?
July 27, 20223 yr Author Ok I decided to use the same way like in Horse Power (1.12.2) in BlockEntity tick. It looks like horse slightly understand what it need to do, but this way still doesn't work properly. What can be wrong here? public static double[][] offsetsXZ = {{-1.5, -1.5}, {0, -1.5}, {1, -1.5}, {1, 0}, {1, 1}, {0, 1}, {-1.5, 1}, {-1.5, 0}}; public AABB[] searchAreas = new AABB[8]; public int origin = -1, target = origin; @Override public void load(CompoundTag tag) { // ^ other load this.origin = tag.getInt("origin"); this.target = tag.getInt("target"); } @Override protected void saveAdditional(CompoundTag tag) { // ^ other save tag.putInt("origin", this.origin); tag.putInt("target", this.target); } public static <T extends BlockEntity> void tick(Level p_155253_, BlockPos p_155254_, BlockState p_155255_, T p_155256_) { if (!p_155253_.isClientSide) { HorseCrankBlockEntity blockentity = (HorseCrankBlockEntity) p_155256_; int oldPower = blockentity.power, oldHorseId = blockentity.horseId, oldLeashId = blockentity.leashId; boolean oldValid = blockentity.valid; Horse horse = blockentity.getHorse(); blockentity.verifyIntegrity(); blockentity.calculatePower(); if (horse != null && blockentity.valid) { if (oldValid != blockentity.valid) { blockentity.target = blockentity.findClosestPoint(); } Vector3d pos = blockentity.calculatePos(blockentity.target); double x = pos.x; double y = pos.y; double z = pos.z; if (blockentity.searchAreas[blockentity.target] == null) blockentity.searchAreas[blockentity.target] = new AABB(x - 0.5, y - 0.5, z - 0.5, x + 0.5, y + 0.5, z + 0.5); if (horse.getBoundingBox().intersects(blockentity.searchAreas[blockentity.target])) { int next = blockentity.target + 1; int previous = blockentity.target - 1; if (next >= offsetsXZ.length) next = 0; if (previous < 0) previous = offsetsXZ.length - 1; if (blockentity.origin != blockentity.target && blockentity.target != previous) { blockentity.origin = blockentity.target; } blockentity.target = next; } if (blockentity.target != -1 && !horse.getNavigation().isDone()) { pos = blockentity.calculatePos(blockentity.target); x = pos.x; y = pos.y; z = pos.z; horse.getNavigation().moveTo(x, y, z, 1D); System.out.println(String.format("%f;%f;%f;%d;%s", x, y, z, blockentity.target, horse.getNavigation().getPath())); } } if (oldPower != blockentity.power || oldValid != blockentity.valid || oldHorseId != blockentity.horseId || oldLeashId != blockentity.leashId) { p_155253_.sendBlockUpdated(p_155254_, p_155255_, p_155255_, 2); } p_155256_.setChanged(); } } private int findClosestPoint() { if (horseId != -1) { double distance = Double.MAX_VALUE; int closest = 0; for (int i = 0; i < offsetsXZ.length; i++) { double tmp = distanceToPoint(i); if (tmp < distance) { distance = tmp; closest = i; } } return closest; } return 0; } private double distanceToPoint(int point) { Vector3d pos = calculatePos(point); return this.getHorse().distanceToSqr(pos.x, pos.y, pos.z); } private Vector3d calculatePos(int point) { double x = this.getBlockPos().getX() + offsetsXZ[point][0] * 2; double y = this.getBlockPos().getY() - 1; double z = this.getBlockPos().getZ() + offsetsXZ[point][1] * 2; return new Vector3d(x, y, z); } https://imgur.com/loLgEAu Edited July 27, 20223 yr by Kitoglavch video
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.