mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-26 11:07:53 +01:00
Added gravity
This commit is contained in:
parent
0a732034c2
commit
8b95e3881d
@ -36,7 +36,6 @@ public abstract class Entity implements Viewable, DataContainer {
|
||||
|
||||
protected Instance instance;
|
||||
protected Position position;
|
||||
protected boolean onGround;
|
||||
protected float lastX, lastY, lastZ;
|
||||
protected float lastYaw, lastPitch;
|
||||
private int id;
|
||||
@ -45,6 +44,9 @@ public abstract class Entity implements Viewable, DataContainer {
|
||||
// Velocity
|
||||
// TODO gravity implementation for entity other than players
|
||||
protected Vector velocity = new Vector(); // Movement in block per second
|
||||
protected float gravityDragPerTick;
|
||||
private int gravityTickCounter;
|
||||
|
||||
private Set<Player> viewers = new CopyOnWriteArraySet<>();
|
||||
private Data data;
|
||||
private Set<Entity> passengers = new CopyOnWriteArraySet<>();
|
||||
@ -104,6 +106,8 @@ public abstract class Entity implements Viewable, DataContainer {
|
||||
// Called when entity a new instance is set
|
||||
public abstract void spawn();
|
||||
|
||||
public abstract boolean isOnGround();
|
||||
|
||||
public void teleport(Position position, Runnable callback) {
|
||||
if (instance == null)
|
||||
throw new IllegalStateException("You need to use Entity#setInstance before teleporting an entity!");
|
||||
@ -114,7 +118,7 @@ public abstract class Entity implements Viewable, DataContainer {
|
||||
EntityTeleportPacket entityTeleportPacket = new EntityTeleportPacket();
|
||||
entityTeleportPacket.entityId = getEntityId();
|
||||
entityTeleportPacket.position = position;
|
||||
entityTeleportPacket.onGround = onGround;
|
||||
entityTeleportPacket.onGround = isOnGround();
|
||||
sendPacketToViewers(entityTeleportPacket);
|
||||
};
|
||||
|
||||
@ -125,7 +129,7 @@ public abstract class Entity implements Viewable, DataContainer {
|
||||
callback.run();
|
||||
});
|
||||
} else {
|
||||
if (isChunkUnloaded(position.getX(), position.getZ()))
|
||||
if (ChunkUtils.isChunkUnloaded(instance, position.getX(), position.getZ()))
|
||||
return;
|
||||
runnable.run();
|
||||
if (callback != null)
|
||||
@ -210,6 +214,36 @@ public abstract class Entity implements Viewable, DataContainer {
|
||||
}
|
||||
}
|
||||
|
||||
// Gravity
|
||||
if (!(this instanceof Player) && !noGravity && gravityDragPerTick != 0) { // Players do manage gravity client-side
|
||||
Position position = getPosition();
|
||||
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());
|
||||
if (blockId != 0) {
|
||||
firstBlock = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float newY = position.getY() - strength;
|
||||
newY = Math.max(newY, firstBlock);
|
||||
refreshPosition(position.getX(), newY, position.getZ());
|
||||
gravityTickCounter++;
|
||||
if (isOnGround()) { // Round Y axis when gravity movement is done
|
||||
refreshPosition(position.getX(), Math.round(position.getY()), position.getZ());
|
||||
gravityTickCounter = 0;
|
||||
}
|
||||
|
||||
if (this instanceof EntityCreature) // Objects are automatically updated client side
|
||||
teleport(getPosition());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
update();
|
||||
|
||||
// Scheduled synchronization
|
||||
@ -295,6 +329,10 @@ public abstract class Entity implements Viewable, DataContainer {
|
||||
this.velocityTime = 0;
|
||||
}
|
||||
|
||||
public void setGravity(float gravityDragPerTick) {
|
||||
this.gravityDragPerTick = gravityDragPerTick;
|
||||
}
|
||||
|
||||
public float getDistance(Entity entity) {
|
||||
return getPosition().getDistance(entity.getPosition());
|
||||
}
|
||||
@ -360,18 +398,26 @@ public abstract class Entity implements Viewable, DataContainer {
|
||||
sendMetadataIndex(0);
|
||||
}
|
||||
|
||||
public boolean isOnFire() {
|
||||
return onFire;
|
||||
}
|
||||
|
||||
public void setGlowing(boolean glowing) {
|
||||
this.glowing = glowing;
|
||||
sendMetadataIndex(0);
|
||||
}
|
||||
|
||||
public boolean isGlowing() {
|
||||
return glowing;
|
||||
}
|
||||
|
||||
public void setNoGravity(boolean noGravity) {
|
||||
this.noGravity = noGravity;
|
||||
sendMetadataIndex(5);
|
||||
}
|
||||
|
||||
public boolean isChunkUnloaded(float x, float z) {
|
||||
return getInstance().getChunk((int) Math.floor(x / 16), (int) Math.floor(z / 16)) == null;
|
||||
public boolean hasNoGravity() {
|
||||
return noGravity;
|
||||
}
|
||||
|
||||
public void refreshPosition(float x, float y, float z) {
|
||||
@ -436,6 +482,10 @@ public abstract class Entity implements Viewable, DataContainer {
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshPosition(Position position) {
|
||||
refreshPosition(position.getX(), position.getY(), position.getZ());
|
||||
}
|
||||
|
||||
public void refreshView(float yaw, float pitch) {
|
||||
this.lastYaw = position.getYaw();
|
||||
this.lastPitch = position.getPitch();
|
||||
@ -554,7 +604,7 @@ public abstract class Entity implements Viewable, DataContainer {
|
||||
EntityTeleportPacket entityTeleportPacket = new EntityTeleportPacket();
|
||||
entityTeleportPacket.entityId = getEntityId();
|
||||
entityTeleportPacket.position = getPosition();
|
||||
entityTeleportPacket.onGround = onGround;
|
||||
entityTeleportPacket.onGround = isOnGround();
|
||||
sendPacketToViewers(entityTeleportPacket);
|
||||
}
|
||||
|
||||
|
@ -5,13 +5,15 @@ import fr.themode.minestom.net.packet.server.play.EntityPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.EntityRelativeMovePacket;
|
||||
import fr.themode.minestom.net.packet.server.play.SpawnMobPacket;
|
||||
import fr.themode.minestom.net.player.PlayerConnection;
|
||||
import fr.themode.minestom.utils.ChunkUtils;
|
||||
import fr.themode.minestom.utils.EntityUtils;
|
||||
import fr.themode.minestom.utils.Position;
|
||||
|
||||
// TODO viewers synchronization each X ticks?
|
||||
public abstract class EntityCreature extends LivingEntity {
|
||||
|
||||
public EntityCreature(int entityType) {
|
||||
super(entityType);
|
||||
public EntityCreature(EntityType entityType) {
|
||||
super(entityType.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -26,7 +28,7 @@ public abstract class EntityCreature extends LivingEntity {
|
||||
float newY = position.getY() + y;
|
||||
float newZ = position.getZ() + z;
|
||||
|
||||
if (isChunkUnloaded(newX, newZ))
|
||||
if (ChunkUtils.isChunkUnloaded(getInstance(), newX, newZ))
|
||||
return;
|
||||
|
||||
EntityRelativeMovePacket entityRelativeMovePacket = new EntityRelativeMovePacket();
|
||||
@ -67,4 +69,8 @@ public abstract class EntityCreature extends LivingEntity {
|
||||
playerConnection.sendPacket(getMetadataPacket());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnGround() {
|
||||
return EntityUtils.isOnGround(this);
|
||||
}
|
||||
}
|
||||
|
85
src/main/java/fr/themode/minestom/entity/EntityType.java
Normal file
85
src/main/java/fr/themode/minestom/entity/EntityType.java
Normal file
@ -0,0 +1,85 @@
|
||||
package fr.themode.minestom.entity;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public enum EntityType {
|
||||
ARMOR_STAND(1), // Object
|
||||
BAT(3),
|
||||
BLAZE(4),
|
||||
CAT(6),
|
||||
CAVE_SPIDER(7),
|
||||
CHICKEN(8),
|
||||
COD(9),
|
||||
COW(10),
|
||||
CREEPER(11),
|
||||
DONKEY(12),
|
||||
DOLPHIN(13),
|
||||
DROWNED(15),
|
||||
ELDER_GUARDIAN(16),
|
||||
ENDER_DRAGON(18),
|
||||
ENDERMAN(19),
|
||||
ENDERMITE(20),
|
||||
EVOKER(22),
|
||||
FOX(27),
|
||||
GHAST(28),
|
||||
GIANT(29),
|
||||
GUARDIAN(30),
|
||||
HORSE(31),
|
||||
HUSK(32),
|
||||
ILLUSIONER(33),
|
||||
LLAMA(38),
|
||||
MAGMA_CUBE(40),
|
||||
MULE(48),
|
||||
MOOSHROOM(49),
|
||||
OCELOT(50),
|
||||
PANDA(52),
|
||||
PARROT(53),
|
||||
PIG(54),
|
||||
PUFFERFISH(55),
|
||||
ZOMBIE_PIGMAN(56),
|
||||
POLAR_BEAR(57),
|
||||
RABBIT(59),
|
||||
SALMON(60),
|
||||
SHEEP(61),
|
||||
SHULKER(62),
|
||||
SILVERFISH(64),
|
||||
SKELETON(65),
|
||||
SKELETON_HORSE(66),
|
||||
SLIME(67),
|
||||
SNOW_GOLEM(69),
|
||||
SPIDER(72),
|
||||
SQUID(73),
|
||||
STRAY(74),
|
||||
TRADER_LLAMA(75),
|
||||
TROPICAL_FISH(76),
|
||||
TURTLE(77),
|
||||
VEX(83),
|
||||
VILLAGER(84),
|
||||
IRON_GOLEM(85),
|
||||
VINDICATOR(86),
|
||||
PILLAGER(87),
|
||||
WANGERING_TRADER(88),
|
||||
WITCH(89),
|
||||
WITHER(90),
|
||||
WITHER_SKELETON(91),
|
||||
WOLF(93),
|
||||
ZOMBIE(94),
|
||||
ZOMBIE_HORSE(95),
|
||||
ZOMBIE_VILLAGER(96),
|
||||
PHANTOM(97),
|
||||
RAVAGER(98);
|
||||
|
||||
private int id;
|
||||
|
||||
EntityType(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static EntityType fromId(int id) {
|
||||
return Arrays.stream(values()).filter(entityType -> entityType.id == id).findFirst().get();
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ public class ItemEntity extends ObjectEntity {
|
||||
public ItemEntity(ItemStack itemStack) {
|
||||
super(34);
|
||||
this.itemStack = itemStack;
|
||||
setGravity(0.02f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -5,6 +5,7 @@ import fr.themode.minestom.entity.property.Attribute;
|
||||
import fr.themode.minestom.event.PickupItemEvent;
|
||||
import fr.themode.minestom.instance.Chunk;
|
||||
import fr.themode.minestom.item.ItemStack;
|
||||
import fr.themode.minestom.net.packet.server.play.AnimationPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.CollectItemPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.EntityPropertiesPacket;
|
||||
|
||||
@ -26,6 +27,7 @@ public abstract class LivingEntity extends Entity {
|
||||
public LivingEntity(int entityType) {
|
||||
super(entityType);
|
||||
setupAttributes();
|
||||
setGravity(0.02f);
|
||||
}
|
||||
|
||||
public abstract void kill();
|
||||
@ -79,11 +81,21 @@ public abstract class LivingEntity extends Entity {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public void damage(float value) {
|
||||
AnimationPacket animationPacket = new AnimationPacket();
|
||||
animationPacket.entityId = getEntityId();
|
||||
animationPacket.animation = AnimationPacket.Animation.TAKE_DAMAGE;
|
||||
sendPacketToViewersAndSelf(animationPacket);
|
||||
setHealth(getHealth() - value);
|
||||
}
|
||||
|
||||
public float getHealth() {
|
||||
return health;
|
||||
}
|
||||
|
||||
public void setHealth(float health) {
|
||||
health = Math.min(health, getMaxHealth());
|
||||
|
||||
this.health = health;
|
||||
if (this.health <= 0) {
|
||||
kill();
|
||||
|
@ -2,6 +2,7 @@ package fr.themode.minestom.entity;
|
||||
|
||||
import fr.themode.minestom.net.packet.server.play.SpawnObjectPacket;
|
||||
import fr.themode.minestom.net.player.PlayerConnection;
|
||||
import fr.themode.minestom.utils.EntityUtils;
|
||||
|
||||
// TODO viewers synchronization each X ticks?
|
||||
public abstract class ObjectEntity extends Entity {
|
||||
@ -31,4 +32,10 @@ public abstract class ObjectEntity extends Entity {
|
||||
public void removeViewer(Player player) {
|
||||
super.removeViewer(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnGround() {
|
||||
return EntityUtils.isOnGround(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import fr.themode.minestom.Main;
|
||||
import fr.themode.minestom.bossbar.BossBar;
|
||||
import fr.themode.minestom.chat.Chat;
|
||||
import fr.themode.minestom.data.Data;
|
||||
import fr.themode.minestom.entity.demo.ChickenCreature;
|
||||
import fr.themode.minestom.entity.property.Attribute;
|
||||
import fr.themode.minestom.event.*;
|
||||
import fr.themode.minestom.instance.Chunk;
|
||||
@ -13,6 +14,7 @@ import fr.themode.minestom.instance.InstanceContainer;
|
||||
import fr.themode.minestom.instance.demo.ChunkGeneratorDemo;
|
||||
import fr.themode.minestom.inventory.Inventory;
|
||||
import fr.themode.minestom.inventory.PlayerInventory;
|
||||
import fr.themode.minestom.item.ItemStack;
|
||||
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.*;
|
||||
@ -40,6 +42,8 @@ public class Player extends LivingEntity {
|
||||
private GameMode gameMode;
|
||||
private LevelType levelType;
|
||||
|
||||
protected boolean onGround;
|
||||
|
||||
private static InstanceContainer instanceContainer;
|
||||
|
||||
static {
|
||||
@ -82,7 +86,7 @@ public class Player extends LivingEntity {
|
||||
protected boolean spawned;
|
||||
|
||||
public Player(UUID uuid, String username, PlayerConnection playerConnection) {
|
||||
super(93);
|
||||
super(100);
|
||||
this.uuid = uuid;
|
||||
this.username = username;
|
||||
this.playerConnection = playerConnection;
|
||||
@ -98,8 +102,11 @@ public class Player extends LivingEntity {
|
||||
setEventCallback(AttackEvent.class, event -> {
|
||||
Entity entity = event.getTarget();
|
||||
if (entity instanceof EntityCreature) {
|
||||
((EntityCreature) entity).kill();
|
||||
sendMessage("You killed an entity!");
|
||||
((EntityCreature) entity).damage(-1);
|
||||
Vector velocity = getPosition().clone().getDirection().multiply(6);
|
||||
velocity.setY(4f);
|
||||
entity.setVelocity(velocity, 150);
|
||||
sendMessage("You attacked an entity!");
|
||||
} else if (entity instanceof Player) {
|
||||
Player player = (Player) entity;
|
||||
Vector velocity = getPosition().clone().getDirection().multiply(6);
|
||||
@ -145,18 +152,18 @@ public class Player extends LivingEntity {
|
||||
setGameMode(GameMode.SURVIVAL);
|
||||
teleport(new Position(0, 66, 0));
|
||||
|
||||
/*ChickenCreature chickenCreature = new ChickenCreature();
|
||||
ChickenCreature chickenCreature = new ChickenCreature();
|
||||
chickenCreature.refreshPosition(2, 65, 2);
|
||||
chickenCreature.setInstance(getInstance());
|
||||
|
||||
for (int ix = 0; ix < 4; ix++)
|
||||
for (int iz = 0; iz < 4; iz++) {
|
||||
ItemEntity itemEntity = new ItemEntity(new ItemStack(1, (byte) 32));
|
||||
itemEntity.refreshPosition(ix, 66, iz);
|
||||
itemEntity.setNoGravity(true);
|
||||
itemEntity.refreshPosition(ix, 68, iz);
|
||||
//itemEntity.setNoGravity(true);
|
||||
itemEntity.setInstance(getInstance());
|
||||
//itemEntity.remove();
|
||||
}*/
|
||||
}
|
||||
|
||||
TeamsPacket teamsPacket = new TeamsPacket();
|
||||
teamsPacket.teamName = "TEAMNAME" + new Random().nextInt(100);
|
||||
@ -270,6 +277,11 @@ public class Player extends LivingEntity {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnGround() {
|
||||
return onGround;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
clearBossBars();
|
||||
@ -345,15 +357,12 @@ public class Player extends LivingEntity {
|
||||
playerConnection.sendPacket(chatMessagePacket);
|
||||
}
|
||||
|
||||
public void damage(float amount) {
|
||||
@Override
|
||||
public void damage(float value) {
|
||||
if (getGameMode() == GameMode.CREATIVE)
|
||||
return;
|
||||
|
||||
AnimationPacket animationPacket = new AnimationPacket();
|
||||
animationPacket.entityId = getEntityId();
|
||||
animationPacket.animation = AnimationPacket.Animation.TAKE_DAMAGE;
|
||||
sendPacketToViewersAndSelf(animationPacket);
|
||||
setHealth(getHealth() - amount);
|
||||
super.damage(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -471,7 +480,7 @@ public class Player extends LivingEntity {
|
||||
@Override
|
||||
public void teleport(Position position, Runnable callback) {
|
||||
super.teleport(position, () -> {
|
||||
if (!instance.hasEnabledAutoChunkLoad() && isChunkUnloaded(position.getX(), position.getZ()))
|
||||
if (!instance.hasEnabledAutoChunkLoad() && ChunkUtils.isChunkUnloaded(instance, position.getX(), position.getZ()))
|
||||
return;
|
||||
updatePlayerPosition();
|
||||
if (callback != null)
|
||||
|
@ -1,12 +1,12 @@
|
||||
package fr.themode.minestom.entity.demo;
|
||||
|
||||
import fr.themode.minestom.entity.EntityCreature;
|
||||
import fr.themode.minestom.utils.Vector;
|
||||
import fr.themode.minestom.entity.EntityType;
|
||||
|
||||
public class ChickenCreature extends EntityCreature {
|
||||
|
||||
public ChickenCreature() {
|
||||
super(8);
|
||||
super(EntityType.CHICKEN);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -43,11 +43,11 @@ public class ChickenCreature extends EntityCreature {
|
||||
move(x * speed, 0, z * speed);
|
||||
}
|
||||
}*/
|
||||
move(0, 0, speed);
|
||||
// move(0, 0, speed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawn() {
|
||||
setVelocity(new Vector(0, 1, 0), 3000);
|
||||
// setVelocity(new Vector(0, 1, 0), 3000);
|
||||
}
|
||||
}
|
||||
|
@ -65,8 +65,11 @@ public class BlockBatch implements BlockModifier {
|
||||
}
|
||||
chunk.refreshDataPacket();
|
||||
instance.sendChunkUpdate(chunk);
|
||||
if (isLast && callback != null)
|
||||
callback.run();
|
||||
if (isLast) {
|
||||
// data.clear();
|
||||
if (callback != null)
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ public class ChunkBatch implements BlockModifier {
|
||||
data.apply(chunk);
|
||||
}
|
||||
|
||||
// dataList.clear();
|
||||
chunk.refreshDataPacket();
|
||||
instance.sendChunkUpdate(chunk);
|
||||
if (callback != null)
|
||||
|
@ -153,20 +153,22 @@ public abstract class Instance implements BlockModifier {
|
||||
lastInstance.removeEntity(entity); // If entity is in another instance, remove it from there and add it to this
|
||||
}
|
||||
|
||||
if (entity instanceof Player) {
|
||||
Player player = (Player) entity;
|
||||
sendChunks(player);
|
||||
long[] visibleChunksEntity = ChunkUtils.getChunksInRange(entity.getPosition(), Main.ENTITY_VIEW_DISTANCE);
|
||||
boolean isPlayer = entity instanceof Player;
|
||||
|
||||
// Send player all visible entities
|
||||
long[] visibleChunksEntity = ChunkUtils.getChunksInRange(entity.getPosition(), Main.ENTITY_VIEW_DISTANCE);
|
||||
for (long chunkIndex : visibleChunksEntity) {
|
||||
getEntitiesInChunk(chunkIndex).forEach(ent -> {
|
||||
ent.addViewer(player);
|
||||
if (ent instanceof Player) {
|
||||
player.addViewer((Player) ent);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (isPlayer) {
|
||||
sendChunks((Player) entity);
|
||||
}
|
||||
|
||||
// Send all visible entities
|
||||
for (long chunkIndex : visibleChunksEntity) {
|
||||
getEntitiesInChunk(chunkIndex).forEach(ent -> {
|
||||
if (isPlayer)
|
||||
ent.addViewer((Player) entity);
|
||||
if (ent instanceof Player) {
|
||||
entity.addViewer((Player) ent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Chunk chunk = getChunkAt(entity.getPosition());
|
||||
|
@ -207,15 +207,19 @@ public class InstanceContainer extends Instance {
|
||||
|
||||
@Override
|
||||
public void sendChunk(Player player, Chunk chunk) {
|
||||
/*Buffer data = chunk.getFullDataPacket();
|
||||
if(data == null) {
|
||||
PacketWriter.writeCallbackPacket(chunk.getFreshFullDataPacket(), buffer -> {
|
||||
chunk.setFullDataPacket(buffer);
|
||||
sendChunkUpdate(player, chunk);
|
||||
});
|
||||
}else{
|
||||
sendChunkUpdate(player, chunk);
|
||||
}*/
|
||||
PacketWriter.writeCallbackPacket(chunk.getFreshFullDataPacket(), buffer -> {
|
||||
buffer.getData().retain(1).markReaderIndex();
|
||||
player.getPlayerConnection().sendUnencodedPacket(buffer);
|
||||
buffer.getData().resetReaderIndex();
|
||||
chunk.setFullDataPacket(buffer);
|
||||
sendChunkUpdate(player, chunk);
|
||||
});
|
||||
// TODO use cached chunk data
|
||||
/*chunkData.getData().retain(1).markReaderIndex();
|
||||
player.getPlayerConnection().sendUnencodedPacket(chunkData);
|
||||
chunkData.getData().resetReaderIndex();*/
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -6,6 +6,7 @@ import fr.themode.minestom.net.packet.client.play.ClientPlayerLookPacket;
|
||||
import fr.themode.minestom.net.packet.client.play.ClientPlayerPacket;
|
||||
import fr.themode.minestom.net.packet.client.play.ClientPlayerPositionAndLookPacket;
|
||||
import fr.themode.minestom.net.packet.client.play.ClientPlayerPositionPacket;
|
||||
import fr.themode.minestom.utils.ChunkUtils;
|
||||
|
||||
public class PlayerPositionListener {
|
||||
|
||||
@ -42,7 +43,7 @@ public class PlayerPositionListener {
|
||||
|
||||
private static void processMovement(Player player, float x, float y, float z, Runnable runnable) {
|
||||
//System.out.println("MOVEMENT PACKET " + Math.round(x) + ":" + Math.round(y) + ":" + Math.round(z));
|
||||
boolean chunkTest = player.isChunkUnloaded(x, z);
|
||||
boolean chunkTest = ChunkUtils.isChunkUnloaded(player.getInstance(), x, z);
|
||||
if (chunkTest) {
|
||||
player.teleport(player.getPosition());
|
||||
return;
|
||||
|
@ -10,10 +10,18 @@ public class BlockPosition {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public void add(int x, int y, int z) {
|
||||
public BlockPosition add(int x, int y, int z) {
|
||||
this.x += x;
|
||||
this.y += y;
|
||||
this.z += z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockPosition subtract(int x, int y, int z) {
|
||||
this.x -= x;
|
||||
this.y -= y;
|
||||
this.z -= z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
|
@ -1,7 +1,13 @@
|
||||
package fr.themode.minestom.utils;
|
||||
|
||||
import fr.themode.minestom.instance.Instance;
|
||||
|
||||
public class ChunkUtils {
|
||||
|
||||
public static boolean isChunkUnloaded(Instance instance, float x, float z) {
|
||||
return instance.getChunk((int) Math.floor(x / 16), (int) Math.floor(z / 16)) == null;
|
||||
}
|
||||
|
||||
public static long getChunkIndex(int chunkX, int chunkZ) {
|
||||
return (((long) chunkX) << 32) | (chunkZ & 0xffffffffL);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package fr.themode.minestom.utils;
|
||||
import fr.themode.minestom.Main;
|
||||
import fr.themode.minestom.entity.Entity;
|
||||
import fr.themode.minestom.instance.Chunk;
|
||||
import fr.themode.minestom.instance.Instance;
|
||||
|
||||
public class EntityUtils {
|
||||
|
||||
@ -26,4 +27,13 @@ public class EntityUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isOnGround(Entity entity) {
|
||||
Instance instance = entity.getInstance();
|
||||
if (instance == null)
|
||||
return false;
|
||||
Position position = entity.getPosition();
|
||||
short blockId = instance.getBlockId(position.toBlockPosition().subtract(0, 1, 0));
|
||||
return blockId != 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,6 +28,13 @@ public class Position {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Position subtract(float x, float y, float z) {
|
||||
this.x -= x;
|
||||
this.y -= y;
|
||||
this.z -= z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public float getDistance(Position position) {
|
||||
return (float) Math.sqrt(MathUtils.square(position.getX() - getX()) + MathUtils.square(position.getY() - getY()) + MathUtils.square(position.getZ() - getZ()));
|
||||
}
|
||||
@ -133,7 +140,7 @@ public class Position {
|
||||
}
|
||||
|
||||
public BlockPosition toBlockPosition() {
|
||||
return new BlockPosition((int) getX(), (int) getY(), (int) getZ());
|
||||
return new BlockPosition((int) Math.ceil(getX()), (int) Math.ceil(getY()), (int) Math.ceil(getZ()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user