Skip to content

Commit

Permalink
Add canStand**(block)
Browse files Browse the repository at this point in the history
  • Loading branch information
fullwall committed Jun 19, 2022
1 parent 1a00288 commit 9122048
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 38 deletions.
18 changes: 5 additions & 13 deletions src/main/java/net/citizensnpcs/api/ai/TeleportStuckAction.java
Expand Up @@ -13,34 +13,26 @@ private TeleportStuckAction() {
// singleton
}

private boolean canStand(Block block) {
return MinecraftBlockExaminer.canStandIn(block.getType())
&& MinecraftBlockExaminer.canStandIn(block.getRelative(BlockFace.UP).getType());
}

@Override
public boolean run(NPC npc, Navigator navigator) {
if (!npc.isSpawned())
return false;
Location base = navigator.getTargetAsLocation();
if (base == null || npc.getEntity().getWorld() == base.getWorld()
&& npc.getEntity().getLocation(CACHE_LOC).distanceSquared(base) <= RANGE)
if (base == null || base.getWorld() != npc.getEntity().getWorld())
return true;
Block block = base.getBlock();
Block block = base.getBlock().getRelative(BlockFace.DOWN);
int iterations = 0;
while (!canStand(block)) {
while (!MinecraftBlockExaminer.canStandOn(block)) {
if (iterations++ >= MAX_ITERATIONS) {
block = base.getBlock();
block = base.getBlock().getRelative(BlockFace.DOWN);
break;
}
block = block.getRelative(BlockFace.UP);
}
npc.teleport(block.getLocation(), TeleportCause.PLUGIN);
npc.teleport(block.getRelative(BlockFace.UP).getLocation(), TeleportCause.PLUGIN);
return false;
}

private static final Location CACHE_LOC = new Location(null, 0, 0, 0);
public static TeleportStuckAction INSTANCE = new TeleportStuckAction();
private static final int MAX_ITERATIONS = 10;
private static final double RANGE = 10;
}
Expand Up @@ -2,11 +2,20 @@

import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.util.Vector;

import net.citizensnpcs.api.util.BoundingBox;

