Adventure Missions progress

- Viewing the adventure missions completed in a card is now possible.
This commit is contained in:
Nacho 2025-09-10 02:09:15 +02:00
parent cb9fe8e716
commit 7160eb792a
27 changed files with 528 additions and 46 deletions

View File

@ -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"
}

View File

@ -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

View File

@ -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>
}

View File

@ -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
"""

View File

@ -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
)
}

View File

@ -13,5 +13,5 @@ interface CardProgressDao {
@Query(
"SELECT currentStage FROM CardProgress WHERE cardId = :cardId"
)
fun getCardProgress(cardId: Int): Int
fun getCardProgress(cardId: Long): Int
}

View File

@ -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

View File

@ -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
"""
)

View File

@ -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

View File

@ -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
}

View File

@ -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?
)

View File

@ -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,

View File

@ -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?
)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,
)
}

View File

@ -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

View File

@ -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
)
}
}
}
}
}

View File

@ -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")

View File

@ -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: -")
}
}
}
}
}

View File

@ -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
)
}
}
}
}

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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()
)
)
}
)
}

View File

@ -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()