diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/BlockPosSet.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/BlockPosSet.kt index b42bfdd85..a4a24cc32 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/BlockPosSet.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/BlockPosSet.kt @@ -88,7 +88,7 @@ class BlockPosSet : MutableSet { fun subset(pos: ChunkPos): Set { val result = BlockPosSet() - for (key in segments.keys.iterator(SectionPos.of(pos.x, 0, pos.z))) { + for (key in segments.keys.iterator(SectionPos.of(pos.x, Int.MIN_VALUE, pos.z))) { if (key.x != pos.x || key.z != pos.z) break result.segments[key] = segments[key] } @@ -192,4 +192,16 @@ class BlockPosSet : MutableSet { override fun retainAll(elements: Collection): Boolean { return removeIf { it !in elements } } + + override fun equals(other: Any?): Boolean { + return this === other || other is Set<*> && other.size == size && other.containsAll(this) + } + + override fun hashCode(): Int { + return segments.hashCode() + } + + override fun toString(): String { + return "BlockPosSet[${joinToString(", ")}]" + } } diff --git a/src/test/kotlin/ru/dbotthepony/mc/otm/tests/BlockPosSetTests.kt b/src/test/kotlin/ru/dbotthepony/mc/otm/tests/BlockPosSetTests.kt new file mode 100644 index 000000000..a67f2f102 --- /dev/null +++ b/src/test/kotlin/ru/dbotthepony/mc/otm/tests/BlockPosSetTests.kt @@ -0,0 +1,91 @@ +package ru.dbotthepony.mc.otm.tests + +import it.unimi.dsi.fastutil.objects.ObjectArraySet +import net.minecraft.core.BlockPos +import net.minecraft.core.SectionPos +import net.minecraft.world.level.ChunkPos +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import ru.dbotthepony.mc.otm.core.collect.BlockPosSet +import ru.dbotthepony.mc.otm.core.util.GJRAND64RandomSource +import java.util.stream.Collectors + +object BlockPosSetTests { + @Test + @DisplayName("BlockPosSet additions") + fun add() { + val rand = GJRAND64RandomSource(43752304058048234L, -29394036784594328L) + + val positions = ObjectArraySet() + + for (i in 0 until 1000) { + val x = rand.nextInt(-200, 200) + val y = rand.nextInt(-200, 200) + val z = rand.nextInt(-200, 200) + positions.add(BlockPos(x, y, z)) + } + + val result = BlockPosSet() + result.addAll(positions) + + Assertions.assertEquals(positions, result) + Assertions.assertEquals(positions, ObjectArraySet(result)) + + run { + val expected = positions.stream().filter { SectionPos.blockToSectionCoord(it.x) == 0 && SectionPos.blockToSectionCoord(it.z) == 0 }.collect(Collectors.toCollection(::ObjectArraySet)) + val actual = result.subset(ChunkPos.ZERO) + + Assertions.assertEquals(expected, actual) + Assertions.assertEquals(expected, ObjectArraySet(actual)) + } + + run { + val expected = positions.stream().filter { SectionPos.blockToSectionCoord(it.x) == 0 && SectionPos.blockToSectionCoord(it.z) == 1 }.collect(Collectors.toCollection(::ObjectArraySet)) + val actual = result.subset(ChunkPos(0, 1)) + + Assertions.assertEquals(expected, actual) + Assertions.assertEquals(expected, ObjectArraySet(actual)) + } + + run { + val expected = positions.stream().filter { SectionPos.blockToSectionCoord(it.x) == 0 && SectionPos.blockToSectionCoord(it.z) == -1 }.collect(Collectors.toCollection(::ObjectArraySet)) + val actual = result.subset(ChunkPos(0, -1)) + + Assertions.assertEquals(expected, actual) + Assertions.assertEquals(expected, ObjectArraySet(actual)) + } + + run { + val expected = positions.stream().filter { SectionPos.blockToSectionCoord(it.x) == 1 && SectionPos.blockToSectionCoord(it.z) == 0 }.collect(Collectors.toCollection(::ObjectArraySet)) + val actual = result.subset(ChunkPos(1, 0)) + + Assertions.assertEquals(expected, actual) + Assertions.assertEquals(expected, ObjectArraySet(actual)) + } + + run { + val expected = positions.stream().filter { SectionPos.blockToSectionCoord(it.x) == -1 && SectionPos.blockToSectionCoord(it.z) == 0 }.collect(Collectors.toCollection(::ObjectArraySet)) + val actual = result.subset(ChunkPos(-1, 0)) + + Assertions.assertEquals(expected, actual) + Assertions.assertEquals(expected, ObjectArraySet(actual)) + } + + run { + val expected = positions.stream().filter { SectionPos.blockToSectionCoord(it.x) == 1 && SectionPos.blockToSectionCoord(it.z) == 1 }.collect(Collectors.toCollection(::ObjectArraySet)) + val actual = result.subset(ChunkPos(1, 1)) + + Assertions.assertEquals(expected, actual) + Assertions.assertEquals(expected, ObjectArraySet(actual)) + } + + run { + val expected = positions.stream().filter { SectionPos.blockToSectionCoord(it.x) == -1 && SectionPos.blockToSectionCoord(it.z) == 1 }.collect(Collectors.toCollection(::ObjectArraySet)) + val actual = result.subset(ChunkPos(-1, 1)) + + Assertions.assertEquals(expected, actual) + Assertions.assertEquals(expected, ObjectArraySet(actual)) + } + } +}