Various border fixes; adhere to world coordinate scale

Fixes #2552
This commit is contained in:
Camotoy 2021-10-10 11:21:48 -04:00
parent 81566d0577
commit bf1359cf0c
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
7 changed files with 55 additions and 26 deletions

View file

@ -67,7 +67,10 @@ public class ChunkCache {
chunks.put(chunkPosition, geyserColumn);
}
public GeyserColumn getChunk(int chunkX, int chunkZ) {
/**
* Doesn't check for cache enabled, so don't use this without checking that first!
*/
private GeyserColumn getChunk(int chunkX, int chunkZ) {
long chunkPosition = MathUtils.chunkPositionToLong(chunkX, chunkZ);
return chunks.getOrDefault(chunkPosition, null);
}

View file

@ -26,7 +26,7 @@
package org.geysermc.connector.network.session.cache;
import com.nukkitx.math.GenericMath;
import com.nukkitx.math.vector.Vector2f;
import com.nukkitx.math.vector.Vector2d;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.LevelEventType;
import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
@ -43,35 +43,45 @@ import java.util.Collections;
public class WorldBorder {
private static final double DEFAULT_WORLD_BORDER_SIZE = 5.9999968E7D;
@Getter @Setter
private @Nonnull Vector2f center = Vector2f.ZERO;
@Setter
private @Nonnull Vector2d center = Vector2d.ZERO;
/**
* The diameter in blocks of the world border before it got changed or similar to newDiameter if not changed.
*/
@Getter @Setter
@Setter
private double oldDiameter = DEFAULT_WORLD_BORDER_SIZE;
/**
* The diameter in blocks of the new world border.
*/
@Getter @Setter
@Setter
private double newDiameter = DEFAULT_WORLD_BORDER_SIZE;
/**
* The speed to apply an expansion/shrinking of the world border.
* When a client joins they get the actual border oldDiameter and the time left to reach the newDiameter.
*/
@Getter @Setter
@Setter
private long speed = 0;
/**
* The time in seconds before a shrinking world border would hit a not moving player.
* Creates the same visual warning effect as warningBlocks.
*/
@Getter @Setter
@Setter
private int warningDelay = 15;
/**
* Block length before you reach the border to show warning particles.
*/
@Getter @Setter
@Setter
private int warningBlocks = 5;
/**
* The world border cannot go beyond this number, positive or negative, in world coordinates
*/
@Setter
private int absoluteMaxSize = 29999984;
/**
* The world coordinate scale as sent in the dimension registry. Used to scale the center X and Z.
*/
private double worldCoordinateScale = 1.0D;
@Getter
private boolean resizing;
@ -112,6 +122,14 @@ public class WorldBorder {
update();
}
public void setWorldCoordinateScale(double worldCoordinateScale) {
boolean needsUpdate = worldCoordinateScale != this.worldCoordinateScale;
this.worldCoordinateScale = worldCoordinateScale;
if (needsUpdate) {
this.update();
}
}
/**
* @return true as long the entity is within the world limits.
*/
@ -173,10 +191,16 @@ public class WorldBorder {
} else {
radius = this.newDiameter / 2.0D;
}
this.minX = center.getX() - radius;
this.minZ = center.getY() - radius; // Mapping 2D vector to 3D coordinates >> Y becomes Z
this.maxX = center.getX() + radius;
this.maxZ = center.getY() + radius; // Mapping 2D vector to 3D coordinates >> Y becomes Z
double absoluteMinSize = -this.absoluteMaxSize;
// Used in the Nether by default
double centerX = this.center.getX() / this.worldCoordinateScale;
double centerZ = this.center.getY() / this.worldCoordinateScale; // Mapping 2D vector to 3D coordinates >> Y becomes Z
this.minX = GenericMath.clamp(centerX - radius, absoluteMinSize, this.absoluteMaxSize);
this.minZ = GenericMath.clamp(centerZ - radius, absoluteMinSize, this.absoluteMaxSize);
this.maxX = GenericMath.clamp(centerX + radius, absoluteMinSize, this.absoluteMaxSize);
this.maxZ = GenericMath.clamp(centerZ + radius, absoluteMinSize, this.absoluteMaxSize);
/*
* Caching the warning boundaries.

View file

@ -114,6 +114,6 @@ public class JavaJoinGameTranslator extends PacketTranslator<ServerJoinGamePacke
DimensionUtils.switchDimension(session, newDimension);
}
ChunkUtils.applyDimensionHeight(session, packet.getDimension());
ChunkUtils.loadDimensionTag(session, packet.getDimension());
}
}

View file

@ -90,6 +90,6 @@ public class JavaRespawnTranslator extends PacketTranslator<ServerRespawnPacket>
DimensionUtils.switchDimension(session, newDimension);
}
ChunkUtils.applyDimensionHeight(session, packet.getDimension());
ChunkUtils.loadDimensionTag(session, packet.getDimension());
}
}

View file

@ -26,7 +26,7 @@
package org.geysermc.connector.network.translators.java.world.border;
import com.github.steveice10.mc.protocol.packet.ingame.server.world.border.ServerInitializeBorderPacket;
import com.nukkitx.math.vector.Vector2f;
import com.nukkitx.math.vector.Vector2d;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.session.cache.WorldBorder;
import org.geysermc.connector.network.translators.PacketTranslator;
@ -38,13 +38,14 @@ public class JavaInitializeBorderTranslator extends PacketTranslator<ServerIniti
@Override
public void translate(GeyserSession session, ServerInitializeBorderPacket packet) {
WorldBorder worldBorder = session.getWorldBorder();
worldBorder.setCenter(Vector2f.from(packet.getNewCenterX(), packet.getNewCenterZ()));
worldBorder.setCenter(Vector2d.from(packet.getNewCenterX(), packet.getNewCenterZ()));
worldBorder.setOldDiameter(packet.getOldSize());
worldBorder.setNewDiameter(packet.getNewSize());
worldBorder.setSpeed(packet.getLerpTime());
worldBorder.setWarningDelay(packet.getWarningTime());
worldBorder.setWarningBlocks(packet.getWarningBlocks());
worldBorder.setResizing(packet.getLerpTime() > 0);
worldBorder.setAbsoluteMaxSize(packet.getNewAbsoluteMaxSize());
worldBorder.update();
}

View file

@ -26,19 +26,19 @@
package org.geysermc.connector.network.translators.java.world.border;
import com.github.steveice10.mc.protocol.packet.ingame.server.world.border.ServerSetBorderCenterPacket;
import com.nukkitx.math.vector.Vector2f;
import com.nukkitx.math.vector.Vector2d;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.session.cache.WorldBorder;
import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator;
@Translator(packet = ServerSetBorderCenterPacket.class)
public class JavaSetBorderCenterPacket extends PacketTranslator<ServerSetBorderCenterPacket> {
public class JavaSetBorderCenterTranslator extends PacketTranslator<ServerSetBorderCenterPacket> {
@Override
public void translate(GeyserSession session, ServerSetBorderCenterPacket packet) {
WorldBorder worldBorder = session.getWorldBorder();
worldBorder.setCenter(Vector2f.from(packet.getNewCenterX(), packet.getNewCenterZ()));
worldBorder.setCenter(Vector2d.from(packet.getNewCenterX(), packet.getNewCenterZ()));
worldBorder.update();
}

View file

@ -31,10 +31,7 @@ import com.github.steveice10.mc.protocol.data.game.chunk.Column;
import com.github.steveice10.mc.protocol.data.game.chunk.palette.GlobalPalette;
import com.github.steveice10.mc.protocol.data.game.chunk.palette.Palette;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.github.steveice10.opennbt.tag.builtin.*;
import com.nukkitx.math.vector.Vector2i;
import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.nbt.NbtMap;
@ -429,10 +426,10 @@ public class ChunkUtils {
}
/**
* Process the minimum and maximum heights for this dimension.
* Process the minimum and maximum heights for this dimension, and processes the world coordinate scale.
* This must be done after the player has switched dimensions so we know what their dimension is
*/
public static void applyDimensionHeight(GeyserSession session, CompoundTag dimensionTag) {
public static void loadDimensionTag(GeyserSession session, CompoundTag dimensionTag) {
int minY = ((IntTag) dimensionTag.get("min_y")).getValue();
int maxY = ((IntTag) dimensionTag.get("height")).getValue();
// Logical height can be ignored probably - seems to be for artificial limits like the Nether.
@ -467,6 +464,10 @@ public class ChunkUtils {
session.getChunkCache().setMinY(minY);
session.getChunkCache().setHeightY(maxY);
// Load world coordinate scale for the world border
double coordinateScale = ((DoubleTag) dimensionTag.get("coordinate_scale")).getValue();
session.getWorldBorder().setWorldCoordinateScale(coordinateScale);
}
@Data