public abstract class BlockSource {
public Block getBlock(int x, int y, int z) {
return getWorld().getBlockAt(x, y, z);
}

public Block getBlock(Vector position) {
return getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
}

public abstract BoundingBox getCollisionBox(int x, int y, int z);

public BoundingBox getCollisionBox(Vector pos) {
Expand Down
Expand Up @@ -3,6 +3,7 @@
import java.util.List;

import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.util.Vector;

import com.google.common.collect.Lists;
Expand Down Expand Up @@ -43,9 +44,9 @@ public List<PathPoint> getNeighbours(BlockSource source, PathPoint point) {
@Override
public PassableState isPassable(BlockSource source, PathPoint point) {
Vector pos = point.getVector();
Material above = source.getMaterialAt(pos.clone().add(UP));
Material in = source.getMaterialAt(pos);
if (MinecraftBlockExaminer.isLiquid(above, in)) {
Block above = source.getBlock(pos.clone().add(UP));
Block in = source.getBlock(pos);
if (MinecraftBlockExaminer.isLiquid(above.getType(), in.getType())) {
return PassableState.UNPASSABLE;
}
return PassableState.fromBoolean(MinecraftBlockExaminer.canStandIn(above, in));
Expand Down
Expand Up @@ -11,6 +11,7 @@
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Waterlogged;
import org.bukkit.block.data.type.Slab;
import org.bukkit.util.Vector;

import com.google.common.base.Function;
Expand Down Expand Up @@ -52,14 +53,14 @@ public PassableState isPassable(BlockSource source, PathPoint point) {
if (!SpigotUtil.checkYSafe(pos.getBlockY(), source.getWorld())) {
return PassableState.UNPASSABLE;
}
Material above = source.getMaterialAt(pos.getBlockX(), pos.getBlockY() + 1, pos.getBlockZ());
Block above = source.getBlock(pos.getBlockX(), pos.getBlockY() + 1, pos.getBlockZ());
Material below = source.getMaterialAt(pos.getBlockX(), pos.getBlockY() - 1, pos.getBlockZ());
Material in = source.getMaterialAt(pos);
boolean canStand = canStandOn(below) || isLiquid(in, below) || isClimbable(below);
Block in = source.getBlock(pos);
boolean canStand = canStandOn(below) || isLiquid(in.getType(), below) || isClimbable(below);
if (!canStand) {
return PassableState.UNPASSABLE;
}
if (isClimbable(in) && (isClimbable(above) || isClimbable(below))) {
if (isClimbable(in.getType()) && (isClimbable(above.getType()) || isClimbable(below))) {
point.addCallback(new LadderClimber());
} else if (!canStandIn(above) || !canStandIn(in)) {
return PassableState.UNPASSABLE;
Expand Down Expand Up @@ -133,6 +134,20 @@ private static boolean canJumpOn(Material mat) {
return !NOT_JUMPABLE.contains(mat);
}

public static boolean canStandIn(Block... blocks) {
boolean passable = true;
for (Block block : blocks) {
passable &= !block.getType().isSolid();
if (block.getType().name().contains("_SLAB")) {
Slab slab = (Slab) block.getBlockData();
if (slab.getType() != Slab.Type.BOTTOM) {
passable = false;
}
}
}
return passable;
}

public static boolean canStandIn(Material... mat) {
boolean passable = true;
for (Material m : mat) {
Expand All @@ -143,8 +158,8 @@ public static boolean canStandIn(Material... mat) {

public static boolean canStandOn(Block block) {
Block up = block.getRelative(BlockFace.UP);
return canStandOn(block.getType()) && canStandIn(up.getType())
&& canStandIn(up.getRelative(BlockFace.UP).getType());
boolean standable = canStandOn(block.getType());
return standable && canStandIn(up, up.getRelative(BlockFace.UP));
}

public static boolean canStandOn(Material mat) {
Expand All @@ -170,7 +185,7 @@ public static Location findRandomValidLocation(Location base, int xrange, int yr
continue;
}
Block block = base.getWorld().getBlockAt(x, y, z);
if (MinecraftBlockExaminer.canStandOn(block)) {
if (canStandOn(block)) {
if (filter != null && !filter.apply(block)) {
continue;
}
Expand All @@ -190,9 +205,9 @@ public static Location findValidLocation(Location location, int radius) {
if (!base.getWorld().isChunkLoaded(base.getX() + x >> 4, base.getZ() + z >> 4)) {
continue;
}
Block relative = base.getRelative(x, y, z);
if (canStandOn(relative.getRelative(BlockFace.DOWN))) {
return relative.getLocation();
Block offset = base.getRelative(x, y, z);
if (canStandOn(offset.getRelative(BlockFace.DOWN))) {
return offset.getLocation();
}
}
}
Expand Down Expand Up @@ -264,11 +279,6 @@ public static boolean isLiquidOrInLiquid(Block block) {
}
}

public static boolean validPosition(Block in) {
return canStandIn(in.getType()) && canStandIn(in.getRelative(BlockFace.UP).getType())
&& canStandOn(in.getRelative(BlockFace.DOWN).getType());
}

private static final Set<Material> CLIMBABLE = EnumSet.of(Material.LADDER, Material.VINE);
private static final Set<Material> LIQUIDS = EnumSet.of(Material.WATER, Material.LAVA);
private static final Set<Material> NOT_JUMPABLE = EnumSet.of(Material.SPRUCE_FENCE, Material.BIRCH_FENCE,
Expand Down
@@ -1,6 +1,7 @@
package net.citizensnpcs.api.astar.pathfinder;

import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Squid;
import org.bukkit.entity.WaterMob;
Expand Down Expand Up @@ -44,8 +45,8 @@ public PassableState isPassable(BlockSource source, PathPoint point) {
if (isWaterMob(npc.getEntity())) {
return PassableState.PASSABLE;
}
Material above = source.getMaterialAt(vector.clone().add(UP));
return isSwimmableLiquid(above) || MinecraftBlockExaminer.canStandIn(above) ? PassableState.PASSABLE
Block block = source.getBlock(vector.clone().add(UP));
return isSwimmableLiquid(block.getType()) || MinecraftBlockExaminer.canStandIn(block) ? PassableState.PASSABLE
: PassableState.UNPASSABLE;
}

Expand Down
6 changes: 1 addition & 5 deletions src/main/java/net/citizensnpcs/api/hpastar/HPAGraph.java
Expand Up @@ -8,7 +8,6 @@
import java.util.Queue;

import org.bukkit.Location;
import org.bukkit.Material;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;
Expand Down Expand Up @@ -213,10 +212,7 @@ public boolean walkable(int x, int y, int z) {
if (y == 0) {
return false;
}
Material in = blockSource.getMaterialAt(x, y, z), on = blockSource.getMaterialAt(x, y - 1, z),
above = blockSource.getMaterialAt(x, y + 1, z);
return MinecraftBlockExaminer.canStandOn(on) && MinecraftBlockExaminer.canStandIn(in)
&& MinecraftBlockExaminer.canStandIn(above);
return MinecraftBlockExaminer.canStandOn(blockSource.getWorld().getBlockAt(x, y - 1, z));
}

private static int BASE_CLUSTER_SIZE = (int) (2 * Math.pow(2, 3));
Expand Down

0 comments on commit 9122048

Please sign in to comment.