~cytrogen/vbhelper

7160eb792a6e01e77c2644c298ef3e996b188224 — Nacho 7 months ago cb9fe8e
Adventure Missions progress
- Viewing the adventure missions completed in a card is now possible.
27 files changed, 528 insertions(+), 46 deletions(-)

M app/build.gradle.kts
M app/src/main/java/com/github/nacabaro/vbhelper/daos/AdventureDao.kt
A app/src/main/java/com/github/nacabaro/vbhelper/daos/CardAdventureDao.kt
M app/src/main/java/com/github/nacabaro/vbhelper/daos/CardDao.kt
A app/src/main/java/com/github/nacabaro/vbhelper/daos/CardFusionsDao.kt
M app/src/main/java/com/github/nacabaro/vbhelper/daos/CardProgressDao.kt
M app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt
M app/src/main/java/com/github/nacabaro/vbhelper/daos/DexDao.kt
M app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt
M app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt
A app/src/main/java/com/github/nacabaro/vbhelper/domain/card/CardAdventure.kt
R app/src/main/java/com/github/nacabaro/vbhelper/domain/card/{CharacterData => CardCharacter}.kt
A app/src/main/java/com/github/nacabaro/vbhelper/domain/card/CardFusions.kt
M app/src/main/java/com/github/nacabaro/vbhelper/domain/card/PossibleTransformations.kt
M app/src/main/java/com/github/nacabaro/vbhelper/domain/characters/Dex.kt
M app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/TransformationHistory.kt
M app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/UserCharacter.kt
M app/src/main/java/com/github/nacabaro/vbhelper/dtos/CardDtos.kt
M app/src/main/java/com/github/nacabaro/vbhelper/dtos/CharacterDtos.kt
M app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt
M app/src/main/java/com/github/nacabaro/vbhelper/navigation/NavigationItems.kt
A app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardAdventureEntry.kt
A app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardAdventureScreen.kt
M app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardScreenController.kt
M app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardScreenControllerImpl.kt
M app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardViewScreen.kt
M app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt
M app/build.gradle.kts => app/build.gradle.kts +1 -1
@@ 15,7 15,7 @@ android {
        minSdk = 28
        targetSdk = 35
        versionCode = 1
        versionName = "Alpha 0.6"
        versionName = "Alpha 0.6.1"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

M app/src/main/java/com/github/nacabaro/vbhelper/daos/AdventureDao.kt => app/src/main/java/com/github/nacabaro/vbhelper/daos/AdventureDao.kt +1 -1
@@ 31,7 31,7 @@ interface AdventureDao {
            a.finishesAdventure AS finishesAdventure,
            a.originalDuration AS originalTimeInMinutes
        FROM UserCharacter uc
        JOIN CharacterData c ON uc.charId = c.id
        JOIN CardCharacter c ON uc.charId = c.id
        JOIN Sprite s ON s.id = c.spriteId
        JOIN Card d ON c.cardId = d.id
        JOIN Adventure a ON uc.id = a.characterId

A app/src/main/java/com/github/nacabaro/vbhelper/daos/CardAdventureDao.kt => app/src/main/java/com/github/nacabaro/vbhelper/daos/CardAdventureDao.kt +58 -0
@@ 0,0 1,58 @@
package com.github.nacabaro.vbhelper.daos

import androidx.room.Dao
import androidx.room.Query
import com.github.nacabaro.vbhelper.dtos.CardDtos

@Dao
interface CardAdventureDao {
    @Query("""
        INSERT INTO 
            CardAdventure (cardId, characterId, steps, bossAp, bossHp, bossDp, bossBp)
        SELECT
            :cardId,
            cc.id,
            :steps,
            :bossAp,
            :bossHp,
            :bossDp,
            :bossBp
        FROM
            CardCharacter cc
        WHERE
            cc.charaIndex = :characterId AND
            cc.cardId = :cardId
    """)
    suspend fun insertNewAdventure(
        cardId: Long,
        characterId: Int,
        steps: Int,
        bossAp: Int,
        bossHp: Int,
        bossDp: Int,
        bossBp: Int?
    )

    @Query("""
        SELECT
            cc.nameSprite as characterName,
            cc.nameWidth as characterNameWidth,
            cc.nameHeight as characterNameHeight,
            s.spriteIdle1 as characterIdleSprite,
            s.width as characterIdleSpriteWidth,
            s.height as characterIdleSpriteHeight,
            ca.bossAp as characterAp,
            ca.bossBp as characterBp,
            ca.bossDp as characterDp,
            ca.bossHp as characterHp,
            ca.steps as steps
        FROM CardCharacter cc
        JOIN Sprite s ON cc.spriteId = s.id
        JOIN CardAdventure ca ON cc.id = ca.characterId
        WHERE
            cc.cardId = :cardId
    """)
    suspend fun getAdventureForCard(
        cardId: Long
    ): List<CardDtos.CardAdventureWithSprites>
}
\ No newline at end of file

M app/src/main/java/com/github/nacabaro/vbhelper/daos/CardDao.kt => app/src/main/java/com/github/nacabaro/vbhelper/daos/CardDao.kt +1 -1
@@ 21,7 21,7 @@ interface CardDao {
        """
        SELECT ca.* 
        FROM Card ca
        JOIN CharacterData ch ON ca.id = ch.cardId
        JOIN CardCharacter ch ON ca.id = ch.cardId
        JOIN UserCharacter uc ON ch.id = uc.charId
        WHERE uc.id = :id
    """

A app/src/main/java/com/github/nacabaro/vbhelper/daos/CardFusionsDao.kt => app/src/main/java/com/github/nacabaro/vbhelper/daos/CardFusionsDao.kt +32 -0
@@ 0,0 1,32 @@
package com.github.nacabaro.vbhelper.daos

import androidx.room.Dao
import androidx.room.Query

@Dao
interface CardFusionsDao {
    @Query("""
        INSERT INTO
            CardFusions (
                fromCharaId,
                attribute1Fusion,
                attribute2Fusion,
                attribute3Fusion,
                attribute4Fusion
            )
        SELECT
            (SELECT id FROM CardCharacter WHERE cardId = :cardId AND charaIndex = :fromCharaId),
            (SELECT id FROM CardCharacter WHERE cardId = :cardId AND charaIndex = :toCharaIdAttr1),
            (SELECT id FROM CardCharacter WHERE cardId = :cardId AND charaIndex = :toCharaIdAttr2),
            (SELECT id FROM CardCharacter WHERE cardId = :cardId AND charaIndex = :toCharaIdAttr3),
            (SELECT id FROM CardCharacter WHERE cardId = :cardId AND charaIndex = :toCharaIdAttr4)            
    """)
    suspend fun insertNewFusion(
        cardId: Long,
        fromCharaId: Int,
        toCharaIdAttr1: Int,
        toCharaIdAttr2: Int,
        toCharaIdAttr3: Int,
        toCharaIdAttr4: Int
    )
}
\ No newline at end of file

M app/src/main/java/com/github/nacabaro/vbhelper/daos/CardProgressDao.kt => app/src/main/java/com/github/nacabaro/vbhelper/daos/CardProgressDao.kt +1 -1
@@ 13,5 13,5 @@ interface CardProgressDao {
    @Query(
        "SELECT currentStage FROM CardProgress WHERE cardId = :cardId"
    )
    fun getCardProgress(cardId: Int): Int
    fun getCardProgress(cardId: Long): Int
}
\ No newline at end of file

M app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt => app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt +8 -8
@@ 3,17 3,17 @@ package com.github.nacabaro.vbhelper.daos
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import com.github.nacabaro.vbhelper.domain.card.CharacterData
import com.github.nacabaro.vbhelper.domain.card.CardCharacter
import com.github.nacabaro.vbhelper.domain.characters.Sprite
import com.github.nacabaro.vbhelper.dtos.CharacterDtos

@Dao
interface CharacterDao {
    @Insert
    suspend fun insertCharacter(vararg characterData: CharacterData)
    suspend fun insertCharacter(vararg characterData: CardCharacter)

    @Query("SELECT * FROM CharacterData WHERE charaIndex = :monIndex AND cardId = :dimId LIMIT 1")
    fun getCharacterByMonIndex(monIndex: Int, dimId: Long): CharacterData
    @Query("SELECT * FROM CardCharacter WHERE charaIndex = :monIndex AND cardId = :dimId LIMIT 1")
    fun getCharacterByMonIndex(monIndex: Int, dimId: Long): CardCharacter

    @Insert
    suspend fun insertSprite(vararg sprite: Sprite)


@@ 25,7 25,7 @@ interface CharacterDao {
            c.charaIndex as charId,
            c.stage as stage,
            c.attribute as attribute
        FROM CharacterData c
        FROM CardCharacter c
        JOIN UserCharacter uc ON c.id = uc.charId
        JOIN Card d ON c.cardId = d.id
        WHERE c.id = :charId


@@ 37,14 37,14 @@ interface CharacterDao {
        """
        INSERT INTO PossibleTransformations (charaId, requiredVitals, requiredTrophies, requiredBattles, requiredWinRate, changeTimerHours, requiredAdventureLevelCompleted, toCharaId)
        SELECT
            (SELECT id FROM CharacterData WHERE charaIndex = :fromChraraIndex AND cardId = :cardId),
            (SELECT id FROM CardCharacter WHERE charaIndex = :fromChraraIndex AND cardId = :cardId),
            :requiredVitals,
            :requiredTrophies,
            :requiredBattles,
            :requiredWinRate,
            :changeTimerHours,
            :requiredAdventureLevelCompleted,
            (SELECT id FROM CharacterData WHERE charaIndex = :toChraraIndex AND cardId = :cardId)
            (SELECT id FROM CardCharacter WHERE charaIndex = :toChraraIndex AND cardId = :cardId)
    """
    )
    suspend fun insertPossibleTransformation(


@@ 76,7 76,7 @@ interface CharacterDao {
            pt.requiredAdventureLevelCompleted as requiredAdventureLevelCompleted
        FROM
            PossibleTransformations pt
        JOIN CharacterData c on pt.toCharaId = c.id
        JOIN CardCharacter c on pt.toCharaId = c.id
        JOIN Sprite s ON s.id = c.spriteId
        LEFT JOIN Dex d ON d.id = pt.toCharaId
        WHERE

M app/src/main/java/com/github/nacabaro/vbhelper/daos/DexDao.kt => app/src/main/java/com/github/nacabaro/vbhelper/daos/DexDao.kt +4 -4
@@ 11,7 11,7 @@ interface DexDao {
        """
        INSERT OR IGNORE INTO Dex(id, discoveredOn)
        VALUES (
            (SELECT id FROM CharacterData WHERE charaIndex = :charIndex AND cardId = :cardId), 
            (SELECT id FROM CardCharacter WHERE charaIndex = :charIndex AND cardId = :cardId), 
            :discoveredOn
        )
    """


@@ 34,7 34,7 @@ interface DexDao {
            c.baseAp as baseAp,
            c.stage as stage,
            c.attribute as attribute
        FROM CharacterData c
        FROM CardCharacter c
        JOIN Sprite s ON c.spriteId = s.id
        LEFT JOIN dex d ON c.id = d.id
        WHERE c.cardId = :cardId


@@ 50,8 50,8 @@ interface DexDao {
            c.logo as cardLogo,
            c.logoWidth as logoWidth,
            c.logoHeight as logoHeight, 
            (SELECT COUNT(*) FROM CharacterData cc WHERE cc.cardId = c.id) AS totalCharacters,
            (SELECT COUNT(*) FROM Dex d JOIN CharacterData cc ON d.id = cc.id WHERE cc.cardId = c.id AND d.discoveredOn IS NOT NULL) AS obtainedCharacters
            (SELECT COUNT(*) FROM CardCharacter cc WHERE cc.cardId = c.id) AS totalCharacters,
            (SELECT COUNT(*) FROM Dex d JOIN CardCharacter cc ON d.id = cc.id WHERE cc.cardId = c.id AND d.discoveredOn IS NOT NULL) AS obtainedCharacters
        FROM Card c
    """
    )

M app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt => app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt +10 -10
@@ 5,7 5,7 @@ import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Upsert
import com.github.nacabaro.vbhelper.domain.card.CharacterData
import com.github.nacabaro.vbhelper.domain.card.CardCharacter
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions


@@ 47,7 47,7 @@ interface UserCharacterDao {
            c.charaIndex AS monIndex, 
            t.transformationDate AS transformationDate
        FROM TransformationHistory t 
        JOIN CharacterData c ON c.id = t.stageId
        JOIN CardCharacter c ON c.id = t.stageId
        JOIN Sprite s ON s.id = c.spriteId
        WHERE monId = :monId
    """


@@ 70,7 70,7 @@ interface UserCharacterDao {
            d.isBEm as isBemCard,
            a.characterId = uc.id as isInAdventure
        FROM UserCharacter uc
        JOIN CharacterData c ON uc.charId = c.id
        JOIN CardCharacter c ON uc.charId = c.id
        JOIN Card d ON  d.id = c.cardId
        JOIN Sprite s ON s.id = c.spriteId
        LEFT JOIN Adventure a ON a.characterId = uc.id


@@ 94,7 94,7 @@ interface UserCharacterDao {
            d.isBEm as isBemCard,
            a.characterId = uc.id as isInAdventure
        FROM UserCharacter uc
        JOIN CharacterData c ON uc.charId = c.id
        JOIN CardCharacter c ON uc.charId = c.id
        JOIN Card d ON c.cardId = d.id
        JOIN Sprite s ON s.id = c.spriteId
        LEFT JOIN Adventure a ON a.characterId = uc.id


@@ 131,7 131,7 @@ interface UserCharacterDao {
            d.isBEm as isBemCard,
            a.characterId as isInAdventure            
        FROM UserCharacter uc
        JOIN CharacterData c ON uc.charId = c.id
        JOIN CardCharacter c ON uc.charId = c.id
        JOIN Card d ON c.cardId = d.id
        JOIN Sprite s ON s.id = c.spriteId
        LEFT JOIN Adventure a ON a.characterId = uc.id


@@ 153,13 153,13 @@ interface UserCharacterDao {
    @Query(
        """
        SELECT c.*
        FROM CharacterData c
        FROM CardCharacter c
        join UserCharacter uc on c.id = uc.charId
        where uc.id = :charId
        LIMIT 1
        """
    )
    suspend fun getCharacterInfo(charId: Long): CharacterData
    suspend fun getCharacterInfo(charId: Long): CardCharacter


    @Query(


@@ 167,7 167,7 @@ interface UserCharacterDao {
        INSERT INTO TransformationHistory(monId, stageId, transformationDate)
        VALUES 
            (:monId, 
            (SELECT id FROM CharacterData WHERE charaIndex = :stage AND cardId = :dimId),
            (SELECT id FROM CardCharacter WHERE charaIndex = :stage AND cardId = :dimId),
            :transformationDate)
    """
    )


@@ 195,7 195,7 @@ interface UserCharacterDao {
            d.isBEm as isBemCard,
            a.characterId = uc.id as isInAdventure
        FROM UserCharacter uc
        JOIN CharacterData c ON uc.charId = c.id
        JOIN CardCharacter c ON uc.charId = c.id
        JOIN Card d ON  d.id = c.cardId
        JOIN Sprite s ON s.id = c.spriteId
        LEFT JOIN Adventure a ON a.characterId = uc.id


@@ 220,7 220,7 @@ interface UserCharacterDao {
            d.isBEm as isBemCard,
            a.characterId = uc.id as isInAdventure
        FROM UserCharacter uc
        JOIN CharacterData c ON uc.charId = c.id
        JOIN CardCharacter c ON uc.charId = c.id
        JOIN Card d ON  d.id = c.cardId
        JOIN Sprite s ON s.id = c.spriteId
        LEFT JOIN Adventure a ON a.characterId = uc.id

M app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt => app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt +10 -2
@@ 3,17 3,21 @@ package com.github.nacabaro.vbhelper.database
import androidx.room.Database
import androidx.room.RoomDatabase
import com.github.nacabaro.vbhelper.daos.AdventureDao
import com.github.nacabaro.vbhelper.daos.CardAdventureDao
import com.github.nacabaro.vbhelper.daos.CharacterDao
import com.github.nacabaro.vbhelper.daos.DexDao
import com.github.nacabaro.vbhelper.daos.CardDao
import com.github.nacabaro.vbhelper.daos.CardFusionsDao
import com.github.nacabaro.vbhelper.daos.CardProgressDao
import com.github.nacabaro.vbhelper.daos.ItemDao
import com.github.nacabaro.vbhelper.daos.SpecialMissionDao
import com.github.nacabaro.vbhelper.daos.SpriteDao
import com.github.nacabaro.vbhelper.daos.UserCharacterDao
import com.github.nacabaro.vbhelper.domain.card.Background
import com.github.nacabaro.vbhelper.domain.card.CharacterData
import com.github.nacabaro.vbhelper.domain.card.CardCharacter
import com.github.nacabaro.vbhelper.domain.card.Card
import com.github.nacabaro.vbhelper.domain.card.CardAdventure
import com.github.nacabaro.vbhelper.domain.card.CardFusions
import com.github.nacabaro.vbhelper.domain.card.CardProgress
import com.github.nacabaro.vbhelper.domain.card.PossibleTransformations
import com.github.nacabaro.vbhelper.domain.characters.Sprite


@@ 32,7 36,9 @@ import com.github.nacabaro.vbhelper.domain.items.Items
    entities = [
        Card::class,
        CardProgress::class,
        CharacterData::class,
        CardCharacter::class,
        CardAdventure::class,
        CardFusions::class,
        Sprite::class,
        UserCharacter::class,
        BECharacterData::class,


@@ 57,4 63,6 @@ abstract class AppDatabase : RoomDatabase() {
    abstract fun adventureDao(): AdventureDao
    abstract fun spriteDao(): SpriteDao
    abstract fun specialMissionDao(): SpecialMissionDao
    abstract fun cardAdventureDao(): CardAdventureDao
    abstract fun cardFusionsDao(): CardFusionsDao
}
\ No newline at end of file

A app/src/main/java/com/github/nacabaro/vbhelper/domain/card/CardAdventure.kt => app/src/main/java/com/github/nacabaro/vbhelper/domain/card/CardAdventure.kt +32 -0
@@ 0,0 1,32 @@
package com.github.nacabaro.vbhelper.domain.card

import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.PrimaryKey

@Entity(
    foreignKeys = [
        ForeignKey(
            entity = CardCharacter::class,
            parentColumns = ["id"],
            childColumns = ["characterId"],
            onDelete = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = Card::class,
            parentColumns = ["id"],
            childColumns = ["cardId"],
            onDelete = ForeignKey.CASCADE
        )
    ]
)
data class CardAdventure(
    @PrimaryKey(autoGenerate = true) val id: Long = 0,
    val cardId: Long,
    val characterId: Long,
    val steps: Int,
    val bossHp: Int,
    val bossAp: Int,
    val bossDp: Int,
    val bossBp: Int?
)
\ No newline at end of file

R app/src/main/java/com/github/nacabaro/vbhelper/domain/card/CharacterData.kt => app/src/main/java/com/github/nacabaro/vbhelper/domain/card/CardCharacter.kt +1 -1
@@ 28,7 28,7 @@ import com.github.nacabaro.vbhelper.domain.characters.Sprite
 * and monIndex.
 * TODO: Customs will mean this should be unique per cardName and monIndex
 */
data class CharacterData (
data class CardCharacter (
    @PrimaryKey(autoGenerate = true) val id: Long = 0,
    val cardId: Long,
    val spriteId: Long,

A app/src/main/java/com/github/nacabaro/vbhelper/domain/card/CardFusions.kt => app/src/main/java/com/github/nacabaro/vbhelper/domain/card/CardFusions.kt +48 -0
@@ 0,0 1,48 @@
package com.github.nacabaro.vbhelper.domain.card

import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.PrimaryKey

@Entity(
    foreignKeys = [
        ForeignKey(
            entity = CardCharacter::class,
            parentColumns = ["id"],
            childColumns = ["fromCharaId"],
            onDelete = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = CardCharacter::class,
            parentColumns = ["id"],
            childColumns = ["attribute1Fusion"],
            onDelete = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = CardCharacter::class,
            parentColumns = ["id"],
            childColumns = ["attribute2Fusion"],
            onDelete = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = CardCharacter::class,
            parentColumns = ["id"],
            childColumns = ["attribute3Fusion"],
            onDelete = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = CardCharacter::class,
            parentColumns = ["id"],
            childColumns = ["attribute4Fusion"],
            onDelete = ForeignKey.CASCADE
        )
    ]
)
data class CardFusions(
    @PrimaryKey(autoGenerate = true) val id: Long,
    val fromCharaId: Long,
    val attribute1Fusion: Long?,
    val attribute2Fusion: Long?,
    val attribute3Fusion: Long?,
    val attribute4Fusion: Long?
)
\ No newline at end of file

M app/src/main/java/com/github/nacabaro/vbhelper/domain/card/PossibleTransformations.kt => app/src/main/java/com/github/nacabaro/vbhelper/domain/card/PossibleTransformations.kt +2 -2
@@ 7,13 7,13 @@ import androidx.room.PrimaryKey
@Entity(
    foreignKeys = [
        ForeignKey(
            entity = CharacterData::class,
            entity = CardCharacter::class,
            parentColumns = ["id"],
            childColumns = ["charaId"],
            onDelete = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = CharacterData::class,
            entity = CardCharacter::class,
            parentColumns = ["id"],
            childColumns = ["toCharaId"],
            onDelete = ForeignKey.CASCADE

M app/src/main/java/com/github/nacabaro/vbhelper/domain/characters/Dex.kt => app/src/main/java/com/github/nacabaro/vbhelper/domain/characters/Dex.kt +2 -2
@@ 3,12 3,12 @@ package com.github.nacabaro.vbhelper.domain.characters
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.PrimaryKey
import com.github.nacabaro.vbhelper.domain.card.CharacterData
import com.github.nacabaro.vbhelper.domain.card.CardCharacter

@Entity(
    foreignKeys = [
        ForeignKey(
            entity = CharacterData::class,
            entity = CardCharacter::class,
            parentColumns = ["id"],
            childColumns = ["id"],
            onDelete = ForeignKey.CASCADE

M app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/TransformationHistory.kt => app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/TransformationHistory.kt +2 -2
@@ 3,7 3,7 @@ package com.github.nacabaro.vbhelper.domain.device_data
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.PrimaryKey
import com.github.nacabaro.vbhelper.domain.card.CharacterData
import com.github.nacabaro.vbhelper.domain.card.CardCharacter

@Entity(
    foreignKeys = [


@@ 14,7 14,7 @@ import com.github.nacabaro.vbhelper.domain.card.CharacterData
            onDelete = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = CharacterData::class,
            entity = CardCharacter::class,
            parentColumns = ["id"],
            childColumns = ["stageId"],
            onDelete = ForeignKey.CASCADE

M app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/UserCharacter.kt => app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/UserCharacter.kt +2 -2
@@ 5,12 5,12 @@ import androidx.room.ForeignKey
import androidx.room.PrimaryKey
import com.github.cfogrady.vbnfc.data.NfcCharacter
import com.github.nacabaro.vbhelper.utils.DeviceType
import com.github.nacabaro.vbhelper.domain.card.CharacterData
import com.github.nacabaro.vbhelper.domain.card.CardCharacter

@Entity(
    foreignKeys = [
        ForeignKey(
            entity = CharacterData::class,
            entity = CardCharacter::class,
            parentColumns = ["id"],
            childColumns = ["charId"],
            onDelete = ForeignKey.CASCADE

M app/src/main/java/com/github/nacabaro/vbhelper/dtos/CardDtos.kt => app/src/main/java/com/github/nacabaro/vbhelper/dtos/CardDtos.kt +14 -0
@@ 10,4 10,18 @@ object CardDtos {
        val totalCharacters: Int,
        val obtainedCharacters: Int,
    )

    data class CardAdventureWithSprites (
        val characterName: ByteArray,
        val characterNameWidth: Int,
        val characterNameHeight: Int,
        val characterIdleSprite: ByteArray,
        val characterIdleSpriteWidth: Int,
        val characterIdleSpriteHeight: Int,
        val characterAp: Int,
        val characterBp: Int?,
        val characterDp: Int,
        val characterHp: Int,
        val steps: Int,
    )
}
\ No newline at end of file

M app/src/main/java/com/github/nacabaro/vbhelper/dtos/CharacterDtos.kt => app/src/main/java/com/github/nacabaro/vbhelper/dtos/CharacterDtos.kt +1 -1
@@ 35,7 35,7 @@ object CharacterDtos {
    )

    data class CardCharacterInfo(
        val cardId: Int,
        val cardId: Long,
        val charId: Int,
        val stage: Int,
        val attribute: NfcCharacter.Attribute

M app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt => app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt +13 -1
@@ 34,6 34,7 @@ import com.github.nacabaro.vbhelper.screens.itemsScreen.ItemsScreenControllerImp
import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreenControllerImpl
import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreen
import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreenControllerImpl
import com.github.nacabaro.vbhelper.screens.cardScreen.CardAdventureScreen
import com.github.nacabaro.vbhelper.screens.cardScreen.CardScreenControllerImpl
import com.github.nacabaro.vbhelper.screens.settingsScreen.CreditsScreen
import com.github.nacabaro.vbhelper.screens.spriteViewer.SpriteViewerControllerImpl


@@ 145,7 146,7 @@ fun AppNavigation(
                if (cardId != null) {
                    CardViewScreen(
                        navController = navController,
                        dimId = cardId.toLong()
                        cardId = cardId.toLong()
                    )
                }
            }


@@ 177,6 178,17 @@ fun AppNavigation(
                    navController = navController
                )
            }
            composable(NavigationItems.CardAdventure.route) {
                val cardId = it.arguments?.getString("cardId")
                if (cardId != null) {
                    CardAdventureScreen(
                        navController = navController,
                        cardId = cardId.toLong(),
                        cardScreenController = applicationNavigationHandlers
                            .cardScreenController
                    )
                }
            }
        }
    }
}

M app/src/main/java/com/github/nacabaro/vbhelper/navigation/NavigationItems.kt => app/src/main/java/com/github/nacabaro/vbhelper/navigation/NavigationItems.kt +1 -0
@@ 11,6 11,7 @@ sealed class NavigationItems (
    object Battles : NavigationItems("Battle", R.drawable.baseline_swords_24, "Battle")
    object Home : NavigationItems("Home", R.drawable.baseline_cottage_24, "Home")
    object Dex : NavigationItems("Dex", R.drawable.baseline_menu_book_24, "Dex")
    object CardAdventure : NavigationItems("CardAdventure/{cardId}", R.drawable.baseline_fort_24, "Card adventure")
    object Storage : NavigationItems("Storage", R.drawable.baseline_catching_pokemon_24, "Storage")
    object Settings : NavigationItems("Settings", R.drawable.baseline_settings_24, "Settings")
    object Viewer : NavigationItems("Viewer", R.drawable.baseline_image_24, "Viewer")

A app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardAdventureEntry.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardAdventureEntry.kt +122 -0
@@ 0,0 1,122 @@
package com.github.nacabaro.vbhelper.screens.cardScreen

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Card
import androidx.compose.material3.CardColors
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.FilterQuality
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import com.github.nacabaro.vbhelper.dtos.CardDtos
import com.github.nacabaro.vbhelper.utils.BitmapData
import com.github.nacabaro.vbhelper.utils.getImageBitmap

@Composable
fun CardAdventureEntry(
    cardAdventureEntry: CardDtos.CardAdventureWithSprites,
    obscure: Boolean
) {
    val charaImageBitmapData = BitmapData(
        bitmap = cardAdventureEntry.characterIdleSprite,
        width = cardAdventureEntry.characterIdleSpriteWidth,
        height = cardAdventureEntry.characterIdleSpriteHeight
    ).getImageBitmap(
        context = LocalContext.current,
        multiplier = 4,
        obscure = obscure
    )

    val nameImageBitmapData = BitmapData(
        bitmap = cardAdventureEntry.characterName,
        width = cardAdventureEntry.characterNameWidth,
        height = cardAdventureEntry.characterNameHeight
    ).getImageBitmap(
        context = LocalContext.current,
        multiplier = 3,
        obscure = obscure
    )

    Card (
        modifier = Modifier
            .fillMaxWidth()
            .padding(8.dp)
    ) {
        Row (
            modifier = Modifier
                .padding(8.dp)
        ){
            Card (
                colors = CardColors(
                    containerColor = MaterialTheme.colorScheme.surfaceVariant,
                    contentColor = MaterialTheme.colorScheme.contentColorFor(
                        backgroundColor = MaterialTheme.colorScheme.surfaceVariant,
                    ),
                    disabledContainerColor = MaterialTheme.colorScheme.surfaceVariant,
                    disabledContentColor = MaterialTheme.colorScheme.contentColorFor(
                        backgroundColor = MaterialTheme.colorScheme.surfaceVariant,
                    )
                )
            ) {
                Image(
                    bitmap = charaImageBitmapData.imageBitmap,
                    contentDescription = "Icon",
                    modifier = Modifier
                        .size(charaImageBitmapData.dpWidth)
                        .padding(8.dp),
                    colorFilter = when (obscure) {
                        true -> ColorFilter.tint(color = MaterialTheme.colorScheme.secondary)
                        false -> null
                    },
                    filterQuality = FilterQuality.None
                )
            }

            Spacer(modifier = Modifier.padding(8.dp))

            Column {
                if (!obscure) {
                    Image(
                        bitmap = nameImageBitmapData.imageBitmap,
                        contentDescription = "Icon",
                        modifier = Modifier
                            .width(nameImageBitmapData.dpWidth)
                            .height(nameImageBitmapData.dpHeight),
                        filterQuality = FilterQuality.None
                    )

                    Spacer(modifier = Modifier.padding(4.dp))

                    Text(
                        text = "HP: ${cardAdventureEntry.characterHp}, DP: ${cardAdventureEntry.characterDp}, AP: ${cardAdventureEntry.characterAp}"
                    )
                    if (cardAdventureEntry.characterBp != null) {
                        Text(text = "BP: ${cardAdventureEntry.characterBp}")
                    }
                    Text(text = "Steps: ${cardAdventureEntry.steps}")
                } else {
                    Text(text = "????????????????")
                    Text(
                        text = "HP: -, BP: -, AP: -"
                    )
                    if (cardAdventureEntry.characterBp != null) {
                        Text(text = "DP: -")
                    }
                    Text(text = "Steps: -")
                }
            }
        }
    }
}
\ No newline at end of file

A app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardAdventureScreen.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardAdventureScreen.kt +63 -0
@@ 0,0 1,63 @@
package com.github.nacabaro.vbhelper.screens.cardScreen

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.navigation.NavController
import com.github.nacabaro.vbhelper.components.TopBanner
import com.github.nacabaro.vbhelper.dtos.CardDtos
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

@Composable
fun CardAdventureScreen(
    navController: NavController,
    cardScreenController: CardScreenControllerImpl,
    cardId: Long
) {
    val cardAdventureMissions = remember { mutableStateOf(emptyList<CardDtos.CardAdventureWithSprites>()) }
    var currentCardAdventure = remember { 0 }

    LaunchedEffect(cardId) {
        withContext(Dispatchers.IO) {
            cardAdventureMissions.value =
                cardScreenController
                    .getCardAdventureMissions(cardId)

            currentCardAdventure =
                cardScreenController
                    .getCardProgress(cardId)
        }
    }

    Scaffold (
        topBar = {
            TopBanner(
                text = "Adventure missions",
                onBackClick = {
                    navController.popBackStack()
                }
            )
        }
    ) { contentPadding ->
        Column (
            modifier = Modifier
                .padding(top = contentPadding.calculateTopPadding())
                .verticalScroll(state = rememberScrollState())
        ) {
            cardAdventureMissions.value.mapIndexed { index, it ->
                CardAdventureEntry(
                    cardAdventureEntry = it,
                    obscure = index > currentCardAdventure
                )
            }
        }
    }
}
\ No newline at end of file

M app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardScreenController.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardScreenController.kt +4 -0
@@ 1,6 1,10 @@
package com.github.nacabaro.vbhelper.screens.cardScreen

import com.github.nacabaro.vbhelper.dtos.CardDtos

interface CardScreenController {
    fun renameCard(cardId: Long, newName: String, onRenamed: (String) -> Unit)
    fun deleteCard(cardId: Long, onDeleted: () -> Unit)
    suspend fun getCardAdventureMissions(cardId: Long): List<CardDtos.CardAdventureWithSprites>
    suspend fun getCardProgress(cardId: Long): Int
}
\ No newline at end of file

M app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardScreenControllerImpl.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardScreenControllerImpl.kt +13 -1
@@ 3,6 3,7 @@ package com.github.nacabaro.vbhelper.screens.cardScreen
import androidx.activity.ComponentActivity
import androidx.lifecycle.lifecycleScope
import com.github.nacabaro.vbhelper.di.VBHelper
import com.github.nacabaro.vbhelper.dtos.CardDtos
import kotlinx.coroutines.launch

class CardScreenControllerImpl(


@@ 11,7 12,6 @@ class CardScreenControllerImpl(
    private val application = componentActivity.applicationContext as VBHelper
    private val database = application.container.db


    override fun renameCard(cardId: Long, newName: String, onRenamed: (String) -> Unit) {
        componentActivity.lifecycleScope.launch {
            database


@@ 31,4 31,16 @@ class CardScreenControllerImpl(
            onDeleted()
        }
    }

    override suspend fun getCardAdventureMissions(cardId: Long): List<CardDtos.CardAdventureWithSprites> {
        return database
            .cardAdventureDao()
            .getAdventureForCard(cardId)
    }

    override suspend fun getCardProgress(cardId: Long): Int {
        return database
            .cardProgressDao()
            .getCardProgress(cardId)
    }
}
\ No newline at end of file

M app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardViewScreen.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/cardScreen/CardViewScreen.kt +15 -3
@@ 16,6 16,7 @@ import com.github.nacabaro.vbhelper.components.CharacterEntry
import com.github.nacabaro.vbhelper.components.TopBanner
import com.github.nacabaro.vbhelper.di.VBHelper
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
import com.github.nacabaro.vbhelper.navigation.NavigationItems
import com.github.nacabaro.vbhelper.screens.cardScreen.dialogs.DexCharaDetailsDialog
import com.github.nacabaro.vbhelper.source.DexRepository
import kotlinx.coroutines.launch


@@ 23,7 24,7 @@ import kotlinx.coroutines.launch
@Composable
fun CardViewScreen(
    navController: NavController,
    dimId: Long
    cardId: Long
) {
    val coroutineScope = rememberCoroutineScope()
    val application = LocalContext.current.applicationContext as VBHelper


@@ 36,10 37,10 @@ fun CardViewScreen(

    LaunchedEffect(dexRepository) {
        coroutineScope.launch {
            val newCharacterList = dexRepository.getCharactersByCardId(dimId)
            val newCharacterList = dexRepository.getCharactersByCardId(cardId)
            characterList.value = newCharacterList

            val newCardPossibleTransformations = dexRepository.getCardPossibleTransformations(dimId)
            val newCardPossibleTransformations = dexRepository.getCardPossibleTransformations(cardId)
            cardPossibleTransformations.value = newCardPossibleTransformations
        }
    }


@@ 50,6 51,17 @@ fun CardViewScreen(
                text = "Discovered characters",
                onBackClick = {
                    navController.popBackStack()
                },
                onAdventureClick = {
                    navController
                        .navigate(route = NavigationItems
                            .CardAdventure
                            .route
                            .replace(
                                "{cardId}",
                                cardId.toString()
                            )
                        )
                }
            )
        }

M app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt +67 -3
@@ 18,7 18,7 @@ import com.github.nacabaro.vbhelper.di.VBHelper
import com.github.nacabaro.vbhelper.domain.characters.Sprite
import com.github.nacabaro.vbhelper.domain.card.Card
import com.github.nacabaro.vbhelper.domain.card.CardProgress
import com.github.nacabaro.vbhelper.domain.card.CharacterData
import com.github.nacabaro.vbhelper.domain.card.CardCharacter
import com.github.nacabaro.vbhelper.source.ApkSecretsImporter
import com.github.nacabaro.vbhelper.source.SecretsImporter
import com.github.nacabaro.vbhelper.source.SecretsRepository


@@ 192,7 192,7 @@ class SettingsScreenControllerImpl(
            false -> 10
        }

        val domainCharacters = mutableListOf<CharacterData>()
        val domainCharacters = mutableListOf<CardCharacter>()

        val characters = card
            .characterStats


@@ 242,7 242,7 @@ class SettingsScreenControllerImpl(


            domainCharacters.add(
                CharacterData(
                CardCharacter(
                    cardId = cardId,
                    spriteId = spriteId,
                    charaIndex = index,


@@ 273,6 273,66 @@ class SettingsScreenControllerImpl(
            .insertCharacter(*domainCharacters.toTypedArray())
    }

    private suspend fun importAdventureMissions(
        cardId: Long,
        card: com.github.cfogrady.vb.dim.card.Card<*, *, *, *, *, *>
    ) {
        Log.d("importAdventureMissions", "Importing adventure missions")
        if (card is BemCard) {
            card.adventureLevels.levels.forEach {
                database
                    .cardAdventureDao()
                    .insertNewAdventure(
                        cardId = cardId,
                        characterId = it.bossCharacterIndex,
                        steps = it.steps,
                        bossAp = it.bossAp,
                        bossHp = it.bossHp,
                        bossDp = it.bossDp,
                        bossBp = it.bossBp
                    )
            }
        } else if (card is DimCard) {
            card.adventureLevels.levels.map {
                database
                    .cardAdventureDao()
                    .insertNewAdventure(
                        cardId = cardId,
                        characterId = it.bossCharacterIndex,
                        steps = it.steps,
                        bossAp = it.bossAp,
                        bossHp = it.bossHp,
                        bossDp = it.bossDp,
                        bossBp = null
                    )
            }
        }
    }

    private suspend fun importCardFusions(
        cardId: Long,
        card: com.github.cfogrady.vb.dim.card.Card<*, *, *, *, *, *>
    ) {
        Log.d("importCardFusions", "Importing card fusions")
        if (card is DimCard) {
            card
                .attributeFusions
                .entries
                .forEach {
                    database
                        .cardFusionsDao()
                        .insertNewFusion(
                            cardId = cardId,
                            fromCharaId = it.characterIndex,
                            toCharaIdAttr1 = it.attribute1Fusion,
                            toCharaIdAttr2 = it.attribute2Fusion,
                            toCharaIdAttr3 = it.attribute3Fusion,
                            toCharaIdAttr4 = it.attribute4Fusion
                        )
                }
        }
    }

    private fun updateCardProgress(
        cardId: Long,
    ) {


@@ 315,6 375,10 @@ class SettingsScreenControllerImpl(
                importCharacterData(cardId, card)

                importEvoData(cardId, card)

                importAdventureMissions(cardId, card)

                importCardFusions(cardId, card)
            }

            inputStream?.close()