diff --git a/src/main/java/de/bixilon/minosoft/data/world/World.kt b/src/main/java/de/bixilon/minosoft/data/world/World.kt index af6ae07a8..7bccaa05d 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/World.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/World.kt @@ -184,6 +184,7 @@ class World( chunk.tick(connection, chunkPosition) } chunks.lock.release() + border.tick() } fun randomTick() { diff --git a/src/main/java/de/bixilon/minosoft/data/world/border/WorldBorder.kt b/src/main/java/de/bixilon/minosoft/data/world/border/WorldBorder.kt index 2ee45c889..d9dc08ef1 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/border/WorldBorder.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/border/WorldBorder.kt @@ -17,6 +17,8 @@ import de.bixilon.kotlinglm.vec2.Vec2d import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.kotlinglm.vec3.Vec3d import de.bixilon.kotlinglm.vec3.Vec3i +import de.bixilon.kutil.math.interpolation.DoubleInterpolation.interpolateLinear +import de.bixilon.kutil.time.TimeUtil import de.bixilon.minosoft.data.world.World import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2dUtil.EMPTY @@ -27,7 +29,13 @@ class WorldBorder { var warningBlocks = 0 var portalBound = 0 - val state = WorldBorderState.STATIC + var state = WorldBorderState.STATIC + private set + + private var lerpStart = -1L + private var lerpEnd = -1L + private var oldRadius = World.MAX_SIZE.toDouble() + private var newRadius = World.MAX_SIZE.toDouble() fun isOutside(blockPosition: Vec3i): Boolean { return isOutside(blockPosition.x.toDouble(), blockPosition.z.toDouble()) @@ -51,7 +59,41 @@ class WorldBorder { return true } - fun lerp(oldRadius: Double, newRadius: Double, speed: Long) { + fun stopLerp() { + lerpStart = -1L + } + fun lerp(oldRadius: Double, newRadius: Double, speed: Long) { + val time = TimeUtil.millis + lerpStart = time + lerpEnd = time + speed + this.oldRadius = oldRadius + this.newRadius = newRadius + } + + fun tick() { + if (lerpStart < 0L) { + return + } + val time = TimeUtil.millis + if (lerpEnd > time) { + state = WorldBorderState.STATIC + lerpStart = -1 + return + } + val remaining = lerpEnd - time + val delta = (lerpEnd - lerpStart) + val oldRadius = radius + val radius = interpolateLinear(remaining.toDouble() / delta.toDouble(), this.oldRadius, this.newRadius) + this.radius = radius + state = if (oldRadius > radius) { + WorldBorderState.SHRINKING + } else { + WorldBorderState.GROWING + } + if (oldRadius == radius) { + lerpStart = -1 + state = WorldBorderState.STATIC + } } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/border/WorldBorderRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/border/WorldBorderRenderer.kt index 5d45407cc..620a90038 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/border/WorldBorderRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/border/WorldBorderRenderer.kt @@ -13,6 +13,7 @@ package de.bixilon.minosoft.gui.rendering.world.border +import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.kutil.latch.CountUpAndDownLatch import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.text.RGBColor.Companion.asColor @@ -50,7 +51,6 @@ class WorldBorderRenderer( override fun postInit(latch: CountUpAndDownLatch) { renderWindow.textureManager.staticTextures.use(shader) shader.setUInt("uIndexLayer", texture.renderData.shaderTextureId) - shader.setFloat("uRadius", 200.0f) } override fun setupTranslucent() { @@ -79,6 +79,8 @@ class WorldBorderRenderer( WorldBorderState.STATIC -> STATIC_COLOR } shader.setRGBColor("uTintColor", color) + shader.setFloat("uRadius", border.radius.toFloat()) + shader.setVec2("uCenter", Vec2(border.center)) } override fun drawTranslucent() { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/border/SizeWorldBorderS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/border/SizeWorldBorderS2CP.kt index aa758895c..653ecfc92 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/border/SizeWorldBorderS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/border/SizeWorldBorderS2CP.kt @@ -25,6 +25,7 @@ class SizeWorldBorderS2CP(buffer: PlayInByteBuffer) : WorldBorderS2CP { val radius = buffer.readDouble() override fun handle(connection: PlayConnection) { + connection.world.border.stopLerp() connection.world.border.radius = radius }