From b670812d00cb98c6882daac7389fff135653cb5e Mon Sep 17 00:00:00 2001 From: YouHaveTrouble Date: Mon, 3 May 2021 01:29:26 +0200 Subject: [PATCH] Initial commit --- .gitignore | 113 +++++++++++++++++ README.md | 20 +++ pom.xml | 80 ++++++++++++ .../youhavetrouble/pathfinderpath/Path.java | 117 ++++++++++++++++++ .../pathfinderpath/PathCalculationResult.java | 7 ++ 5 files changed, 337 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 pom.xml create mode 100644 src/main/java/me/youhavetrouble/pathfinderpath/Path.java create mode 100644 src/main/java/me/youhavetrouble/pathfinderpath/PathCalculationResult.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4788b4b --- /dev/null +++ b/.gitignore @@ -0,0 +1,113 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +target/ + +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next + +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.flattened-pom.xml + +# Common working directory +run/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..7d1e17e --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# PathfinderPath + +PathfinderPath is an API that allows you to use minecraft pathfinder to get a list of locations from the starting point +up until the goal. + +## Usage + +This will initialize the path from location1 to location2 with pathfinder limit of 120 steps. +```java +Path path = new Path(location1, location2, 120); +``` + +This snippet demonstrates how to calculate path between the locations. Only result of SUCCESS will update the path list. +```java +PathCalculationResult result = path.recalculatePath(); + +if (result.equals(PathCalculationResult.SUCCESS)) { + List locations = path.getPath(); +} +``` \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..9d0eae2 --- /dev/null +++ b/pom.xml @@ -0,0 +1,80 @@ + + + 4.0.0 + + me.youhavetrouble + ParticlePathfinder + 1.0-SNAPSHOT + jar + + ParticlePathfinder + + + 1.8 + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + false + + + + + + + + src/main/resources + true + + + + + + + papermc-repo + https://papermc.io/repo/repository/maven-public/ + + + sonatype + https://oss.sonatype.org/content/groups/public/ + + + + + + com.destroystokyo.paper + paper-api + 1.16.5-R0.1-SNAPSHOT + provided + + + org.spigotmc + spigot + 1.16.5-R0.1-SNAPSHOT + provided + + + diff --git a/src/main/java/me/youhavetrouble/pathfinderpath/Path.java b/src/main/java/me/youhavetrouble/pathfinderpath/Path.java new file mode 100644 index 0000000..8aa6359 --- /dev/null +++ b/src/main/java/me/youhavetrouble/pathfinderpath/Path.java @@ -0,0 +1,117 @@ +package me.youhavetrouble.pathfinderpath; + +import com.destroystokyo.paper.entity.Pathfinder; +import net.minecraft.server.v1_16_R3.*; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeInstance; +import org.bukkit.craftbukkit.v1_16_R3.CraftWorld; +import org.bukkit.entity.Mob; + +import java.util.ArrayList; +import java.util.List; + +public class Path { + + List path = new ArrayList<>(); + Location startLocation, endLocation; + int pointLimit; + + /** + * @param startLocation Location to start pathfinding from + * @param endLocation Location that pathfinder is trying to reach + * @param stepLimit Limit on how many maximum steps pathfinder will take + */ + public Path(Location startLocation, Location endLocation, int stepLimit) { + this.startLocation = startLocation; + this.endLocation = endLocation; + this.pointLimit = stepLimit; + } + + /** + * Updates path Location list for getPath(). Calling this from any other thread than primary will result in ASYNC_ERROR result. + * + * @return Result of calculating path + */ + public PathCalculationResult recalculatePath() { + + if (!Bukkit.isPrimaryThread()) { + return PathCalculationResult.ASYNC_ERROR; + } + + // Clear all current points + path.clear(); + + if (startLocation.getWorld() != endLocation.getWorld()) + return PathCalculationResult.DIFFERENT_WORLD; + + Mob mob = spawnMob(startLocation, pointLimit); + + if (mob == null) + return PathCalculationResult.FAILED_TO_SPAWN_MOB; + + Pathfinder.PathResult pathResult = mob.getPathfinder().findPath(endLocation); + + if (pathResult == null) + return PathCalculationResult.PATH_NULL; + + for (Location point : pathResult.getPoints()) { + // add the offset, so location points to the center of a block + point.add(0.5, 0.25, 0.5); + path.add(point); + } + mob.remove(); + return PathCalculationResult.SUCCESS; + } + + public void setStartLocation(Location startLocation) { + this.startLocation = startLocation; + } + + public Location getStartLocation() { + return startLocation; + } + + public void setEndLocation(Location endLocation) { + this.endLocation = endLocation; + } + + public Location getEndLocation() { + return endLocation; + } + + public double getDistance() { + return startLocation.distance(endLocation); + } + + public double getDistanceSquared() { + return startLocation.distanceSquared(endLocation); + } + + public List getPath() { + return path; + } + + private Mob spawnMob(Location loc, int range) { + // Create an NMS entity without adding it to the world to prevent clients from rendering it + WorldServer nmsWorld = ((CraftWorld) loc.getWorld()).getHandle(); + EntityInsentient nmsEntity = EntityTypes.EVOKER.createCreature(nmsWorld, null, null, null, BlockPosition.ZERO, EnumMobSpawn.TRIGGERED, false, false); + + // If failed to spawn mob, return null + if (nmsEntity == null) + return null; + + nmsEntity.setPositionRotation(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch()); + + // Convert nms entity to bukkit entity + Mob mob = (Mob) nmsEntity.getBukkitEntity(); + + // This is for setting pathfinder range + AttributeInstance followRange = mob.getAttribute(Attribute.GENERIC_FOLLOW_RANGE); + if (followRange != null) { + followRange.setBaseValue(range); + } + return mob; + } +} diff --git a/src/main/java/me/youhavetrouble/pathfinderpath/PathCalculationResult.java b/src/main/java/me/youhavetrouble/pathfinderpath/PathCalculationResult.java new file mode 100644 index 0000000..3a26086 --- /dev/null +++ b/src/main/java/me/youhavetrouble/pathfinderpath/PathCalculationResult.java @@ -0,0 +1,7 @@ +package me.youhavetrouble.pathfinderpath; + +public enum PathCalculationResult { + + SUCCESS, DIFFERENT_WORLD, FAILED_TO_SPAWN_MOB, PATH_NULL, ASYNC_ERROR + +}