DEADSOFTWARE

Refactor rendering
[cavedroid.git] / core / src / ru / deadsoftware / cavedroid / game / model / block / Block.kt
index 440d258eb94bbb832df8bedd9e060c3661382079..4a0c31a4a4fa7e7038284aa5b3b9776412c99c03 100644 (file)
@@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.g2d.Sprite
 import com.badlogic.gdx.graphics.g2d.SpriteBatch
 import com.badlogic.gdx.math.Rectangle
 import com.badlogic.gdx.utils.TimeUtils
+import ru.deadsoftware.cavedroid.game.model.item.Item
 import kotlin.contracts.ExperimentalContracts
 import kotlin.contracts.contract
 
@@ -20,11 +21,14 @@ sealed class Block {
 
     private var animation: Array<Sprite>? = null
 
-    private var sprite: Sprite? = null
+    private var _sprite: Sprite? = null
         get() {
             return animation?.get(currentAnimationFrame) ?: field
         }
 
+    val sprite: Sprite
+        get() = requireNotNull(_sprite) { "null sprite for block '${params.key}'" }
+
     private val currentAnimationFrame: Int
         get() {
             return params.animationInfo?.let { animInfo ->
@@ -32,6 +36,14 @@ sealed class Block {
             } ?: 0
         }
 
+    override fun hashCode(): Int {
+        return params.key.hashCode()
+    }
+
+    override fun equals(other: Any?): Boolean {
+        return params.key == (other as Item).params.key
+    }
+
     fun initialize() {
         initAnimation()
         initSprite()
@@ -50,7 +62,7 @@ sealed class Block {
     }
 
     private fun initSprite() {
-        sprite = animation?.get(0) ?: params.texture?.let { tex ->
+        _sprite = animation?.get(0) ?: params.texture?.let { tex ->
             val width = 16 - params.spriteMargins.left - params.spriteMargins.right
             val height = 16 - params.spriteMargins.top - params.spriteMargins.bottom
             Sprite(tex, params.spriteMargins.left, params.spriteMargins.top, width, height)
@@ -61,7 +73,7 @@ sealed class Block {
     fun requireSprite() = requireNotNull(sprite)
 
     fun draw(spriter: SpriteBatch, x: Float, y: Float) {
-        sprite?.apply {
+        sprite.apply {
             setBounds(
                 /* x = */ x + params.spriteMargins.left,
                 /* y = */ y + params.spriteMargins.top,
@@ -92,6 +104,11 @@ sealed class Block {
         return this is Slab
     }
 
+    fun isNone(): Boolean {
+        contract { returns(true) implies (this@Block is None) }
+        return this is None
+    }
+
     fun getRectangle(x: Int, y: Int): Rectangle {
         return Rectangle(
             /* x = */ x * 16f + params.collisionMargins.left,
@@ -101,7 +118,9 @@ sealed class Block {
         )
     }
 
-
+    data class None(
+        override val params: CommonBlockParams
+    ) : Block()
 
     data class Normal(
         override val params: CommonBlockParams,
@@ -112,18 +131,18 @@ sealed class Block {
         val fullBlockKey: String,
     ): Block()
 
-    abstract class Fluid: Block() {
-        abstract val statesCount: Int
+    sealed class Fluid: Block() {
+        abstract val state: Int
     }
     
     data class Water(
         override val params: CommonBlockParams,
-        override val statesCount: Int
+        override val state: Int,
     ) : Fluid()
 
     data class Lava(
         override val params: CommonBlockParams,
-        override val statesCount: Int
+        override val state: Int,
     ) : Fluid()
 
     /* Legacy accessors below */
@@ -146,7 +165,6 @@ sealed class Block {
     @Deprecated(LEGACY_ACCESSOR_DEPRECATION) fun isTransparent() = params.isTransparent
     @Deprecated(LEGACY_ACCESSOR_DEPRECATION) fun getTexture() = sprite
 
-
     companion object {
         private const val LEGACY_ACCESSOR_DEPRECATION = "legacy accessors will be removed"
         private const val ANIMATION_FRAME_DURATION_MS = 100L