mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-14 18:05:51 -04:00
position datatypes: fix overflow when adding from -1
This commit is contained in:
parent
76f39bd426
commit
d711e077b7
@ -39,50 +39,67 @@ value class BlockPosition(
|
||||
inline val y: Int get() = (((raw ushr SHIFT_Y).toInt() and MASK_Y) shl (Int.SIZE_BITS - BITS_Y)) shr (Int.SIZE_BITS - BITS_Y)
|
||||
inline val z: Int get() = (((raw ushr SHIFT_Z).toInt() and MASK_Z) shl (Int.SIZE_BITS - BITS_Z)) shr (Int.SIZE_BITS - BITS_Z)
|
||||
|
||||
inline fun modify(other: Long, component: Long, add: Long): BlockPosition {
|
||||
val bc = raw and other
|
||||
val a = ((raw and component) + add) and component
|
||||
return BlockPosition(bc or a)
|
||||
}
|
||||
|
||||
inline fun modifyX(modify: Long): BlockPosition {
|
||||
return modify((Integer.toUnsignedLong(MASK_Y) shl SHIFT_Y) or (Integer.toUnsignedLong(MASK_Z) shl SHIFT_Z), Integer.toUnsignedLong(MASK_X) shl SHIFT_X, modify)
|
||||
}
|
||||
|
||||
inline fun modifyY(modify: Long): BlockPosition {
|
||||
return modify((Integer.toUnsignedLong(MASK_X) shl SHIFT_X) or (Integer.toUnsignedLong(MASK_Z) shl SHIFT_Z), Integer.toUnsignedLong(MASK_Y) shl SHIFT_Y, modify)
|
||||
}
|
||||
|
||||
inline fun modifyZ(modify: Long): BlockPosition {
|
||||
return modify((Integer.toUnsignedLong(MASK_X) shl SHIFT_X) or (Integer.toUnsignedLong(MASK_Y) shl SHIFT_Y), Integer.toUnsignedLong(MASK_Z) shl SHIFT_Z, modify)
|
||||
}
|
||||
|
||||
inline fun plusX(): BlockPosition {
|
||||
assertPosition(this.x < MAX_X)
|
||||
return BlockPosition(raw + X * 1)
|
||||
return modifyX(X * 1)
|
||||
}
|
||||
|
||||
inline fun plusX(x: Int): BlockPosition {
|
||||
assertPosition(this.x + x, -MAX_X, MAX_X)
|
||||
return BlockPosition(raw + X * x)
|
||||
return modifyX(X * x)
|
||||
}
|
||||
|
||||
inline fun minusX(): BlockPosition {
|
||||
assertPosition(this.x > -MAX_X)
|
||||
return BlockPosition(raw - X * 1)
|
||||
return modifyX(-X * 1)
|
||||
}
|
||||
|
||||
inline fun plusY(): BlockPosition {
|
||||
assertPosition(this.y < MAX_Y)
|
||||
return BlockPosition(raw + Y * 1)
|
||||
return modifyY(Y * 1)
|
||||
}
|
||||
|
||||
inline fun plusY(y: Int): BlockPosition {
|
||||
assertPosition(this.y + y, MIN_Y, MAX_Y)
|
||||
return BlockPosition(raw + Y * y)
|
||||
return modifyY(Y * y)
|
||||
}
|
||||
|
||||
inline fun minusY(): BlockPosition {
|
||||
assertPosition(this.y > -MAX_Y)
|
||||
return BlockPosition(raw - Y * 1)
|
||||
return modifyY(-Y * 1)
|
||||
}
|
||||
|
||||
inline fun plusZ(): BlockPosition {
|
||||
assertPosition(this.z < MAX_Y)
|
||||
return BlockPosition(raw + Z * 1)
|
||||
return modifyZ(Z * 1)
|
||||
}
|
||||
|
||||
inline fun plusZ(z: Int): BlockPosition {
|
||||
assertPosition(this.z + z, -MAX_Z, MAX_Z)
|
||||
return BlockPosition(raw + Z * z)
|
||||
return modifyZ(Z * z)
|
||||
}
|
||||
|
||||
inline fun minusZ(): BlockPosition {
|
||||
assertPosition(this.z > -MAX_Z)
|
||||
return BlockPosition(raw - Z * 1)
|
||||
return modifyZ(-Z * 1)
|
||||
}
|
||||
|
||||
inline fun with(x: Int = this.x, y: Int = this.y, z: Int = this.z) = BlockPosition(x, y, z)
|
||||
|
@ -34,35 +34,49 @@ value class ChunkPosition(
|
||||
inline val x: Int get() = (raw ushr SHIFT_X).toInt() and MASK_X
|
||||
inline val z: Int get() = (raw ushr SHIFT_Z).toInt() and MASK_Z
|
||||
|
||||
inline fun modify(other: Long, component: Long, add: Long): ChunkPosition {
|
||||
val bc = raw and other
|
||||
val a = ((raw and component) + add) and component
|
||||
return ChunkPosition(bc or a)
|
||||
}
|
||||
|
||||
inline fun modifyX(modify: Long): ChunkPosition {
|
||||
return modify(Integer.toUnsignedLong(MASK_Z) shl SHIFT_Z, Integer.toUnsignedLong(MASK_X) shl SHIFT_X, modify)
|
||||
}
|
||||
|
||||
inline fun modifyZ(modify: Long): ChunkPosition {
|
||||
return modify(Integer.toUnsignedLong(MASK_X) shl SHIFT_X, Integer.toUnsignedLong(MASK_Z) shl SHIFT_Z, modify)
|
||||
}
|
||||
|
||||
|
||||
inline fun plusX(): ChunkPosition {
|
||||
assertPosition(this.x < MAX_X)
|
||||
return ChunkPosition(raw + X * 1)
|
||||
return modifyX(X * 1)
|
||||
}
|
||||
|
||||
inline fun plusX(x: Int): ChunkPosition {
|
||||
assertPosition(this.x + x, -MAX_X, MAX_X)
|
||||
return ChunkPosition(raw + X * x)
|
||||
return modifyX(X * x)
|
||||
}
|
||||
|
||||
inline fun minusX(): ChunkPosition {
|
||||
assert(this.x > -MAX_X)
|
||||
return ChunkPosition(raw - X * 1)
|
||||
return modifyX(-X * 1)
|
||||
}
|
||||
|
||||
inline fun plusZ(): ChunkPosition {
|
||||
assert(this.z < MAX_Z)
|
||||
return ChunkPosition(raw + Z * 1)
|
||||
return modifyZ(Z * 1)
|
||||
}
|
||||
|
||||
inline fun plusZ(z: Int): ChunkPosition {
|
||||
assertPosition(this.z + z, -MAX_Z, MAX_Z)
|
||||
return ChunkPosition(raw + Z * z)
|
||||
return modifyZ(Z * z)
|
||||
}
|
||||
|
||||
inline fun minusZ(): ChunkPosition {
|
||||
assert(this.z > -MAX_Z)
|
||||
return ChunkPosition(raw - Z * 1)
|
||||
return modifyZ(-Z * 1)
|
||||
}
|
||||
|
||||
inline fun with(x: Int = this.x, z: Int = this.z) = ChunkPosition(x, z)
|
||||
|
@ -39,6 +39,15 @@ value class InChunkPosition(
|
||||
inline val z: Int get() = (raw ushr SHIFT_Z) and MASK_Z
|
||||
inline val xz: Int get() = raw and ((MASK_X shl SHIFT_X) or (MASK_Z shl SHIFT_Z))
|
||||
|
||||
inline fun modify(other: Int, component: Int, add: Int): InChunkPosition {
|
||||
val bc = raw and other
|
||||
val a = ((raw and component) + add) and component
|
||||
return InChunkPosition(bc or a)
|
||||
}
|
||||
|
||||
inline fun modifyY(modify: Int): InChunkPosition {
|
||||
return modify((MASK_X shl SHIFT_X) or (MASK_Z shl SHIFT_Z), MASK_Y shl SHIFT_Y, modify)
|
||||
}
|
||||
|
||||
inline fun plusX(): InChunkPosition {
|
||||
assertPosition(this.x < ProtocolDefinition.SECTION_MAX_X)
|
||||
@ -57,17 +66,17 @@ value class InChunkPosition(
|
||||
|
||||
inline fun plusY(): InChunkPosition {
|
||||
assertPosition(this.y < ProtocolDefinition.CHUNK_MAX_Y)
|
||||
return InChunkPosition(raw + Y * 1)
|
||||
return modifyY(Y * 1)
|
||||
}
|
||||
|
||||
inline fun plusY(y: Int): InChunkPosition {
|
||||
assertPosition(this.y + y, ProtocolDefinition.CHUNK_MIN_Y, ProtocolDefinition.CHUNK_MAX_Y)
|
||||
return InChunkPosition(raw + Y * y)
|
||||
return modifyY(Y * y)
|
||||
}
|
||||
|
||||
inline fun minusY(): InChunkPosition {
|
||||
assertPosition(this.y > ProtocolDefinition.CHUNK_MIN_Y)
|
||||
return InChunkPosition(raw - Y * 1)
|
||||
return modifyY(-Y * 1)
|
||||
}
|
||||
|
||||
inline fun plusZ(): InChunkPosition {
|
||||
|
@ -35,49 +35,68 @@ value class SectionPosition(
|
||||
inline val y: SectionHeight get() = (((raw ushr SHIFT_Y).toInt() and MASK_Y) shl (Int.SIZE_BITS - BITS_Y)) shr (Int.SIZE_BITS - BITS_Y)
|
||||
inline val z: Int get() = (((raw ushr SHIFT_Z).toInt() and MASK_Z) shl (Int.SIZE_BITS - BITS_Z)) shr (Int.SIZE_BITS - BITS_Z)
|
||||
|
||||
|
||||
inline fun modify(other: Long, component: Long, add: Long): SectionPosition {
|
||||
val bc = raw and other
|
||||
val a = ((raw and component) + add) and component
|
||||
return SectionPosition(bc or a)
|
||||
}
|
||||
|
||||
inline fun modifyX(modify: Long): SectionPosition {
|
||||
return modify((Integer.toUnsignedLong(MASK_Y) shl SHIFT_Y) or (Integer.toUnsignedLong(MASK_Z) shl SHIFT_Z), Integer.toUnsignedLong(MASK_X) shl SHIFT_X, modify)
|
||||
}
|
||||
|
||||
inline fun modifyY(modify: Long): SectionPosition {
|
||||
return modify((Integer.toUnsignedLong(MASK_X) shl SHIFT_X) or (Integer.toUnsignedLong(MASK_Z) shl SHIFT_Z), Integer.toUnsignedLong(MASK_Y) shl SHIFT_Y, modify)
|
||||
}
|
||||
|
||||
inline fun modifyZ(modify: Long): SectionPosition {
|
||||
return modify((Integer.toUnsignedLong(MASK_X) shl SHIFT_X) or (Integer.toUnsignedLong(MASK_Y) shl SHIFT_Y), Integer.toUnsignedLong(MASK_Z) shl SHIFT_Z, modify)
|
||||
}
|
||||
|
||||
inline fun plusX(): SectionPosition {
|
||||
assertPosition(this.x < MAX_X)
|
||||
return SectionPosition(raw + X * 1)
|
||||
return modifyX(X * 1)
|
||||
}
|
||||
|
||||
inline fun plusX(x: Int): SectionPosition {
|
||||
assertPosition(this.x + x, -MAX_X, MAX_X)
|
||||
return SectionPosition(raw + X * x)
|
||||
return modifyX(X * x)
|
||||
}
|
||||
|
||||
inline fun minusX(): SectionPosition {
|
||||
assert(this.x > -MAX_X)
|
||||
return SectionPosition(raw - X * 1)
|
||||
return modifyX(-X * 1)
|
||||
}
|
||||
|
||||
inline fun plusY(): SectionPosition {
|
||||
assertPosition(this.y < MAX_Y)
|
||||
return SectionPosition(raw + Y * 1)
|
||||
return modifyY(Y * 1)
|
||||
}
|
||||
|
||||
inline fun plusY(y: Int): SectionPosition {
|
||||
assertPosition(this.y + y, MIN_Y, MAX_Y)
|
||||
return SectionPosition(raw + Y * y)
|
||||
return modifyY(Y * y)
|
||||
}
|
||||
|
||||
inline fun minusY(): SectionPosition {
|
||||
assert(this.y > MIN_Y)
|
||||
return SectionPosition(raw - Y * 1)
|
||||
return modifyY(-Y * 1)
|
||||
}
|
||||
|
||||
inline fun plusZ(): SectionPosition {
|
||||
assert(this.z < MAX_Z)
|
||||
return SectionPosition(raw + Z * 1)
|
||||
return modifyZ(Z * 1)
|
||||
}
|
||||
|
||||
inline fun plusZ(z: Int): SectionPosition {
|
||||
assertPosition(this.z + z, -MAX_Z, MAX_Z)
|
||||
return SectionPosition(raw + Z * z)
|
||||
return modifyZ(Z * z)
|
||||
}
|
||||
|
||||
inline fun minusZ(): SectionPosition {
|
||||
assert(this.z > -MAX_Z)
|
||||
return SectionPosition(raw - Z * 1)
|
||||
return modifyZ(-Z * 1)
|
||||
}
|
||||
|
||||
inline fun with(x: Int = this.x, y: Int = this.y, z: Int = this.z) = SectionPosition(x, y, z)
|
||||
|
@ -66,6 +66,18 @@ class BlockPositionTest {
|
||||
assertEquals(position.plusX().x, 3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus negative x`() {
|
||||
val position = BlockPosition(-2, 0xF, 0xF).plusX()
|
||||
assertEquals(position, BlockPosition(-1, 0xF, 0xF))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus zero x`() {
|
||||
val position = BlockPosition(-1, 0xF, 0xF).plusX()
|
||||
assertEquals(position, BlockPosition(0, 0xF, 0xF))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus 2 x`() {
|
||||
val position = BlockPosition(2, 0xF, 0xF)
|
||||
@ -114,6 +126,18 @@ class BlockPositionTest {
|
||||
assertEquals(position.plusY(2).y, 4)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus negative y`() {
|
||||
val position = BlockPosition(0xF, -2, 0xF).plusY()
|
||||
assertEquals(position, BlockPosition(0xF, -1, 0xF))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus zero y`() {
|
||||
val position = BlockPosition(0xF, -1, 0xF).plusY()
|
||||
assertEquals(position, BlockPosition(0xF, 0, 0xF))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct minus y`() {
|
||||
val position = BlockPosition(0xF, 2, 0xF)
|
||||
@ -153,8 +177,20 @@ class BlockPositionTest {
|
||||
|
||||
@Test
|
||||
fun `correct plus 2 z`() {
|
||||
val position = BlockPosition(0xF, 0xF, 2)
|
||||
assertEquals(position.plusZ(2).z, 4)
|
||||
val position = BlockPosition(0xF, 0xF, 2).plusZ(2)
|
||||
assertEquals(position, BlockPosition(0xF, 0xF, 4))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus negative z`() {
|
||||
val position = BlockPosition(0xF, 0xF, -2).plusZ()
|
||||
assertEquals(position, BlockPosition(0xF, 0xF, -1))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus zero z`() {
|
||||
val position = BlockPosition(0xF, 0xF, -1).plusZ()
|
||||
assertEquals(position, BlockPosition(0xF, 0xF, 0))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -66,6 +66,12 @@ class ChunkPositionTest {
|
||||
assertEquals(position.plusX().x, 3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus negative x`() {
|
||||
val position = ChunkPosition(-1, 0xF).plusX()
|
||||
assertEquals(position, ChunkPosition(0, 0xF))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus 2 x`() {
|
||||
val position = ChunkPosition(2, 0xF)
|
||||
@ -108,6 +114,12 @@ class ChunkPositionTest {
|
||||
assertEquals(position.plusZ().z, 3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus negative z`() {
|
||||
val position = ChunkPosition(0xF, -1).plusZ()
|
||||
assertEquals(position, ChunkPosition(0xF, 0))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus 2 z`() {
|
||||
val position = ChunkPosition(0xF, 2)
|
||||
|
@ -85,6 +85,12 @@ class InChunkPositionTest {
|
||||
assertEquals(position.plusY().y, 3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus negative y`() {
|
||||
val position = InChunkPosition(0xF, -1, 0xF).plusY()
|
||||
assertEquals(position, InChunkPosition(0xF, 0, 0xF))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus 2 y`() {
|
||||
val position = InChunkPosition(0xF, 2, 0xF)
|
||||
|
@ -66,6 +66,12 @@ class SectionPositionTest {
|
||||
assertEquals(position.plusX().x, 3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus negative x`() {
|
||||
val position = SectionPosition(-1, 0xF, 0xF).plusX()
|
||||
assertEquals(position, SectionPosition(0, 0xF, 0xF))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus 2 x`() {
|
||||
val position = SectionPosition(2, 0xF, 0xF)
|
||||
@ -108,6 +114,12 @@ class SectionPositionTest {
|
||||
assertEquals(position.plusY().y, 3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus negative y`() {
|
||||
val position = SectionPosition(0xF, -1, 0xF).plusY()
|
||||
assertEquals(position, SectionPosition(0xF, 0, 0xF))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus 2 y`() {
|
||||
val position = SectionPosition(0xF, 2, 0xF)
|
||||
@ -144,13 +156,18 @@ class SectionPositionTest {
|
||||
assertEquals(position.z, -1875000)
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `correct plus z`() {
|
||||
val position = SectionPosition(0xF, 0xF, 2)
|
||||
assertEquals(position.plusZ().z, 3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus negative z`() {
|
||||
val position = SectionPosition(0xF, 0xF, -1).plusZ()
|
||||
assertEquals(position, SectionPosition(0xF, 0xF, 0))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct plus 2 z`() {
|
||||
val position = SectionPosition(0xF, 0xF, 2)
|
||||
|
Loading…
x
Reference in New Issue
Block a user