DEADSOFTWARE

MainComponent in kotlin
[cavedroid.git] / core / src / ru / deadsoftware / cavedroid / game / model / block / Block.kt
index 62c6f493e0f8d66221bc54d1a297dc506a28f688..fa99bfd91ed2afa2ed63221b23374ba221ad1baa 100644 (file)
@@ -4,6 +4,8 @@ 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 ru.deadsoftware.cavedroid.misc.utils.colorFromHexString
 import kotlin.contracts.ExperimentalContracts
 import kotlin.contracts.contract
 
@@ -15,18 +17,18 @@ sealed class Block {
     val width: Float get() = 16f - params.collisionMargins.left - params.collisionMargins.right
     val height: Float get() = 16f - params.collisionMargins.top - params.collisionMargins.bottom
 
-    private val spriteWidth: Float get() = 16f - params.spriteMargins.left - params.spriteMargins.right
-    private val spriteHeight: Float get() = 16f - params.spriteMargins.top - params.spriteMargins.bottom
+    val spriteWidth: Float get() = 16f - params.spriteMargins.left - params.spriteMargins.right
+    val spriteHeight: Float get() = 16f - params.spriteMargins.top - params.spriteMargins.bottom
 
-    private var animation: Array<Sprite>? = null
+    protected var animation: Array<Sprite>? = null
 
     private var _sprite: Sprite? = null
         get() {
             return animation?.get(currentAnimationFrame) ?: field
         }
 
-    val sprite: Sprite
-        get() = requireNotNull(_sprite)
+    open val sprite: Sprite
+        get() = requireNotNull(_sprite) { "null sprite for block '${params.key}'" }
 
     private val currentAnimationFrame: Int
         get() {
@@ -35,6 +37,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()
@@ -47,7 +57,10 @@ sealed class Block {
                 val width = 16 - params.spriteMargins.left - params.spriteMargins.right
                 val height = 16 - params.spriteMargins.top - params.spriteMargins.bottom
                 Sprite(params.texture, params.spriteMargins.left, 16 * y + params.spriteMargins.top, width, height)
-                    .apply { flip(false, true) }
+                    .apply {
+                        flip(false, true)
+                        params.tint?.let { tint -> color = colorFromHexString(tint) }
+                    }
             }
         }
     }
@@ -57,7 +70,10 @@ sealed class Block {
             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)
-                .apply { flip(false, true) }
+                .apply {
+                    flip(false, true)
+                    params.tint?.let { tint -> color = colorFromHexString(tint) }
+                }
         }
     }
 
@@ -95,6 +111,26 @@ sealed class Block {
         return this is Slab
     }
 
+    fun isContainer(): Boolean {
+        contract { returns(true) implies (this@Block is Container) }
+        return this is Container
+    }
+
+    fun isFurnace(): Boolean {
+        contract { returns(true) implies (this@Block is Furnace) }
+        return this is Furnace
+    }
+
+    fun isChest(): Boolean {
+        contract { returns(true) implies (this@Block is Chest) }
+        return this is Chest
+    }
+
+    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,
@@ -104,29 +140,69 @@ sealed class Block {
         )
     }
 
+    sealed class Container() : Block()
 
+    data class None(
+        override val params: CommonBlockParams
+    ) : Block()
 
     data class Normal(
         override val params: CommonBlockParams,
     ) : Block()
 
+    data class Furnace(
+        override val params: CommonBlockParams,
+    ): Container() {
+
+        override val sprite: Sprite
+            get() = getSprite(false)
+
+        private fun getSprite(isActive: Boolean): Sprite {
+            return animation?.let { animation ->
+                if (isActive) {
+                    animation[1]
+                } else {
+                    animation[0]
+                }
+            } ?: sprite
+        }
+
+        fun draw(spriter: SpriteBatch, x: Float, y: Float, isActive: Boolean) {
+            getSprite(isActive).apply {
+                setBounds(
+                    /* x = */ x + params.spriteMargins.left,
+                    /* y = */ y + params.spriteMargins.top,
+                    /* width = */ spriteWidth,
+                    /* height = */ spriteHeight
+                )
+                draw(spriter)
+            }
+        }
+
+    }
+
+    data class Chest(
+        override val params: CommonBlockParams
+    ): Container()
+
     data class Slab(
         override val params: CommonBlockParams,
         val fullBlockKey: String,
+        val otherPartBlockKey: String,
     ): Block()
 
     sealed class Fluid: Block() {
-        abstract val statesCount: Int
+        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 */
@@ -149,7 +225,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