Jump to content

[1.18.2] How to make horse run along the four points


Kitoglavch
 Share

Recommended Posts

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?

28RFwHJ.png

ZHIhDVq.png

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 by Kitoglavch
Link to comment
Share on other sites

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 by Luis_ST
Link to comment
Share on other sites

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 by Luis_ST
Link to comment
Share on other sites

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 

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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 by Kitoglavch
Link to comment
Share on other sites

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 by Kitoglavch
video
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • ---- Minecraft Crash Report ---- // Uh... Did I do that? Time: 2023-02-07 01:42:22 Description: Unexpected error java.lang.NoClassDefFoundError: me/jellysquid/mods/sodium/client/model/vertex/type/VertexType     at net.minecraft.class_702.handler$zml001$render(class_702.java:3138)     at net.minecraft.class_702.method_3049(class_702.java)     at net.minecraft.class_761.method_22710(class_761.java:1502)     at net.minecraft.class_757.method_3188(class_757.java:1085)     at net.minecraft.class_757.method_3192(class_757.java:864)     at net.minecraft.class_310.method_1523(class_310.java:1193)     at net.minecraft.class_310.method_1514(class_310.java:781)     at net.minecraft.client.main.Main.method_44604(Main.java:244)     at net.minecraft.client.main.Main.main(Main.java:51)     at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:461)     at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74)     at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23) Caused by: java.lang.ClassNotFoundException: me.jellysquid.mods.sodium.client.model.vertex.type.VertexType     at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)     at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)     at net.fabricmc.loader.impl.launch.knot.KnotClassDelegate.loadClass(KnotClassDelegate.java:226)     at net.fabricmc.loader.impl.launch.knot.KnotClassLoader.loadClass(KnotClassLoader.java:112)     at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)     ... 12 more A detailed walkthrough of the error, its code path and all known details is as follows: --------------------------------------------------------------------------------------- -- Head -- Thread: Render thread Stacktrace:     at net.minecraft.class_702.handler$zml001$render(class_702.java:3138)     at net.minecraft.class_702.method_3049(class_702.java)     at net.minecraft.class_761.method_22710(class_761.java:1502)     at net.minecraft.class_757.method_3188(class_757.java:1085) -- Affected level -- Details:     All players: 1 total; [class_746['RappyTheToy'/199, l='ClientLevel', x=-8.50, y=68.00, z=9.50]]     Chunk stats: 1024, 475     Level dimension: minecraft:overworld     Level spawn location: World: (0,72,0), Section: (at 0,8,0 in 0,4,0; chunk contains blocks 0,-64,0 to 15,319,15), Region: (0,0; contains chunks 0,0 to 31,31, blocks 0,-64,0 to 511,319,511)     Level time: 62 game time, 62 day time     Server brand: fabric     Server type: Integrated singleplayer server Stacktrace:     at net.minecraft.class_638.method_8538(class_638.java:455)     at net.minecraft.class_310.method_1587(class_310.java:2390)     at net.minecraft.class_310.method_1514(class_310.java:805)     at net.minecraft.client.main.Main.method_44604(Main.java:244)     at net.minecraft.client.main.Main.main(Main.java:51)     at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:461)     at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74)     at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23) -- Last reload -- Details:     Reload number: 1     Reload reason: initial     Finished: Yes     Packs: vanilla, Fabric Mods, minecraft/physicsmod -- System Details -- Details:     Minecraft Version: 1.19.3     Minecraft Version ID: 1.19.3     Operating System: Windows 10 (amd64) version 10.0     Java Version: 17.0.3, Microsoft     Java VM Version: OpenJDK 64-Bit Server VM (mixed mode), Microsoft     Memory: 825264992 bytes (787 MiB) / 2147483648 bytes (2048 MiB) up to 2147483648 bytes (2048 MiB)     CPUs: 24     Processor Vendor: AuthenticAMD     Processor Name: AMD Ryzen 9 5900X 12-Core Processor                 Identifier: AuthenticAMD Family 25 Model 33 Stepping 2     Microarchitecture: Zen 3     Frequency (GHz): 4.20     Number of physical packages: 1     Number of physical CPUs: 12     Number of logical CPUs: 24     Graphics card #0 name: NVIDIA GeForce RTX 3080     Graphics card #0 vendor: NVIDIA (0x10de)     Graphics card #0 VRAM (MB): 4095.00     Graphics card #0 deviceId: 0x2216     Graphics card #0 versionInfo: DriverVersion=31.0.15.2824     Memory slot #0 capacity (MB): 8192.00     Memory slot #0 clockSpeed (GHz): 2.13     Memory slot #0 type: DDR4     Memory slot #1 capacity (MB): 8192.00     Memory slot #1 clockSpeed (GHz): 2.13     Memory slot #1 type: DDR4     Memory slot #2 capacity (MB): 8192.00     Memory slot #2 clockSpeed (GHz): 2.13     Memory slot #2 type: DDR4     Memory slot #3 capacity (MB): 8192.00     Memory slot #3 clockSpeed (GHz): 2.13     Memory slot #3 type: DDR4     Virtual memory max (MB): 37790.38     Virtual memory used (MB): 15848.40     Swap memory total (MB): 5120.00     Swap memory used (MB): 12.06     JVM Flags: 9 total; -XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump -Xss1M -Xmx2G -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:G1NewSizePercent=20 -XX:G1ReservePercent=20 -XX:MaxGCPauseMillis=50 -XX:G1HeapRegionSize=32M     Fabric Mods:          fabric-api: Fabric API 0.72.0+1.19.3             fabric-api-base: Fabric API Base 0.4.20+afca2f3e85             fabric-api-lookup-api-v1: Fabric API Lookup API (v1) 1.6.19+49abcf7e85             fabric-biome-api-v1: Fabric Biome API (v1) 12.1.0+b5d379b085             fabric-block-api-v1: Fabric Block API (v1) 1.0.4+e022e5d185             fabric-blockrenderlayer-v1: Fabric BlockRenderLayer Registration (v1) 1.1.29+c6af733c85             fabric-client-tags-api-v1: Fabric Client Tags 1.0.11+1134c5b885             fabric-command-api-v1: Fabric Command API (v1) 1.2.21+f71b366f85             fabric-command-api-v2: Fabric Command API (v2) 2.2.0+3fc4752e85             fabric-commands-v0: Fabric Commands (v0) 0.2.38+df3654b385             fabric-containers-v0: Fabric Containers (v0) 0.1.46+df3654b385             fabric-content-registries-v0: Fabric Content Registries (v0) 3.5.0+1d37d50285             fabric-convention-tags-v1: Fabric Convention Tags 1.2.1+8e4e694f85             fabric-crash-report-info-v1: Fabric Crash Report Info (v1) 0.2.13+aeb40ebe85             fabric-data-generation-api-v1: Fabric Data Generation API (v1) 11.1.4+1134c5b885             fabric-dimensions-v1: Fabric Dimensions API (v1) 2.1.40+48349a3f85             fabric-entity-events-v1: Fabric Entity Events (v1) 1.5.6+b83334a085             fabric-events-interaction-v0: Fabric Events Interaction (v0) 0.4.39+3baeb27a85             fabric-events-lifecycle-v0: Fabric Events Lifecycle (v0) 0.2.42+df3654b385             fabric-game-rule-api-v1: Fabric Game Rule API (v1) 1.0.29+99f9db8085             fabric-item-api-v1: Fabric Item API (v1) 2.1.8+1134c5b885             fabric-item-group-api-v1: Fabric Item Group API (v1) 2.1.11+1134c5b885             fabric-key-binding-api-v1: Fabric Key Binding API (v1) 1.0.30+bc01e09785             fabric-keybindings-v0: Fabric Key Bindings (v0) 0.2.28+df3654b385             fabric-lifecycle-events-v1: Fabric Lifecycle Events (v1) 2.2.9+23a79c8a85             fabric-loot-api-v2: Fabric Loot API (v2) 1.1.19+75e9821185             fabric-loot-tables-v1: Fabric Loot Tables (v1) 1.1.23+9e7660c685             fabric-message-api-v1: Fabric Message API (v1) 5.0.13+6ede1da985             fabric-mining-level-api-v1: Fabric Mining Level API (v1) 2.1.30+49abcf7e85             fabric-models-v0: Fabric Models (v0) 0.3.26+11ba9c3b85             fabric-networking-api-v1: Fabric Networking API (v1) 1.2.16+4017a8cb85             fabric-networking-v0: Fabric Networking (v0) 0.3.33+df3654b385             fabric-object-builder-api-v1: Fabric Object Builder API (v1) 5.3.0+85f102ee85             fabric-particles-v1: Fabric Particles (v1) 1.0.19+f1e4495b85             fabric-recipe-api-v1: Fabric Recipe API (v1) 1.0.0+5176f73d85             fabric-registry-sync-v0: Fabric Registry Sync (v0) 2.0.4+1134c5b885             fabric-renderer-api-v1: Fabric Renderer API (v1) 2.2.0+9f179aa185             fabric-renderer-indigo: Fabric Renderer - Indigo 0.7.0+9f179aa185             fabric-renderer-registries-v1: Fabric Renderer Registries (v1) 3.2.29+df3654b385             fabric-rendering-data-attachment-v1: Fabric Rendering Data Attachment (v1) 0.3.24+afca2f3e85             fabric-rendering-fluids-v1: Fabric Rendering Fluids (v1) 3.0.17+f1e4495b85             fabric-rendering-v0: Fabric Rendering (v0) 1.1.32+df3654b385             fabric-rendering-v1: Fabric Rendering (v1) 1.12.0+6dc0edd785             fabric-resource-conditions-api-v1: Fabric Resource Conditions API (v1) 2.2.2+1134c5b885             fabric-resource-loader-v0: Fabric Resource Loader (v0) 0.10.4+a91e48b785             fabric-screen-api-v1: Fabric Screen API (v1) 1.0.40+f1e4495b85             fabric-screen-handler-api-v1: Fabric Screen Handler API (v1) 1.3.12+99f9db8085             fabric-sound-api-v1: Fabric Sound API (v1) 1.0.7+75e9821185             fabric-transfer-api-v1: Fabric Transfer API (v1) 2.1.14+ccd377ba85             fabric-transitive-access-wideners-v1: Fabric Transitive Access Wideners (v1) 2.3.0+5b9a588b85         fabricloader: Fabric Loader 0.14.14         java: OpenJDK 64-Bit Server VM 17         minecraft: Minecraft 1.19.3         physicsmod: Physics Mod 2.10.1         sodium: Sodium 0.4.9+build.23     Launched Version: fabric-loader-0.14.14-1.19.3     Backend library: LWJGL version 3.3.1 SNAPSHOT     Backend API: NVIDIA GeForce RTX 3080/PCIe/SSE2 GL version 3.2.0 NVIDIA 528.24, NVIDIA Corporation     Window size: 1920x1080     GL Caps: Using framebuffer using OpenGL 3.2     GL debug messages:      Using VBOs: Yes     Is Modded: Definitely; Client brand changed to 'fabric'; Server brand changed to 'fabric'     Type: Integrated Server (map_client.txt)     Graphics mode: fancy     Resource Packs: fabric     Current Language: English (US)     CPU: 24x AMD Ryzen 9 5900X 12-Core Processor      Server Running: true     Player Count: 1 / 8; [class_3222['RappyTheToy'/199, l='ServerLevel[re]', x=-8.50, y=68.00, z=9.50]]     Data Packs: vanilla, fabric     Enabled Feature Flags: minecraft:vanilla     World Generation: Stable
    • The error message "attempting to assign weaker access privileges; was public" usually occurs in Java when you try to change the access level of a member (such as a field or method) to a less restrictive level than it was defined with originally. For example, if a method is defined as public, you cannot change its access level to private or protected. In Java, the access level for a member can only be made more restrictive, not less restrictive, to ensure that subclasses cannot weaken the accessibility of members inherited from their superclasses.
    • Ive been browsing the web for solutions as when I try to run gradlew genIntellijRuns, it states it cannot find a specific file in a folder called in Bundled_repo I checked the supposed location of this file but could not find the folders it should be contained in, which are bundeled_repo/net. I deleted the chache and ran it again but it did not fix the issue.
    • I have no idea why but my forge server console is spammed by BlockPos {x=0, y=0, z=0} nearly every second on the server console. Anyone have any idea how to stop this?
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.