BlockStateManager

This abstracts it and makes the code cleaner
This commit is contained in:
Bixilon 2023-06-22 01:00:24 +02:00
parent 36199275be
commit 60cda1237e
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
48 changed files with 214 additions and 107 deletions

View File

@ -36,7 +36,7 @@ internal class LightBenchmark {
@Test
fun calculateWithSolidBottom() {
val chunk = createChunkWithNeighbours()
chunk.fillBottom(createSolidBlock().defaultState)
chunk.fillBottom(createSolidBlock().states.default)
BenchmarkUtil.benchmark(100000) {
chunk.light.recalculate()
}.println()
@ -46,8 +46,8 @@ internal class LightBenchmark {
@Test
fun calculateSimplePlace() {
val chunk = createChunkWithNeighbours()
val solid = createSolidBlock().defaultState
val light = createOpaqueLight().defaultState
val solid = createSolidBlock().states.default
val light = createOpaqueLight().states.default
val lowest = chunk.getOrPut(0)!!.blocks
for (index in 0 until 256) {
lowest.unsafeSet(index, solid)
@ -70,7 +70,7 @@ internal class LightBenchmark {
@Test
fun calculateChangeAtY255() {
val chunk = createChunkWithNeighbours()
val solid = createSolidBlock().defaultState
val solid = createSolidBlock().states.default
val lowest = chunk.getOrPut(0)!!.blocks
for (index in 0 until 256) {
lowest.unsafeSet(index, solid)
@ -94,8 +94,8 @@ internal class LightBenchmark {
fun placeBottom() {
val chunk = createChunkWithNeighbours()
val solid = createSolidBlock().defaultState
val light = createOpaqueLight().defaultState
val solid = createSolidBlock().states.default
val light = createOpaqueLight().states.default
val highest = chunk.getOrPut(15)!!.blocks
for (index in 0 until 256) {
highest.unsafeSet(index or (0x0F shl 8), solid)

View File

@ -132,7 +132,7 @@ class ElytraFlyIT {
fun startFlyingInWater() {
val player = createPlayer(createConnection(5))
player.forceTeleport(Vec3d(0.0, 31.8, 0.0))
player.connection.world.fill(Vec3i(-3, 30, -3), Vec3i(3, 33, 3), player.connection.registries.block[WaterFluid]!!.defaultState)
player.connection.world.fill(Vec3i(-3, 30, -3), Vec3i(3, 33, 3), player.connection.registries.block[WaterFluid]!!.states.default)
player.equip()
@ -149,7 +149,7 @@ class ElytraFlyIT {
fun startFlyingInLava() {
val player = createPlayer(createConnection(5))
player.forceTeleport(Vec3d(0.0, 31.8, 0.0))
player.connection.world.fill(Vec3i(-3, 30, -3), Vec3i(3, 33, 3), player.connection.registries.block[LavaFluid]!!.defaultState)
player.connection.world.fill(Vec3i(-3, 30, -3), Vec3i(3, 33, 3), player.connection.registries.block[LavaFluid]!!.states.default)
player.equip()
player.runTicks(3)

View File

@ -26,7 +26,7 @@ class BedBounceIT : BounceIT() {
@Test(priority = -1)
fun getBed() {
this.block = IT.REGISTRIES.block[MinecraftBlocks.RED_BED]?.defaultState ?: throw SkipException("Can not find bed!")
this.block = IT.REGISTRIES.block[MinecraftBlocks.RED_BED]?.states?.default ?: throw SkipException("Can not find bed!")
}
fun bedLanding() {

View File

@ -33,7 +33,7 @@ class HoneyBounceIT : BounceIT() {
@Test(priority = -1)
fun getHoney() {
this.block = IT.REGISTRIES.block[MinecraftBlocks.HONEY_BLOCK]?.defaultState ?: throw SkipException("Can not find honey!")
this.block = IT.REGISTRIES.block[MinecraftBlocks.HONEY_BLOCK]?.states?.default ?: throw SkipException("Can not find honey!")
}
fun honeyLanding1() {

View File

@ -32,7 +32,7 @@ class SlimeBounceIT : BounceIT() {
@Test(priority = -1)
fun getSlime() {
this.block = IT.REGISTRIES.block[MinecraftBlocks.SLIME_BLOCK]?.defaultState ?: throw SkipException("Can not find slime!")
this.block = IT.REGISTRIES.block[MinecraftBlocks.SLIME_BLOCK]?.states?.default ?: throw SkipException("Can not find slime!")
}
fun slimeLanding() {

View File

@ -225,7 +225,7 @@ abstract class ClimbingIT {
protected fun climbingUpTrapdoor(): LocalPlayerEntity {
val player = createPlayer(createConnection())
player.connection.world.fill(Vec3i(5, 0, 5), Vec3i(5, 10, 5), block)
player.connection.world[Vec3i(5, 10, 5)] = player.connection.registries.block[MinecraftBlocks.OAK_TRAPDOOR]?.defaultState?.withProperties(BlockProperties.DOOR_OPEN to true) ?: throw SkipException("Can not get oak trapdoor!")
player.connection.world[Vec3i(5, 10, 5)] = player.connection.registries.block[MinecraftBlocks.OAK_TRAPDOOR]?.states?.default?.withProperties(BlockProperties.DOOR_OPEN to true) ?: throw SkipException("Can not get oak trapdoor!")
player.forceTeleport(Vec3d(5.0, 8.0, 5.0))
player.input = PlayerMovementInput(jump = true)

View File

@ -26,7 +26,7 @@ class LadderIT : ClimbingIT() {
@Test(priority = -1)
fun getLadder() {
this.block = IT.REGISTRIES.block[MinecraftBlocks.LADDER]?.defaultState ?: throw SkipException("Can not find ladder!")
this.block = IT.REGISTRIES.block[MinecraftBlocks.LADDER]?.states?.default ?: throw SkipException("Can not find ladder!")
}
fun ladderFallingInto1() {

View File

@ -26,7 +26,7 @@ class ScaffoldingIT : ClimbingIT() {
@Test(priority = -1)
fun getScaffolding() {
this.block = IT.REGISTRIES.block[MinecraftBlocks.SCAFFOLDING]?.defaultState ?: throw SkipException("Can not find scaffolding!")
this.block = IT.REGISTRIES.block[MinecraftBlocks.SCAFFOLDING]?.states?.default ?: throw SkipException("Can not find scaffolding!")
}
fun scaffoldingFallingInto1() {

View File

@ -26,7 +26,7 @@ class TwistedVinesIT : ClimbingIT() {
@Test(priority = -1)
fun getTwistingVines() {
this.block = IT.REGISTRIES.block[MinecraftBlocks.TWISTING_VINES]?.defaultState ?: throw SkipException("Can not find twisting vines!")
this.block = IT.REGISTRIES.block[MinecraftBlocks.TWISTING_VINES]?.states?.default ?: throw SkipException("Can not find twisting vines!")
}
fun twistedVinesFallingInto1() {

View File

@ -26,7 +26,7 @@ class CobwebIT : SlowMovementIT() {
@Test(priority = -1)
fun getCobweb() {
this.block = IT.REGISTRIES.block[MinecraftBlocks.COBWEB]?.defaultState ?: throw SkipException("Can not find cobweb!")
this.block = IT.REGISTRIES.block[MinecraftBlocks.COBWEB]?.states?.default ?: throw SkipException("Can not find cobweb!")
}
fun cobwebLanding() {

View File

@ -38,7 +38,7 @@ class PowderSnowIT : SlowMovementIT() {
@Test(priority = -1)
fun getPowderSnow() {
this.block = IT.REGISTRIES.block[MinecraftBlocks.POWDER_SNOW]?.defaultState ?: throw SkipException("Can not find powder snow!")
this.block = IT.REGISTRIES.block[MinecraftBlocks.POWDER_SNOW]?.states?.default ?: throw SkipException("Can not find powder snow!")
}
private fun LocalPlayerEntity.setFrozenTicks(ticks: Int) {

View File

@ -26,7 +26,7 @@ class SweetBerryBushIT : SlowMovementIT() {
@Test(priority = -1)
fun getSweetBerryBush() {
this.block = IT.REGISTRIES.block[MinecraftBlocks.SWEET_BERRY_BUSH]?.defaultState ?: throw SkipException("Can not find sweet berry bush!")
this.block = IT.REGISTRIES.block[MinecraftBlocks.SWEET_BERRY_BUSH]?.states?.default ?: throw SkipException("Can not find sweet berry bush!")
}
fun sweetBerryBushLanding() {

View File

@ -26,7 +26,7 @@ class HoneyWalkIT : WalkIT() {
@Test(priority = -1)
fun getHoney() {
this.block = IT.REGISTRIES.block[MinecraftBlocks.HONEY_BLOCK]?.defaultState ?: throw SkipException("Can not find honey!")
this.block = IT.REGISTRIES.block[MinecraftBlocks.HONEY_BLOCK]?.states?.default ?: throw SkipException("Can not find honey!")
}
fun honeyLanding2() {

View File

@ -32,7 +32,7 @@ class IceWalkIT : WalkIT() {
@Test(priority = -1)
fun getIce() {
this.block = IT.REGISTRIES.block[MinecraftBlocks.ICE]?.defaultState ?: throw SkipException("Can not find ice!")
this.block = IT.REGISTRIES.block[MinecraftBlocks.ICE]?.states?.default ?: throw SkipException("Can not find ice!")
}
fun iceLanding() {

View File

@ -26,7 +26,7 @@ class PackedIceWalkIT : WalkIT() {
@Test(priority = -1)
fun getPackedIce() {
this.block = IT.REGISTRIES.block[MinecraftBlocks.PACKED_ICE]?.defaultState ?: throw SkipException("Can not find packed packedIce!")
this.block = IT.REGISTRIES.block[MinecraftBlocks.PACKED_ICE]?.states?.default ?: throw SkipException("Can not find packed packedIce!")
}
fun packedIceLanding() {

View File

@ -26,7 +26,7 @@ class SlimeWalkIT : WalkIT() {
@Test(priority = -1)
fun getSlime() {
this.block = IT.REGISTRIES.block[MinecraftBlocks.SLIME_BLOCK]?.defaultState ?: throw SkipException("Can not find slime!")
this.block = IT.REGISTRIES.block[MinecraftBlocks.SLIME_BLOCK]?.states?.default ?: throw SkipException("Can not find slime!")
}
fun slimeLanding1() {

View File

@ -26,7 +26,7 @@ class SoulSandWalkIT : WalkIT() {
@Test(priority = -1)
fun getSoulSand() {
this.block = IT.REGISTRIES.block[MinecraftBlocks.SOUL_SAND]?.defaultState ?: throw SkipException("Can not find soul sand!")
this.block = IT.REGISTRIES.block[MinecraftBlocks.SOUL_SAND]?.states?.default ?: throw SkipException("Can not find soul sand!")
}
fun soulSandLanding() {

View File

@ -29,7 +29,7 @@ class SpeedGrassWalkIT : WalkIT() {
@Test(priority = -1)
fun getGrassBlock() {
this.block = IT.REGISTRIES.block[MinecraftBlocks.GRASS_BLOCK]?.defaultState ?: throw SkipException("Can not find grass block!")
this.block = IT.REGISTRIES.block[MinecraftBlocks.GRASS_BLOCK]?.states?.default ?: throw SkipException("Can not find grass block!")
}
override fun createPlayer(connection: PlayConnection): LocalPlayerEntity {

View File

@ -26,7 +26,7 @@ class StoneWalkIT : WalkIT() {
@Test(priority = -1)
fun getStone() {
this.block = IT.REGISTRIES.block[MinecraftBlocks.STONE]?.defaultState ?: throw SkipException("Can not find stone!")
this.block = IT.REGISTRIES.block[MinecraftBlocks.STONE]?.states?.default ?: throw SkipException("Can not find stone!")
}
fun stoneLanding() {

View File

@ -31,14 +31,14 @@ import kotlin.math.abs
abstract class FlowingFluidIT {
protected val levels by lazy {
arrayOf(
block!!.withProperties(BlockProperties.FLUID_LEVEL to 7),
block!!.withProperties(BlockProperties.FLUID_LEVEL to 6),
block!!.withProperties(BlockProperties.FLUID_LEVEL to 5),
block!!.withProperties(BlockProperties.FLUID_LEVEL to 4),
block!!.withProperties(BlockProperties.FLUID_LEVEL to 3),
block!!.withProperties(BlockProperties.FLUID_LEVEL to 2),
block!!.withProperties(BlockProperties.FLUID_LEVEL to 1),
block!!.withProperties(BlockProperties.FLUID_LEVEL to 0),
block!!.states.withProperties(BlockProperties.FLUID_LEVEL to 7),
block!!.states.withProperties(BlockProperties.FLUID_LEVEL to 6),
block!!.states.withProperties(BlockProperties.FLUID_LEVEL to 5),
block!!.states.withProperties(BlockProperties.FLUID_LEVEL to 4),
block!!.states.withProperties(BlockProperties.FLUID_LEVEL to 3),
block!!.states.withProperties(BlockProperties.FLUID_LEVEL to 2),
block!!.states.withProperties(BlockProperties.FLUID_LEVEL to 1),
block!!.states.withProperties(BlockProperties.FLUID_LEVEL to 0),
)
}
@ -57,7 +57,7 @@ abstract class FlowingFluidIT {
fill(
Vec3i(x - size - 2, y - 1, z - size - 2),
Vec3i(x + size + 2, y - 1, z + size + 2),
StoneTest0.block.defaultState
StoneTest0.block.states.default
)
for (offsetX in -size..size) {

View File

@ -42,7 +42,7 @@ class BubbleColumnIT {
private fun bubbleColumn(height: Int, drag: Boolean): PlayConnection {
val connection = ConnectionTestUtil.createConnection(4)
connection.world.fill(Vec3i(-10, 16, -10), Vec3i(10, 15 + height, 10), block.withProperties(BlockProperties.BUBBLE_COLUMN_DRAG to drag))
connection.world.fill(Vec3i(-10, 16, -10), Vec3i(10, 15 + height, 10), block.states.withProperties(BlockProperties.BUBBLE_COLUMN_DRAG to drag))
connection.world.fill(Vec3i(-10, 15, -10), Vec3i(10, 15, 10), StoneTest0.state)
return connection

View File

@ -44,9 +44,9 @@ class MixedFluidIT {
}
private fun World.fill() {
this[Vec3i(10, 2, 3)] = lava!!.withProperties(BlockProperties.FLUID_LEVEL to 0)
this[Vec3i(10, 2, 3)] = lava!!.states.withProperties(BlockProperties.FLUID_LEVEL to 0)
this[Vec3i(10, 1, 3)] = StoneTest0.state
this[Vec3i(10, 2, 4)] = water!!.withProperties(BlockProperties.FLUID_LEVEL to 0)
this[Vec3i(10, 2, 4)] = water!!.states.withProperties(BlockProperties.FLUID_LEVEL to 0)
this[Vec3i(10, 1, 4)] = StoneTest0.state
}
@ -78,7 +78,7 @@ class MixedFluidIT {
fun stillLavaAndLava2() {
val player = createPlayer(createConnection(3))
player.connection.world.fill()
player.connection.world[Vec3i(10, 2, 4)] = lava!!.withProperties(BlockProperties.FLUID_LEVEL to 0)
player.connection.world[Vec3i(10, 2, 4)] = lava!!.states.withProperties(BlockProperties.FLUID_LEVEL to 0)
player.forceTeleport(Vec3d(10.0, 2.0, 3.8))
player.input = PlayerMovementInput(forward = true)
@ -92,8 +92,8 @@ class MixedFluidIT {
fun mixedHeight1() {
val player = createPlayer(createConnection(3))
player.connection.world[Vec3i(10, 1, 4)] = StoneTest0.state
player.connection.world[Vec3i(10, 2, 4)] = lava!!.withProperties(BlockProperties.FLUID_LEVEL to 7)
player.connection.world[Vec3i(10, 3, 4)] = water!!.withProperties(BlockProperties.FLUID_LEVEL to 7)
player.connection.world[Vec3i(10, 2, 4)] = lava!!.states.withProperties(BlockProperties.FLUID_LEVEL to 7)
player.connection.world[Vec3i(10, 3, 4)] = water!!.states.withProperties(BlockProperties.FLUID_LEVEL to 7)
player.forceTeleport(Vec3d(10.0, 2.0, 3.8))
player.runTicks(2)
player.input = PlayerMovementInput(jump = true, forward = true)
@ -106,8 +106,8 @@ class MixedFluidIT {
fun mixedHeight2() {
val player = createPlayer(createConnection(3))
player.connection.world[Vec3i(10, 1, 4)] = StoneTest0.state
player.connection.world[Vec3i(10, 2, 4)] = lava!!.withProperties(BlockProperties.FLUID_LEVEL to 7)
player.connection.world[Vec3i(10, 3, 4)] = water!!.withProperties(BlockProperties.FLUID_LEVEL to 7)
player.connection.world[Vec3i(10, 2, 4)] = lava!!.states.withProperties(BlockProperties.FLUID_LEVEL to 7)
player.connection.world[Vec3i(10, 3, 4)] = water!!.states.withProperties(BlockProperties.FLUID_LEVEL to 7)
player.forceTeleport(Vec3d(10.0, 2.0, 3.8))
player.runTicks(2)
player.input = PlayerMovementInput(jump = true, forward = true)
@ -120,8 +120,8 @@ class MixedFluidIT {
fun mixedHeight3() {
val player = createPlayer(createConnection(3))
player.connection.world[Vec3i(10, 1, 4)] = StoneTest0.state
player.connection.world[Vec3i(10, 2, 4)] = water!!.withProperties(BlockProperties.FLUID_LEVEL to 7)
player.connection.world[Vec3i(10, 3, 4)] = lava!!.withProperties(BlockProperties.FLUID_LEVEL to 7)
player.connection.world[Vec3i(10, 2, 4)] = water!!.states.withProperties(BlockProperties.FLUID_LEVEL to 7)
player.connection.world[Vec3i(10, 3, 4)] = lava!!.states.withProperties(BlockProperties.FLUID_LEVEL to 7)
player.forceTeleport(Vec3d(10.0, 2.0, 3.8))
player.runTicks(2)
player.input = PlayerMovementInput(jump = true, forward = true)
@ -134,8 +134,8 @@ class MixedFluidIT {
fun mixedHeight4() {
val player = createPlayer(createConnection(3))
player.connection.world[Vec3i(10, 1, 4)] = StoneTest0.state
player.connection.world[Vec3i(10, 2, 4)] = water!!.withProperties(BlockProperties.FLUID_LEVEL to 7)
player.connection.world[Vec3i(10, 3, 4)] = lava!!.withProperties(BlockProperties.FLUID_LEVEL to 7)
player.connection.world[Vec3i(10, 2, 4)] = water!!.states.withProperties(BlockProperties.FLUID_LEVEL to 7)
player.connection.world[Vec3i(10, 3, 4)] = lava!!.states.withProperties(BlockProperties.FLUID_LEVEL to 7)
player.forceTeleport(Vec3d(10.0, 2.0, 3.8))
player.runTicks(2)
player.input = PlayerMovementInput(jump = true, forward = true)

View File

@ -32,7 +32,7 @@ abstract class StillFluidIT {
connection.world.fill(
Vec3i(-10, 16, -10),
Vec3i(20, 16, 20),
block!!.withProperties(BlockProperties.FLUID_LEVEL to 0)
block!!.states.withProperties(BlockProperties.FLUID_LEVEL to 0)
)
connection.world.fill(Vec3i(-10, 15, -10), Vec3i(20, 15, 20), StoneTest0.state)
@ -43,7 +43,7 @@ abstract class StillFluidIT {
connection.world.fill(
Vec3i(-10, 16, -10),
Vec3i(20, 20, 20),
block!!.withProperties(BlockProperties.FLUID_LEVEL to 0)
block!!.states.withProperties(BlockProperties.FLUID_LEVEL to 0)
)
connection.world.fill(Vec3i(-10, 15, -10), Vec3i(20, 15, 20), StoneTest0.state)
@ -60,7 +60,7 @@ abstract class StillFluidIT {
player.connection.world.fill(
Vec3i(4, 5, 7),
Vec3i(4, 16, 7),
block!!.withProperties(BlockProperties.FLUID_LEVEL to 0)
block!!.states.withProperties(BlockProperties.FLUID_LEVEL to 0)
)
player.forceTeleport(Vec3d(4.0, 18.0, 7.0))
player.runTicks(10)
@ -72,7 +72,7 @@ abstract class StillFluidIT {
player.connection.world.fill(
Vec3i(4, 5, 7),
Vec3i(4, 16, 7),
block!!.withProperties(BlockProperties.FLUID_LEVEL to 0)
block!!.states.withProperties(BlockProperties.FLUID_LEVEL to 0)
)
player.forceTeleport(Vec3d(4.0, 30.0, 7.0))
player.runTicks(35)
@ -100,7 +100,7 @@ abstract class StillFluidIT {
connection.world.fill(
Vec3i(-10, 16, -10),
Vec3i(20, 17, 20),
block!!.withProperties(BlockProperties.FLUID_LEVEL to 0)
block!!.states.withProperties(BlockProperties.FLUID_LEVEL to 0)
)
connection.world.fill(Vec3i(-10, 15, -10), Vec3i(20, 15, 20), StoneTest0.state)

View File

@ -137,7 +137,7 @@ class SneakIT {
val player = createPlayer(createConnection(3))
player.forceTeleport(Vec3d(17.0, 9.0, 8.8))
player.connection.world[Vec3i(17, 8, 8)] = StoneTest0.state
player.connection.world[Vec3i(17, 8, 9)] = player.connection.registries.block[MinecraftBlocks.SNOW]!!.withProperties(BlockProperties.SNOW_LAYERS to 4)
player.connection.world[Vec3i(17, 8, 9)] = player.connection.registries.block[MinecraftBlocks.SNOW]!!.states.withProperties(BlockProperties.SNOW_LAYERS to 4)
player.input = PlayerMovementInput(forward = true, sneak = true)
player.runTicks(20)
@ -150,7 +150,7 @@ class SneakIT {
val player = createPlayer(createConnection(3))
player.forceTeleport(Vec3d(17.0, 9.0, 8.8))
player.connection.world[Vec3i(17, 8, 8)] = StoneTest0.state
player.connection.world[Vec3i(17, 8, 9)] = player.connection.registries.block[MinecraftBlocks.SNOW]!!.withProperties(BlockProperties.SNOW_LAYERS to 5)
player.connection.world[Vec3i(17, 8, 9)] = player.connection.registries.block[MinecraftBlocks.SNOW]!!.states.withProperties(BlockProperties.SNOW_LAYERS to 5)
player.input = PlayerMovementInput(forward = true, sneak = true)
player.runTicks(15)

View File

@ -158,7 +158,7 @@ class SprintIT {
val player = createPlayer(createConnection(3))
player.forceTeleport(Vec3d(17.0, 9.0, 8.0))
player.connection.world.fill(10, 8, 5, 20, 8, 15, StoneTest0.state)
player.connection.world.fill(10, 9, 9, 20, 9, 15, player.connection.registries.block[LavaFluidBlock]!!.defaultState)
player.connection.world.fill(10, 9, 9, 20, 9, 15, player.connection.registries.block[LavaFluidBlock]!!.states.default)
player.input = PlayerMovementInput(forward = true, sprint = true)
player.runTicks(20)
player.assertPosition(17.0, 9.0, 9.7527920785995)

View File

@ -38,7 +38,7 @@ abstract class BlockTest<T : Block> {
block!!
assertEquals(block.identifier, name)
this::block.forceSet(block)
this::state.forceSet(block.defaultState)
this::state.forceSet(block.states.default)
}
fun BlockState.testLightProperties(

View File

@ -31,7 +31,7 @@ class SlabTest : BlockTest<Block>() {
fun getSlabs() {
super.retrieveBlock(MinecraftBlocks.OAK_SLAB)
top = block.withProperties(BlockProperties.SLAB_TYPE to Halves.UPPER)
top = block.states.withProperties(BlockProperties.SLAB_TYPE to Halves.UPPER)
}
}

View File

@ -31,19 +31,19 @@ class StairsTest : BlockTest<Block>() {
}
fun testLightPropertiesNorth() {
block.withProperties(BlockProperties.FACING to Directions.NORTH).testLightProperties(0, true, true, false, booleanArrayOf(false, true, false, true, true, true))
block.states.withProperties(BlockProperties.FACING to Directions.NORTH).testLightProperties(0, true, true, false, booleanArrayOf(false, true, false, true, true, true))
}
fun testLightPropertiesSouth() {
block.withProperties(BlockProperties.FACING to Directions.SOUTH).testLightProperties(0, true, true, false, booleanArrayOf(false, true, true, false, true, true))
block.states.withProperties(BlockProperties.FACING to Directions.SOUTH).testLightProperties(0, true, true, false, booleanArrayOf(false, true, true, false, true, true))
}
fun testLightPropertiesWest() {
block.withProperties(BlockProperties.FACING to Directions.WEST).testLightProperties(0, true, true, false, booleanArrayOf(false, true, true, true, false, true))
block.states.withProperties(BlockProperties.FACING to Directions.WEST).testLightProperties(0, true, true, false, booleanArrayOf(false, true, true, true, false, true))
}
fun testLightPropertiesEast() {
block.withProperties(BlockProperties.FACING to Directions.EAST).testLightProperties(0, true, true, false, booleanArrayOf(false, true, true, true, true, false))
block.states.withProperties(BlockProperties.FACING to Directions.EAST).testLightProperties(0, true, true, false, booleanArrayOf(false, true, true, true, true, false))
}
}

View File

@ -128,7 +128,7 @@ object VerifyIntegratedBlockRegistry {
compareHardness(pixlyzer, integrated, errors)
compareItem(pixlyzer, integrated, errors)
for (state in pixlyzer.states) {
val integratedState = if (state is PropertyBlockState) integrated.withProperties(state.properties) else integrated.defaultState
val integratedState = if (state is PropertyBlockState) integrated.states.withProperties(state.properties) else integrated.states.default
compareCollisionShape(state, integratedState, errors)
compareOutlineShape(state, integratedState, errors)

View File

@ -17,6 +17,7 @@ import de.bixilon.kotlinglm.vec3.Vec3i
import de.bixilon.kutil.cast.CastUtil
import de.bixilon.minosoft.data.registries.blocks.BlockTest
import de.bixilon.minosoft.data.registries.blocks.shapes.collision.context.EmptyCollisionContext
import de.bixilon.minosoft.data.registries.blocks.state.manager.SimpleStateManager
import de.bixilon.minosoft.data.registries.blocks.types.Block
import de.bixilon.minosoft.data.registries.blocks.types.properties.shape.collision.CollidableBlock
import de.bixilon.minosoft.data.registries.blocks.types.properties.shape.outline.OutlinedBlock
@ -24,6 +25,7 @@ import de.bixilon.minosoft.data.registries.shapes.voxel.AbstractVoxelShape
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.EMPTY
import de.bixilon.minosoft.protocol.network.connection.play.ConnectionTestUtil.createConnection
import org.testng.Assert.assertEquals
import org.testng.Assert.assertTrue
import org.testng.annotations.Test
@Test(groups = ["block"])
@ -48,8 +50,7 @@ class CobwebTest : BlockTest<Block>() {
}
fun testStates() {
assertEquals(1, block.states.size)
assertEquals(0, block.properties.size)
assertTrue(block.states is SimpleStateManager)
}
fun testLightProperties() {

View File

@ -17,10 +17,12 @@ import de.bixilon.kotlinglm.vec3.Vec3i
import de.bixilon.kutil.cast.CastUtil.unsafeNull
import de.bixilon.minosoft.data.registries.blocks.BlockTest
import de.bixilon.minosoft.data.registries.blocks.shapes.collision.context.EmptyCollisionContext
import de.bixilon.minosoft.data.registries.blocks.state.manager.SimpleStateManager
import de.bixilon.minosoft.data.registries.shapes.voxel.AbstractVoxelShape
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.EMPTY
import de.bixilon.minosoft.protocol.network.connection.play.ConnectionTestUtil.createConnection
import org.testng.Assert.assertEquals
import org.testng.Assert.assertTrue
import org.testng.annotations.Test
@Test(groups = ["block"])
@ -43,8 +45,7 @@ class StoneTest : BlockTest<RockBlock.Stone>() {
}
fun testStates() {
assertEquals(1, block.states.size)
assertEquals(0, block.properties.size)
assertTrue(block.states is SimpleStateManager)
}
fun testLightProperties() {

View File

@ -36,42 +36,42 @@ class WaterFluidTest {
}
fun heightLevel0() {
val state = block.withProperties(BlockProperties.FLUID_LEVEL to 0)
val state = block.states.withProperties(BlockProperties.FLUID_LEVEL to 0)
assertEquals(this.water.getHeight(state), 0.8888889f)
}
fun heightLevel2() {
val state = block.withProperties(BlockProperties.FLUID_LEVEL to 2)
val state = block.states.withProperties(BlockProperties.FLUID_LEVEL to 2)
assertEquals(this.water.getHeight(state), 0.6666667f)
}
fun heightLevel8() {
val state = block.withProperties(BlockProperties.FLUID_LEVEL to 8)
val state = block.states.withProperties(BlockProperties.FLUID_LEVEL to 8)
assertEquals(this.water.getHeight(state), 0.8888889f)
}
fun heightLevel12() {
val state = block.withProperties(BlockProperties.FLUID_LEVEL to 12)
val state = block.states.withProperties(BlockProperties.FLUID_LEVEL to 12)
assertEquals(this.water.getHeight(state), 0.8888889f)
}
fun waterlogged() {
val state = IT.REGISTRIES.block[MinecraftBlocks.OAK_SLAB]!!.withProperties(BlockProperties.WATERLOGGED to true)
val state = IT.REGISTRIES.block[MinecraftBlocks.OAK_SLAB]!!.states.withProperties(BlockProperties.WATERLOGGED to true)
assertEquals(this.water.getHeight(state), 0.8888889f)
}
fun kelp() {
val state = IT.REGISTRIES.block[MinecraftBlocks.KELP]!!.defaultState
val state = IT.REGISTRIES.block[MinecraftBlocks.KELP]!!.states.default
assertEquals(this.water.getHeight(state), 0.8888889f)
}
fun bubbleColumn() {
val state = IT.REGISTRIES.block[BubbleColumnBlock]!!.defaultState
val state = IT.REGISTRIES.block[BubbleColumnBlock]!!.states.default
assertEquals(this.water.getHeight(state), 0.8888889f)
}
fun stone() {
val state = IT.REGISTRIES.block[RockBlock.Stone]!!.defaultState
val state = IT.REGISTRIES.block[RockBlock.Stone]!!.states.default
assertEquals(this.water.getHeight(state), 0.0f)
}
}

View File

@ -26,7 +26,7 @@ abstract class ToolTest {
protected fun mine(item: Identified, block: ResourceLocation): Pair<Boolean, Float?> {
val connection = ConnectionTestUtil.createConnection()
val item: ToolItem = IT.REGISTRIES.item[item]?.unsafeCast() ?: throw SkipException("tool not available")
val block = IT.REGISTRIES.block[block]?.defaultState ?: throw SkipException("block not available")
val block = IT.REGISTRIES.block[block]?.states?.default ?: throw SkipException("block not available")
val suitable = item.isSuitableFor(connection, block, ItemStack(item))
val speed = item.getMiningSpeed(connection, block, ItemStack(item))

View File

@ -41,7 +41,7 @@ class PickaxeTagsTest {
protected fun mine(connection: PlayConnection, item: Identified, block: ResourceLocation): Pair<Boolean, Float?> {
val item: ToolItem = IT.REGISTRIES.item[item]!!.unsafeCast()
val block = IT.REGISTRIES.block[block]!!.defaultState
val block = IT.REGISTRIES.block[block]!!.states.default
val suitable = item.isSuitableFor(connection, block, ItemStack(item))
val speed = item.getMiningSpeed(connection, block, ItemStack(item))

View File

@ -474,7 +474,7 @@ class BreakHandlerTest {
companion object {
fun createTarget(connection: PlayConnection, block: ResourceLocation, distance: Double): BlockState {
val state = connection.registries.block[block]!!.defaultState
val state = connection.registries.block[block]!!.states.default
connection.world[Vec3i(1, 2, 3)] = state
val target = BlockTarget(Vec3d(1.0, 2.0, 3.0), distance, Directions.UP, state, null, Vec3i(1, 2, 3), false)

View File

@ -27,7 +27,7 @@ class SequencedExecutorTest {
fun testSequenceId() {
val connection = createConnection()
val executor = SequencedExecutor(BreakHandler(connection.camera.interactions))
val state = connection.registries.block[RockBlock.Stone]!!.defaultState
val state = connection.registries.block[RockBlock.Stone]!!.states.default
assertEquals(1, executor.start(Vec3i(1, 1, 1), state))
assertEquals(2, executor.finish())
assertEquals(3, executor.start(Vec3i(1, 1, 2), state))
@ -37,7 +37,7 @@ class SequencedExecutorTest {
fun testRevert() {
val connection = createConnection(1)
val executor = SequencedExecutor(BreakHandler(connection.camera.interactions))
val state = connection.registries.block[RockBlock.Stone]!!.defaultState
val state = connection.registries.block[RockBlock.Stone]!!.states.default
connection.world[Vec3i(1, 1, 1)] = state
@ -55,7 +55,7 @@ class SequencedExecutorTest {
fun testAcknowledge() {
val connection = createConnection()
val executor = SequencedExecutor(BreakHandler(connection.camera.interactions))
val state = connection.registries.block[RockBlock.Stone]!!.defaultState
val state = connection.registries.block[RockBlock.Stone]!!.states.default
executor.start(Vec3i(1, 1, 1), state)

View File

@ -17,6 +17,7 @@ import com.google.common.base.Objects
import de.bixilon.kutil.cast.CastUtil.unsafeCast
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
import de.bixilon.minosoft.data.registries.blocks.state.builder.BlockStateSettings
import de.bixilon.minosoft.data.registries.blocks.state.manager.PropertyStateManager
import de.bixilon.minosoft.data.registries.blocks.types.Block
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.text.BaseComponent
@ -80,7 +81,7 @@ open class PropertyBlockState(
override fun cycle(property: BlockProperties): BlockState {
val value: Any = this[property]
return withProperties(property to block.properties[property]!!.next(value))
return withProperties(property to block.states.unsafeCast<PropertyStateManager>().properties[property]!!.next(value))
}
override fun <T> get(property: BlockProperties): T {

View File

@ -0,0 +1,30 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.blocks.state.manager
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
import de.bixilon.minosoft.data.registries.blocks.state.BlockState
interface BlockStateManager : Iterable<BlockState> {
val default: BlockState
fun withProperties(vararg properties: Pair<BlockProperties, Any>): BlockState {
return this.default.withProperties(*properties)
}
fun withProperties(properties: Map<BlockProperties, Any>): BlockState {
return this.default.withProperties(properties)
}
}

View File

@ -0,0 +1,28 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.blocks.state.manager
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
import de.bixilon.minosoft.data.registries.blocks.state.BlockState
class PropertyStateManager(
val properties: Map<BlockProperties, Array<Any>>,
val states: Set<BlockState>,
override val default: BlockState,
) : BlockStateManager {
override fun iterator(): Iterator<BlockState> {
return states.iterator()
}
}

View File

@ -0,0 +1,26 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.blocks.state.manager
import de.bixilon.minosoft.data.registries.blocks.state.BlockState
import de.bixilon.minosoft.util.SingleIterator
class SimpleStateManager(
override val default: BlockState,
) : BlockStateManager {
override fun iterator(): Iterator<BlockState> {
return SingleIterator(default)
}
}

View File

@ -22,6 +22,9 @@ import de.bixilon.minosoft.data.language.translate.Translatable
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
import de.bixilon.minosoft.data.registries.blocks.settings.BlockSettings
import de.bixilon.minosoft.data.registries.blocks.state.BlockState
import de.bixilon.minosoft.data.registries.blocks.state.manager.BlockStateManager
import de.bixilon.minosoft.data.registries.blocks.state.manager.PropertyStateManager
import de.bixilon.minosoft.data.registries.blocks.state.manager.SimpleStateManager
import de.bixilon.minosoft.data.registries.blocks.types.properties.LightedBlock
import de.bixilon.minosoft.data.registries.blocks.types.properties.hardness.HardnessBlock
import de.bixilon.minosoft.data.registries.blocks.types.properties.physics.PushingBlock
@ -37,9 +40,7 @@ abstract class Block(
override val identifier: ResourceLocation,
settings: BlockSettings,
) : RegistryItem(), LightedBlock, HardnessBlock, Translatable, PushingBlock {
val properties: Map<BlockProperties, Array<Any>> = unsafeNull()
val states: Set<BlockState> = unsafeNull()
val defaultState: BlockState = unsafeNull()
val states: BlockStateManager = unsafeNull()
override val translationKey: ResourceLocation = identifier.translation("block")
@ -53,21 +54,13 @@ abstract class Block(
}
@Deprecated("Interface")
open fun getPlacementState(connection: PlayConnection, target: BlockTarget): BlockState? = defaultState
open fun getPlacementState(connection: PlayConnection, target: BlockTarget): BlockState? = states.default
@Deprecated("Interface")
open fun onUse(connection: PlayConnection, target: BlockTarget, hand: Hands, itemStack: ItemStack?): InteractionResults {
return InteractionResults.IGNORED
}
fun withProperties(vararg properties: Pair<BlockProperties, Any>): BlockState {
return this.defaultState.withProperties(*properties)
}
fun withProperties(properties: Map<BlockProperties, Any>): BlockState {
return this.defaultState.withProperties(properties)
}
@Deprecated("Interface")
open fun randomTick(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, random: Random) = Unit
@ -77,14 +70,14 @@ abstract class Block(
fun updateStates(states: Set<BlockState>, default: BlockState, properties: Map<BlockProperties, Array<Any>>) {
PROPERTIES.set(this, properties)
STATES.set(this, states)
DEFAULT_STATE.set(this, default)
val manager = when {
states.size == 1 -> SimpleStateManager(default)
else -> PropertyStateManager(properties, states, default)
}
STATES.set(this, manager)
}
private companion object {
val PROPERTIES = Block::properties.javaField!!.apply { isAccessible = true }
val STATES = Block::states.javaField!!.apply { isAccessible = true }
val DEFAULT_STATE = Block::defaultState.javaField!!.apply { isAccessible = true }
}
}

View File

@ -33,7 +33,7 @@ abstract class BlockItem<T : Block>(identifier: ResourceLocation) : Item(identif
BLOCK_FIELD.inject<RegistryItem>(_block)
}
override fun getPlacementState(connection: PlayConnection, target: BlockTarget, stack: ItemStack) = block.defaultState
override fun getPlacementState(connection: PlayConnection, target: BlockTarget, stack: ItemStack) = block.states.default
private companion object {

View File

@ -40,7 +40,7 @@ open class PixLyzerBlockItem(
}
override fun getPlacementState(connection: PlayConnection, target: BlockTarget, stack: ItemStack): BlockState {
return block.defaultState
return block.states.default
}
companion object : PixLyzerItemFactory<PixLyzerBlockItem>, MultiClassFactory<PixLyzerBlockItem> {

View File

@ -16,7 +16,6 @@ package de.bixilon.minosoft.data.registries.item.items.bucket
import de.bixilon.kutil.json.JsonObject
import de.bixilon.minosoft.camera.target.targets.BlockTarget
import de.bixilon.minosoft.data.container.stack.ItemStack
import de.bixilon.minosoft.data.registries.blocks.state.BlockState
import de.bixilon.minosoft.data.registries.blocks.types.pixlyzer.snow.PowderSnowBlock
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
@ -44,9 +43,7 @@ abstract class BucketItem(
open class PowderSnowBucketItem(resourceLocation: ResourceLocation = this.identifier) : BucketItem(resourceLocation), PlaceableItem {
protected val block: PowderSnowBlock = this::block.inject(PowderSnowBlock)
override fun getPlacementState(connection: PlayConnection, target: BlockTarget, stack: ItemStack): BlockState {
return block.defaultState
}
override fun getPlacementState(connection: PlayConnection, target: BlockTarget, stack: ItemStack) = block.states.default
companion object : ItemFactory<BucketItem> {
override val identifier = minecraft("powder_snow_bucket")

View File

@ -41,7 +41,7 @@ abstract class AxeItem(identifier: ResourceLocation, registries: Registries, dat
val properties = target.state.nullCast<PropertyBlockState>()?.properties ?: emptyMap()
return super.interact(player.connection, target.blockPosition, strippable?.get(target.state.block)?.withProperties(properties))
return super.interact(player.connection, target.blockPosition, strippable?.get(target.state.block)?.states?.withProperties(properties))
}
companion object {

View File

@ -88,7 +88,7 @@ class RawItemElement(
val color = ChatColors.WHITE
if (item is PixLyzerBlockItem) {
val defaultState = item.block.defaultState
val defaultState = item.block.states.default
defaultState.blockModel?.getParticleTexture(KUtil.RANDOM, Vec3i.EMPTY)?.let {
element = ImageElement(guiRenderer, it, size = textureSize)
}

View File

@ -47,8 +47,8 @@ class SolidCullSectionPreparer(
val context: RenderContext,
) : SolidSectionPreparer {
private val profile = context.connection.profiles.block.rendering
private val bedrock = context.connection.registries.block[MinecraftBlocks.BEDROCK]?.defaultState
private val someFullBlock = context.connection.registries.block[MinecraftBlocks.COMMAND_BLOCK]?.defaultState
private val bedrock = context.connection.registries.block[MinecraftBlocks.BEDROCK]?.states?.default
private val someFullBlock = context.connection.registries.block[MinecraftBlocks.COMMAND_BLOCK]?.states?.default
private val tintColorCalculator = context.tintManager
private var fastBedrock = false

View File

@ -0,0 +1,30 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.util
@Deprecated("Kutil 1.23")
class SingleIterator<T>(
val item: T,
) : Iterator<T> {
private var iterated = false
override fun hasNext() = !iterated
override fun next(): T {
if (iterated) throw IllegalStateException("Already iterated!")
iterated = true
return this.item
}
}