From 3f1570125683d7edc2a5e0d8e9b6de458f751e42 Mon Sep 17 00:00:00 2001 From: Felix Cravic Date: Thu, 23 Apr 2020 01:26:45 +0200 Subject: [PATCH] WIP entity/block collision/gravity --- .../themode/demo/commands/SimpleCommand.java | 2 +- .../minestom/collision/CollisionUtils.java | 12 ++++++------ .../fr/themode/minestom/entity/Entity.java | 10 +++++++++- .../minestom/entity/EntityCreature.java | 18 ++++++++++++------ .../minestom/entity/pathfinding/JPS.java | 3 ++- .../minestom/instance/InstanceContainer.java | 7 ++++--- .../themode/minestom/instance/block/Block.java | 2 +- .../minestom/instance/block/BlockManager.java | 2 +- .../rule/vanilla/RedstonePlacementRule.java | 4 ++-- .../themode/minestom/utils/BlockPosition.java | 4 +++- .../fr/themode/minestom/utils/EntityUtils.java | 12 +++++++++--- .../fr/themode/minestom/utils/Position.java | 2 +- 12 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/main/java/fr/themode/demo/commands/SimpleCommand.java b/src/main/java/fr/themode/demo/commands/SimpleCommand.java index 10ca4f236..b100ec425 100644 --- a/src/main/java/fr/themode/demo/commands/SimpleCommand.java +++ b/src/main/java/fr/themode/demo/commands/SimpleCommand.java @@ -19,7 +19,7 @@ public class SimpleCommand implements CommandProcessor { for (EntityCreature entity : player.getInstance().getCreatures()) { if (entity instanceof ChickenCreature) { ChickenCreature chickenCreature = (ChickenCreature) entity; - chickenCreature.moveTo(player.getPosition()); + chickenCreature.moveTo(player.getPosition().clone()); player.sendMessage("CHICKEN GO"); } } diff --git a/src/main/java/fr/themode/minestom/collision/CollisionUtils.java b/src/main/java/fr/themode/minestom/collision/CollisionUtils.java index 6dc0dc608..d7a63e046 100644 --- a/src/main/java/fr/themode/minestom/collision/CollisionUtils.java +++ b/src/main/java/fr/themode/minestom/collision/CollisionUtils.java @@ -18,13 +18,13 @@ public class CollisionUtils { float targetZ = targetPosition.getZ(); - BlockPosition xBlock = new BlockPosition(targetX, currentY, currentZ); - BlockPosition yBlock = new BlockPosition(currentX, targetY, currentZ); - BlockPosition zBlock = new BlockPosition(currentX, currentY, targetZ); + BlockPosition xBlock = new BlockPosition(targetX, (int) currentY, currentZ); + BlockPosition yBlock = new BlockPosition(currentX, (int) targetY, currentZ); + BlockPosition zBlock = new BlockPosition(currentX, (int) currentY, targetZ); - boolean xAir = !Block.getFromId(instance.getBlockId(xBlock)).isSolid(); - boolean yAir = !Block.getFromId(instance.getBlockId(yBlock)).isSolid(); - boolean zAir = !Block.getFromId(instance.getBlockId(zBlock)).isSolid(); + boolean xAir = !Block.fromId(instance.getBlockId(xBlock)).isSolid(); + boolean yAir = !Block.fromId(instance.getBlockId(yBlock)).isSolid(); + boolean zAir = !Block.fromId(instance.getBlockId(zBlock)).isSolid(); boolean xIntersect = boundingBox.intersect(xBlock); boolean yIntersect = boundingBox.intersect(yBlock); diff --git a/src/main/java/fr/themode/minestom/entity/Entity.java b/src/main/java/fr/themode/minestom/entity/Entity.java index b8453f274..932f8d064 100644 --- a/src/main/java/fr/themode/minestom/entity/Entity.java +++ b/src/main/java/fr/themode/minestom/entity/Entity.java @@ -241,25 +241,33 @@ public abstract class Entity implements Viewable, DataContainer { // Gravity if (!(this instanceof Player) && !noGravity && gravityDragPerTick != 0) { // Players do manage gravity client-side Position position = getPosition(); + //System.out.println("on ground: "+isOnGround()); if (!isOnGround()) { float strength = gravityDragPerTick * gravityTickCounter; int firstBlock = 0; for (int y = (int) position.getY(); y > 0; y--) { - short blockId = instance.getBlockId((int) position.getX(), y, (int) position.getZ()); + BlockPosition blockPosition = new BlockPosition(position.getX(), y + 1, position.getZ()); + short blockId = instance.getBlockId(blockPosition); + //if (y == 70) + // System.out.println("id: " + blockId); if (blockId != 0) { firstBlock = y; + //System.out.println("first block: " + y); break; } } float newY = position.getY() - strength; + //System.out.println("REFRESH Y " + newY); newY = Math.max(newY, firstBlock); refreshPosition(position.getX(), newY, position.getZ()); gravityTickCounter++; if (isOnGround()) { // Round Y axis when gravity movement is done + //System.out.println("ROUND " + position.getY()); refreshPosition(position.getX(), Math.round(position.getY()), position.getZ()); gravityTickCounter = 0; + // System.out.println("recheck: " + isOnGround() + " : " + getPosition()); } if (this instanceof EntityCreature) { diff --git a/src/main/java/fr/themode/minestom/entity/EntityCreature.java b/src/main/java/fr/themode/minestom/entity/EntityCreature.java index 74809d133..0305ba1ca 100644 --- a/src/main/java/fr/themode/minestom/entity/EntityCreature.java +++ b/src/main/java/fr/themode/minestom/entity/EntityCreature.java @@ -30,7 +30,8 @@ public abstract class EntityCreature extends LivingEntity { if (blockPositions != null) { if (targetPosition != null) { float distance = getPosition().getDistance(targetPosition); - if (distance < 0.2f) { + //System.out.println("test: "+distance); + if (distance < 0.7f) { setNextPathPosition(); //System.out.println("END TARGET"); } else { @@ -130,12 +131,17 @@ public abstract class EntityCreature extends LivingEntity { public void jump(float height) { // FIXME magic value - Vector velocity = new Vector(0, height * 8, 0); - setVelocity(velocity, 350); + Vector velocity = new Vector(0, height * 7, 0); + setVelocity(velocity, 200); } public void moveTo(Position position) { pathFinder.getPath(position, blockPositions -> { + if (blockPositions.isEmpty()) { + // Didn't find path + System.out.println("NOT FOUND"); + return; + } this.blockPositions = blockPositions; setNextPathPosition(); }); @@ -157,9 +163,9 @@ public abstract class EntityCreature extends LivingEntity { return; } - this.targetPosition = blockPosition.toPosition().subtract(0.5f, 0, 0.5f); + this.targetPosition = blockPosition.toPosition();//.add(0.5f, 0, 0.5f); // FIXME: jump support - //if(blockPosition.getY() > getPosition().getY()) - // jump(1); + if (blockPosition.getY() > getPosition().getY()) + jump(1); } } diff --git a/src/main/java/fr/themode/minestom/entity/pathfinding/JPS.java b/src/main/java/fr/themode/minestom/entity/pathfinding/JPS.java index ea2778d06..aaf9950f0 100644 --- a/src/main/java/fr/themode/minestom/entity/pathfinding/JPS.java +++ b/src/main/java/fr/themode/minestom/entity/pathfinding/JPS.java @@ -1,6 +1,7 @@ package fr.themode.minestom.entity.pathfinding; import fr.themode.minestom.instance.Instance; +import fr.themode.minestom.instance.block.Block; import fr.themode.minestom.utils.BlockPosition; import fr.themode.minestom.utils.Position; @@ -132,7 +133,7 @@ public class JPS { //if(loc.getBlock().getType().isSolid()) //return true; short blockId = instance.getBlockId(loc.toBlockPosition()); - return blockId != 0; + return Block.fromId(blockId).isSolid(); } // --- diff --git a/src/main/java/fr/themode/minestom/instance/InstanceContainer.java b/src/main/java/fr/themode/minestom/instance/InstanceContainer.java index 41a65a50e..1004c5d5b 100644 --- a/src/main/java/fr/themode/minestom/instance/InstanceContainer.java +++ b/src/main/java/fr/themode/minestom/instance/InstanceContainer.java @@ -22,6 +22,7 @@ import java.io.File; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; /** @@ -36,7 +37,7 @@ public class InstanceContainer extends Instance { private ChunkGenerator chunkGenerator; private Map chunks = new ConcurrentHashMap<>(); - private volatile boolean autoChunkLoad; + private AtomicBoolean autoChunkLoad = new AtomicBoolean(false); protected InstanceContainer(UUID uniqueId, File folder) { super(uniqueId); @@ -330,12 +331,12 @@ public class InstanceContainer extends Instance { @Override public void enableAutoChunkLoad(boolean enable) { - this.autoChunkLoad = enable; + this.autoChunkLoad.set(enable); } @Override public boolean hasEnabledAutoChunkLoad() { - return autoChunkLoad; + return autoChunkLoad.get(); } protected void addSharedInstance(SharedInstance sharedInstance) { diff --git a/src/main/java/fr/themode/minestom/instance/block/Block.java b/src/main/java/fr/themode/minestom/instance/block/Block.java index 4f23a994e..0ea5f96dd 100644 --- a/src/main/java/fr/themode/minestom/instance/block/Block.java +++ b/src/main/java/fr/themode/minestom/instance/block/Block.java @@ -692,7 +692,7 @@ public enum Block { private static Short2ObjectOpenHashMap blocksMap = new Short2ObjectOpenHashMap<>(); - public static Block getFromId(short blockId) { + public static Block fromId(short blockId) { return blocksMap.getOrDefault(blockId, AIR); } diff --git a/src/main/java/fr/themode/minestom/instance/block/BlockManager.java b/src/main/java/fr/themode/minestom/instance/block/BlockManager.java index 26ab838bb..eab1c1223 100644 --- a/src/main/java/fr/themode/minestom/instance/block/BlockManager.java +++ b/src/main/java/fr/themode/minestom/instance/block/BlockManager.java @@ -26,7 +26,7 @@ public class BlockManager { } public BlockPlacementRule getBlockPlacementRule(short blockId) { - Block block = Block.getFromId(blockId); // Convert block alternative + Block block = Block.fromId(blockId); // Convert block alternative blockId = block.getBlockId(); return this.placementRules.get(blockId); } diff --git a/src/main/java/fr/themode/minestom/instance/block/rule/vanilla/RedstonePlacementRule.java b/src/main/java/fr/themode/minestom/instance/block/rule/vanilla/RedstonePlacementRule.java index 3a5371163..17641378a 100644 --- a/src/main/java/fr/themode/minestom/instance/block/rule/vanilla/RedstonePlacementRule.java +++ b/src/main/java/fr/themode/minestom/instance/block/rule/vanilla/RedstonePlacementRule.java @@ -74,12 +74,12 @@ public class RedstonePlacementRule extends BlockPlacementRule { private boolean isRedstone(Instance instance, int x, int y, int z) { short blockId = instance.getBlockId(x, y, z); - return Block.getFromId(blockId) == Block.REDSTONE_WIRE; + return Block.fromId(blockId) == Block.REDSTONE_WIRE; } private boolean isAir(Instance instance, int x, int y, int z) { short blockId = instance.getBlockId(x, y, z); - return Block.getFromId(blockId) == Block.AIR; + return Block.fromId(blockId) == Block.AIR; } } diff --git a/src/main/java/fr/themode/minestom/utils/BlockPosition.java b/src/main/java/fr/themode/minestom/utils/BlockPosition.java index 688b060fc..7498bd616 100644 --- a/src/main/java/fr/themode/minestom/utils/BlockPosition.java +++ b/src/main/java/fr/themode/minestom/utils/BlockPosition.java @@ -11,8 +11,10 @@ public class BlockPosition { } public BlockPosition(float x, float y, float z) { + final int castedY = (int) y; + this.x = (int) (x < 0 ? x - 1 : x); - this.y = (int) (y < 0 ? y - 1 : y); + this.y = (y == castedY) ? castedY : castedY + 1; this.z = (int) (z < 0 ? z - 1 : z); } diff --git a/src/main/java/fr/themode/minestom/utils/EntityUtils.java b/src/main/java/fr/themode/minestom/utils/EntityUtils.java index fc3eddb93..de8330044 100644 --- a/src/main/java/fr/themode/minestom/utils/EntityUtils.java +++ b/src/main/java/fr/themode/minestom/utils/EntityUtils.java @@ -4,6 +4,7 @@ import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.entity.Entity; import fr.themode.minestom.instance.Chunk; import fr.themode.minestom.instance.Instance; +import fr.themode.minestom.instance.block.Block; public class EntityUtils { @@ -31,10 +32,15 @@ public class EntityUtils { Instance instance = entity.getInstance(); if (instance == null) return false; - Position position = entity.getPosition(); + + Position entityPosition = entity.getPosition(); + + BlockPosition blockPosition = entityPosition.toBlockPosition(); + blockPosition = blockPosition.subtract(0, 1, 0); try { - short blockId = instance.getBlockId(position.toBlockPosition().subtract(0, 1, 0)); - return blockId != 0; + short blockId = instance.getBlockId(blockPosition); + Block block = Block.fromId(blockId); + return block.isSolid(); } catch (NullPointerException e) { // Probably an entity at the border of an unloaded chunk return false; diff --git a/src/main/java/fr/themode/minestom/utils/Position.java b/src/main/java/fr/themode/minestom/utils/Position.java index 99a5ae5c4..b25595819 100644 --- a/src/main/java/fr/themode/minestom/utils/Position.java +++ b/src/main/java/fr/themode/minestom/utils/Position.java @@ -140,7 +140,7 @@ public class Position { } public BlockPosition toBlockPosition() { - return new BlockPosition((int) Math.ceil(x), (int) Math.ceil(y), (int) Math.ceil(z)); + return new BlockPosition(x, y, z); } @Override