mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-06 16:37:38 +01:00
Simplify pathfinding block
This commit is contained in:
parent
4fb6e37622
commit
78898bfa9b
@ -67,7 +67,6 @@ public final class MinecraftServer {
|
||||
public final static Logger LOGGER = LoggerFactory.getLogger(MinecraftServer.class);
|
||||
|
||||
public static final String VERSION_NAME = "1.17";
|
||||
public static final String VERSION_NAME_UNDERSCORED = VERSION_NAME.replace('.', '_');
|
||||
public static final int PROTOCOL_VERSION = 755;
|
||||
|
||||
// Threads
|
||||
@ -332,7 +331,8 @@ public final class MinecraftServer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the manager handling {@link BlockPlacementRule}.
|
||||
* Gets the manager handling {@link net.minestom.server.instance.block.BlockHandler block handlers}
|
||||
* and {@link BlockPlacementRule placement rules}.
|
||||
*
|
||||
* @return the block manager
|
||||
*/
|
||||
@ -615,6 +615,7 @@ public final class MinecraftServer {
|
||||
|
||||
/**
|
||||
* Gets if the built in Minestom terminal is enabled.
|
||||
*
|
||||
* @return true if the terminal is enabled
|
||||
*/
|
||||
public static boolean isTerminalEnabled() {
|
||||
|
@ -1,39 +1,42 @@
|
||||
package net.minestom.server.entity.pathfinding;
|
||||
|
||||
import com.extollit.gaming.ai.path.model.IBlockDescription;
|
||||
import com.extollit.gaming.ai.path.model.IBlockObject;
|
||||
import com.extollit.linalg.immutable.AxisAlignedBBox;
|
||||
import it.unimi.dsi.fastutil.shorts.Short2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PFBlockObject implements IBlockObject {
|
||||
public class PFBlock implements IBlockDescription, IBlockObject {
|
||||
|
||||
private static final Short2ObjectMap<PFBlockObject> BLOCK_OBJECT_MAP = new Short2ObjectOpenHashMap<>();
|
||||
private static final Short2ObjectMap<PFBlock> BLOCK_DESCRIPTION_MAP = new Short2ObjectOpenHashMap<>();
|
||||
|
||||
/**
|
||||
* Gets the {@link PFBlockObject} linked to the block state id.
|
||||
* Gets the {@link PFBlock} linked to the block state id.
|
||||
* <p>
|
||||
* Cache the result if it is not already.
|
||||
*
|
||||
* @param block the block
|
||||
* @return the {@link PFBlockObject} linked to {@code blockStateId}
|
||||
* @return the {@link PFBlock} linked to {@code blockStateId}
|
||||
*/
|
||||
public static PFBlockObject getBlockObject(Block block) {
|
||||
public static @NotNull PFBlock get(@NotNull Block block) {
|
||||
final short blockStateId = block.stateId();
|
||||
if (!BLOCK_OBJECT_MAP.containsKey(blockStateId)) {
|
||||
synchronized (BLOCK_OBJECT_MAP) {
|
||||
final PFBlockObject blockObject = new PFBlockObject(block);
|
||||
BLOCK_OBJECT_MAP.put(blockStateId, blockObject);
|
||||
return blockObject;
|
||||
if (!BLOCK_DESCRIPTION_MAP.containsKey(blockStateId)) {
|
||||
synchronized (BLOCK_DESCRIPTION_MAP) {
|
||||
if (!BLOCK_DESCRIPTION_MAP.containsKey(blockStateId)) {
|
||||
final var pfBlock = new PFBlock(block);
|
||||
BLOCK_DESCRIPTION_MAP.put(blockStateId, pfBlock);
|
||||
return pfBlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return BLOCK_OBJECT_MAP.get(blockStateId);
|
||||
return BLOCK_DESCRIPTION_MAP.get(blockStateId);
|
||||
}
|
||||
|
||||
private final Block block;
|
||||
|
||||
public PFBlockObject(Block block) {
|
||||
public PFBlock(Block block) {
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
@ -144,4 +147,5 @@ public class PFBlockObject implements IBlockObject {
|
||||
public boolean isIncinerating() {
|
||||
return block == Block.LAVA || block == Block.FIRE || block == Block.SOUL_FIRE;
|
||||
}
|
||||
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
package net.minestom.server.entity.pathfinding;
|
||||
|
||||
import com.extollit.gaming.ai.path.model.IBlockDescription;
|
||||
import it.unimi.dsi.fastutil.shorts.Short2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
|
||||
public class PFBlockDescription implements IBlockDescription {
|
||||
|
||||
private static final Short2ObjectMap<PFBlockDescription> BLOCK_DESCRIPTION_MAP = new Short2ObjectOpenHashMap<>();
|
||||
|
||||
/**
|
||||
* Gets the {@link PFBlockDescription} linked to the block state id.
|
||||
* <p>
|
||||
* Cache the result if it is not already.
|
||||
*
|
||||
* @param block the block
|
||||
* @return the {@link PFBlockDescription} linked to {@code blockStateId}
|
||||
*/
|
||||
public static PFBlockDescription getBlockDescription(Block block) {
|
||||
final short blockStateId = block.stateId();
|
||||
if (!BLOCK_DESCRIPTION_MAP.containsKey(blockStateId)) {
|
||||
synchronized (BLOCK_DESCRIPTION_MAP) {
|
||||
final PFBlockDescription blockDescription = new PFBlockDescription(block);
|
||||
BLOCK_DESCRIPTION_MAP.put(blockStateId, blockDescription);
|
||||
return blockDescription;
|
||||
}
|
||||
}
|
||||
|
||||
return BLOCK_DESCRIPTION_MAP.get(blockStateId);
|
||||
}
|
||||
|
||||
private final Block block;
|
||||
|
||||
public PFBlockDescription(Block block) {
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFenceLike() {
|
||||
// TODO: Use Hitbox
|
||||
// Return fences, fencegates and walls.
|
||||
// It just so happens that their namespace IDs contain "fence".
|
||||
if (block.namespace().asString().contains("fence")) {
|
||||
return true;
|
||||
}
|
||||
// Return all walls
|
||||
// It just so happens that their namespace IDs all end with "door".
|
||||
return block.namespace().asString().endsWith("wall");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClimbable() {
|
||||
// Return ladders and vines (including weeping and twisting vines)
|
||||
// Note that no other Namespace IDs contain "vine" except vines.
|
||||
return block.compare(Block.LADDER) || block.namespace().asString().contains("vine");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDoor() {
|
||||
// Return all normal doors and trap doors.
|
||||
// It just so happens that their namespace IDs all end with "door".
|
||||
return block.namespace().asString().endsWith("door");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImpeding() {
|
||||
return block.isSolid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullyBounded() {
|
||||
// TODO: Use Hitbox (would probably be faster as well)
|
||||
// Return false for anything that does not have a full hitbox but impedes
|
||||
// e.g. Anvils, Lilypads, Ladders, Walls, Fences, EnchantmentTables
|
||||
// Fences & Walls
|
||||
if (isFenceLike()) {
|
||||
return false;
|
||||
}
|
||||
// Ladders and Vines
|
||||
if (isClimbable()) {
|
||||
return false;
|
||||
}
|
||||
// All doors/trapdoors.
|
||||
if (isDoor()) {
|
||||
return false;
|
||||
}
|
||||
if (block.name().startsWith("potted")) {
|
||||
return false;
|
||||
}
|
||||
// Skulls & Heads
|
||||
if (block.name().contains("skull") || block.name().contains("head")) {
|
||||
// NOTE: blocks.getName().contains("head") also matches Piston_Head
|
||||
// I could not find out by documentation if piston_head is fully bounded, I would presume it is NOT.
|
||||
return false;
|
||||
}
|
||||
// Carpets
|
||||
if (block.name().endsWith("carpet")) {
|
||||
return false;
|
||||
}
|
||||
// Slabs
|
||||
if (block.name().contains("slab")) {
|
||||
return false;
|
||||
}
|
||||
// Beds
|
||||
if (block.name().endsWith("bed")) {
|
||||
return false;
|
||||
}
|
||||
// Glass Panes
|
||||
if (block.name().endsWith("pane")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !Block.CHORUS_FLOWER.compare(block) && !Block.CHORUS_PLANT.compare(block) && !Block.BAMBOO.compare(block)
|
||||
&& !Block.BAMBOO_SAPLING.compare(block) && !Block.SEA_PICKLE.compare(block)
|
||||
&& !Block.TURTLE_EGG.compare(block) && !Block.SNOW.compare(block) && !Block.FLOWER_POT.compare(block)
|
||||
&& !Block.LILY_PAD.compare(block) && !Block.ANVIL.compare(block) && !Block.CHIPPED_ANVIL.compare(block)
|
||||
&& !Block.DAMAGED_ANVIL.compare(block) && !Block.CAKE.compare(block) && !Block.CACTUS.compare(block)
|
||||
&& !Block.BREWING_STAND.compare(block) && !Block.LECTERN.compare(block)
|
||||
&& !Block.DAYLIGHT_DETECTOR.compare(block) && !Block.CAMPFIRE.compare(block)
|
||||
&& !Block.SOUL_CAMPFIRE.compare(block) && !Block.ENCHANTING_TABLE.compare(block)
|
||||
&& !Block.CHEST.compare(block) && !Block.ENDER_CHEST.compare(block) && !Block.GRINDSTONE.compare(block)
|
||||
&& !Block.TRAPPED_CHEST.compare(block) && !Block.SOUL_SAND.compare(block)
|
||||
&& !Block.SOUL_SOIL.compare(block) && !Block.LANTERN.compare(block) && !Block.COCOA.compare(block)
|
||||
&& !Block.CONDUIT.compare(block) && !Block.DIRT_PATH.compare(block) && !Block.FARMLAND.compare(block)
|
||||
&& !Block.END_ROD.compare(block) && !Block.STONECUTTER.compare(block) && !Block.BELL.compare(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLiquid() {
|
||||
return block.isLiquid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncinerating() {
|
||||
return block == Block.LAVA || block == Block.FIRE || block == Block.SOUL_FIRE;
|
||||
}
|
||||
}
|
@ -22,7 +22,7 @@ public class PFColumnarSpace implements IColumnarSpace {
|
||||
@Override
|
||||
public IBlockDescription blockAt(int x, int y, int z) {
|
||||
final Block block = chunk.getBlock(x, y, z);
|
||||
return PFBlockDescription.getBlockDescription(block);
|
||||
return PFBlock.get(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -22,7 +22,7 @@ public class PFInstanceSpace implements IInstanceSpace {
|
||||
@Override
|
||||
public IBlockObject blockObjectAt(int x, int y, int z) {
|
||||
final Block block = instance.getBlock(x, y, z);
|
||||
return PFBlockObject.getBlockObject(block);
|
||||
return PFBlock.get(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -31,7 +31,6 @@ public class PFInstanceSpace implements IInstanceSpace {
|
||||
if (chunk == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return chunkSpaceMap.computeIfAbsent(chunk, c -> {
|
||||
final PFColumnarSpace cs = new PFColumnarSpace(this, c);
|
||||
c.setColumnarSpace(cs);
|
||||
|
@ -2,7 +2,7 @@ package net.minestom.server.instance;
|
||||
|
||||
import com.extollit.gaming.ai.path.model.ColumnarOcclusionFieldList;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import net.minestom.server.entity.pathfinding.PFBlockDescription;
|
||||
import net.minestom.server.entity.pathfinding.PFBlock;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockHandler;
|
||||
import net.minestom.server.network.packet.server.play.ChunkDataPacket;
|
||||
@ -47,7 +47,7 @@ public class DynamicChunk extends Chunk {
|
||||
// Update pathfinder
|
||||
if (columnarSpace != null) {
|
||||
final ColumnarOcclusionFieldList columnarOcclusionFieldList = columnarSpace.occlusionFields();
|
||||
final PFBlockDescription blockDescription = PFBlockDescription.getBlockDescription(block);
|
||||
final var blockDescription = PFBlock.get(block);
|
||||
columnarOcclusionFieldList.onBlockChanged(x, y, z, blockDescription, 0);
|
||||
}
|
||||
Section section = retrieveSection(y);
|
||||
|
Loading…
Reference in New Issue
Block a user