mirror of
https://github.com/nacabaro/vbhelper.git
synced 2026-09-30 23:21:36 +00:00
Compare commits
53
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd76c46f39 | ||
|
|
e85e1f45bf | ||
|
|
630cccefe4 | ||
|
|
7160eb792a | ||
|
|
cb9fe8e716 | ||
|
|
540766eefb | ||
|
|
af2c852bac | ||
|
|
8dc5bbbdde | ||
|
|
aac05a3b1c | ||
|
|
b827fdccbe | ||
|
|
2586190e5c | ||
|
|
1a6753d2aa | ||
|
|
f8ec899335 | ||
|
|
b95edfa2a1 | ||
|
|
1a570170ca | ||
|
|
1566876106 | ||
|
|
019f07d827 | ||
|
|
4474e6689d | ||
|
|
fb09004d13 | ||
|
|
dd1a62d184 | ||
|
|
f96f00e05a | ||
|
|
3c17e93d0f | ||
|
|
f8ce81e932 | ||
|
|
7bb7693876 | ||
|
|
2b33042fe0 | ||
|
|
4d8dcde26e | ||
|
|
0b1eed7da9 | ||
|
|
36c3e25fd3 | ||
|
|
ac05dfc541 | ||
|
|
220a61a553 | ||
|
|
d847f600f1 | ||
|
|
f7a4039d66 | ||
|
|
1eed6a4c17 | ||
|
|
1a09e40d1d | ||
|
|
13051145b7 | ||
|
|
1a150ce7ce | ||
|
|
39ba48d867 | ||
|
|
3f324ca141 | ||
|
|
1e28a8c249 | ||
|
|
d46769b0cb | ||
|
|
fce05870c5 | ||
|
|
9f5f806786 | ||
|
|
d749af0a9c | ||
|
|
076f6bfacf | ||
|
|
a4f3b701e5 | ||
|
|
da134247b1 | ||
|
|
f7b3b7256a | ||
|
|
e36a700d9f | ||
|
|
fb6b6d2825 | ||
|
|
e17f6c23e4 | ||
|
|
409474b5d1 | ||
|
|
547318864b | ||
|
|
1a38cefb92 |
@@ -15,7 +15,7 @@ android {
|
||||
minSdk = 28
|
||||
targetSdk = 35
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
versionName = "Alpha 0.6.1"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
@@ -9,9 +9,14 @@ import androidx.compose.runtime.Composable
|
||||
import com.github.nacabaro.vbhelper.navigation.AppNavigation
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.navigation.AppNavigationHandlers
|
||||
import com.github.nacabaro.vbhelper.screens.homeScreens.HomeScreenControllerImpl
|
||||
import com.github.nacabaro.vbhelper.screens.itemsScreen.ItemsScreenControllerImpl
|
||||
import com.github.nacabaro.vbhelper.screens.scanScreen.ScanScreenControllerImpl
|
||||
import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreenControllerImpl
|
||||
import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreenControllerImpl
|
||||
import com.github.nacabaro.vbhelper.screens.cardScreen.CardScreenControllerImpl
|
||||
import com.github.nacabaro.vbhelper.screens.spriteViewer.SpriteViewerControllerImpl
|
||||
import com.github.nacabaro.vbhelper.screens.storageScreen.StorageScreenControllerImpl
|
||||
import com.github.nacabaro.vbhelper.ui.theme.VBHelperTheme
|
||||
|
||||
|
||||
@@ -39,6 +44,11 @@ class MainActivity : ComponentActivity() {
|
||||
)
|
||||
val settingsScreenController = SettingsScreenControllerImpl(this)
|
||||
val itemsScreenController = ItemsScreenControllerImpl(this)
|
||||
val adventureScreenController = AdventureScreenControllerImpl(this)
|
||||
val storageScreenController = StorageScreenControllerImpl(this)
|
||||
val homeScreenController = HomeScreenControllerImpl(this)
|
||||
val spriteViewerController = SpriteViewerControllerImpl(this)
|
||||
val cardScreenController = CardScreenControllerImpl(this)
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
@@ -49,7 +59,12 @@ class MainActivity : ComponentActivity() {
|
||||
MainApplication(
|
||||
scanScreenController = scanScreenController,
|
||||
settingsScreenController = settingsScreenController,
|
||||
itemsScreenController = itemsScreenController
|
||||
itemsScreenController = itemsScreenController,
|
||||
adventureScreenController = adventureScreenController,
|
||||
homeScreenController = homeScreenController,
|
||||
storageScreenController = storageScreenController,
|
||||
spriteViewerController = spriteViewerController,
|
||||
cardScreenController = cardScreenController
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -77,13 +92,23 @@ class MainActivity : ComponentActivity() {
|
||||
private fun MainApplication(
|
||||
scanScreenController: ScanScreenControllerImpl,
|
||||
settingsScreenController: SettingsScreenControllerImpl,
|
||||
itemsScreenController: ItemsScreenControllerImpl
|
||||
itemsScreenController: ItemsScreenControllerImpl,
|
||||
adventureScreenController: AdventureScreenControllerImpl,
|
||||
storageScreenController: StorageScreenControllerImpl,
|
||||
homeScreenController: HomeScreenControllerImpl,
|
||||
spriteViewerController: SpriteViewerControllerImpl,
|
||||
cardScreenController: CardScreenControllerImpl
|
||||
) {
|
||||
AppNavigation(
|
||||
applicationNavigationHandlers = AppNavigationHandlers(
|
||||
settingsScreenController,
|
||||
scanScreenController,
|
||||
itemsScreenController
|
||||
itemsScreenController,
|
||||
adventureScreenController,
|
||||
storageScreenController,
|
||||
homeScreenController,
|
||||
spriteViewerController,
|
||||
cardScreenController
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,11 +5,14 @@ import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
@@ -28,6 +31,9 @@ import com.github.nacabaro.vbhelper.utils.getBitmap
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import com.github.cfogrady.vbnfc.vb.SpecialMission
|
||||
import com.github.nacabaro.vbhelper.R
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions
|
||||
import com.github.nacabaro.vbhelper.utils.getObscuredBitmap
|
||||
|
||||
@Composable
|
||||
@@ -35,6 +41,7 @@ fun CharacterEntry(
|
||||
icon: BitmapData,
|
||||
modifier: Modifier = Modifier,
|
||||
obscure: Boolean = false,
|
||||
disabled: Boolean = false,
|
||||
shape: Shape = MaterialTheme.shapes.medium,
|
||||
multiplier: Int = 4,
|
||||
onClick: () -> Unit = { }
|
||||
@@ -48,7 +55,10 @@ fun CharacterEntry(
|
||||
|
||||
Card(
|
||||
shape = shape,
|
||||
onClick = onClick,
|
||||
onClick = when (disabled) {
|
||||
true -> { {} }
|
||||
false -> onClick
|
||||
},
|
||||
modifier = modifier
|
||||
.aspectRatio(1f)
|
||||
.padding(8.dp)
|
||||
@@ -110,4 +120,90 @@ fun ItemDisplay(
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SpecialMissionsEntry(
|
||||
specialMission: SpecialMissions,
|
||||
modifier: Modifier = Modifier,
|
||||
onClickCard: () -> Unit = { },
|
||||
) {
|
||||
val textValue = when (specialMission.missionType) {
|
||||
SpecialMission.Type.NONE -> "No mission selected"
|
||||
SpecialMission.Type.STEPS -> "Walk ${specialMission.goal} steps"
|
||||
SpecialMission.Type.BATTLES -> "Battle ${specialMission.goal} times"
|
||||
SpecialMission.Type.WINS -> "Win ${specialMission.goal} battles"
|
||||
SpecialMission.Type.VITALS -> "Earn ${specialMission.goal} vitals"
|
||||
}
|
||||
|
||||
val progress = if (specialMission.status == SpecialMission.Status.COMPLETED) {
|
||||
specialMission.goal
|
||||
} else {
|
||||
specialMission.progress
|
||||
}
|
||||
|
||||
val completion = when (specialMission.missionType) {
|
||||
SpecialMission.Type.NONE -> ""
|
||||
SpecialMission.Type.STEPS -> "Walked $progress steps"
|
||||
SpecialMission.Type.BATTLES -> "Battled $progress times"
|
||||
SpecialMission.Type.WINS -> "Won $progress battles"
|
||||
SpecialMission.Type.VITALS -> "Earned $progress vitals"
|
||||
}
|
||||
|
||||
val icon = when (specialMission.missionType) {
|
||||
SpecialMission.Type.NONE -> R.drawable.baseline_free_24
|
||||
SpecialMission.Type.STEPS -> R.drawable.baseline_agility_24
|
||||
SpecialMission.Type.BATTLES -> R.drawable.baseline_swords_24
|
||||
SpecialMission.Type.WINS -> R.drawable.baseline_trophy_24
|
||||
SpecialMission.Type.VITALS -> R.drawable.baseline_vitals_24
|
||||
}
|
||||
|
||||
val color = when (specialMission.status)
|
||||
{
|
||||
SpecialMission.Status.IN_PROGRESS -> MaterialTheme.colorScheme.secondary
|
||||
SpecialMission.Status.COMPLETED -> MaterialTheme.colorScheme.primary
|
||||
SpecialMission.Status.FAILED -> MaterialTheme.colorScheme.error
|
||||
else -> MaterialTheme.colorScheme.surfaceContainerHighest
|
||||
}
|
||||
|
||||
Card(
|
||||
modifier = modifier,
|
||||
shape = androidx.compose.material.MaterialTheme.shapes.small,
|
||||
onClick = if (specialMission.status == SpecialMission.Status.COMPLETED || specialMission.status == SpecialMission.Status.FAILED) {
|
||||
onClickCard
|
||||
} else {
|
||||
{ }
|
||||
},
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = color
|
||||
)
|
||||
|
||||
) {
|
||||
Row (
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(icon),
|
||||
contentDescription = "Vitals",
|
||||
modifier = Modifier
|
||||
.fillMaxHeight()
|
||||
.padding(16.dp)
|
||||
)
|
||||
Column {
|
||||
Text(
|
||||
text = textValue,
|
||||
fontFamily = MaterialTheme.typography.titleLarge.fontFamily,
|
||||
fontWeight = FontWeight.Bold,
|
||||
)
|
||||
Text(
|
||||
text = completion,
|
||||
fontFamily = MaterialTheme.typography.titleSmall.fontFamily,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,9 @@ fun TopBanner(
|
||||
modifier: Modifier = Modifier,
|
||||
onGearClick: (() -> Unit)? = null,
|
||||
onBackClick: (() -> Unit)? = null,
|
||||
onScanClick: (() -> Unit)? = null
|
||||
onScanClick: (() -> Unit)? = null,
|
||||
onAdventureClick: (() -> Unit)? = null,
|
||||
onModifyClick: (() -> Unit)? = null
|
||||
) {
|
||||
Box( // Use Box to overlay elements
|
||||
modifier = modifier
|
||||
@@ -36,29 +38,51 @@ fun TopBanner(
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = 24.sp,
|
||||
modifier = Modifier
|
||||
.align(Alignment.Center) // Center the text
|
||||
.align(Alignment.Center)
|
||||
)
|
||||
if (onGearClick != null) {
|
||||
IconButton(
|
||||
onClick = onGearClick,
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterEnd) // Place gear icon at the end
|
||||
.align(Alignment.CenterEnd)
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.baseline_settings_24), // Use a gear icon
|
||||
painter = painterResource(R.drawable.baseline_settings_24),
|
||||
contentDescription = "Settings"
|
||||
)
|
||||
}
|
||||
}
|
||||
} else if (onAdventureClick != null) {
|
||||
IconButton(
|
||||
onClick = onAdventureClick,
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterEnd)
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.baseline_fort_24),
|
||||
contentDescription = "Adventure"
|
||||
)
|
||||
}
|
||||
} else if (onModifyClick != null) {
|
||||
IconButton(
|
||||
onClick = onModifyClick,
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterEnd)
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.baseline_edit_24),
|
||||
contentDescription = "Adventure"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (onScanClick != null) {
|
||||
IconButton(
|
||||
onClick = onScanClick,
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterStart) // Place gear icon at the end
|
||||
.align(Alignment.CenterStart)
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.baseline_nfc_24), // Use a gear icon
|
||||
painter = painterResource(R.drawable.baseline_nfc_24),
|
||||
contentDescription = "Scan"
|
||||
)
|
||||
}
|
||||
@@ -66,10 +90,10 @@ fun TopBanner(
|
||||
IconButton(
|
||||
onClick = onBackClick,
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterStart) // Place gear icon at the end
|
||||
.align(Alignment.CenterStart)
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.baseline_arrow_back_24), // Use a gear icon
|
||||
painter = painterResource(R.drawable.baseline_arrow_back_24),
|
||||
contentDescription = "Settings"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.github.nacabaro.vbhelper.daos
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
|
||||
|
||||
@Dao
|
||||
interface AdventureDao {
|
||||
@Query("""
|
||||
INSERT INTO Adventure (characterId, originalDuration, finishesAdventure)
|
||||
VALUES (:characterId, :originalDuration, strftime('%s', 'now') + :timeInSeconds)
|
||||
""")
|
||||
fun insertNewAdventure(characterId: Long, originalDuration: Long, timeInSeconds: Long)
|
||||
|
||||
@Query("""
|
||||
SELECT COUNT(*) FROM Adventure
|
||||
""")
|
||||
fun getAdventureCount(): Int
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT
|
||||
uc.*,
|
||||
c.stage,
|
||||
c.attribute,
|
||||
s.spriteIdle1 AS spriteIdle,
|
||||
s.width AS spriteWidth,
|
||||
s.height AS spriteHeight,
|
||||
d.isBEm as isBemCard,
|
||||
a.finishesAdventure AS finishesAdventure,
|
||||
a.originalDuration AS originalTimeInMinutes
|
||||
FROM UserCharacter uc
|
||||
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
|
||||
"""
|
||||
)
|
||||
suspend fun getAdventureCharacters(): List<CharacterDtos.AdventureCharacterWithSprites>
|
||||
|
||||
@Query("""
|
||||
DELETE FROM Adventure
|
||||
WHERE characterId = :characterId
|
||||
""")
|
||||
suspend fun deleteAdventure(characterId: Long)
|
||||
}
|
||||
@@ -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>
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
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.CardBackground
|
||||
|
||||
@Dao
|
||||
interface CardBackgroundDao {
|
||||
@Insert
|
||||
suspend fun insertCardBackground(vararg cardBackground: CardBackground)
|
||||
|
||||
@Query("""
|
||||
SELECT * FROM CardBackground
|
||||
WHERE cardId = :cardId
|
||||
""")
|
||||
suspend fun getCardBackground(cardId: Long): CardBackground
|
||||
|
||||
@Query("""
|
||||
SELECT * FROM CardBackground
|
||||
""")
|
||||
suspend fun getBackgrounds(): List<CardBackground>
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.github.nacabaro.vbhelper.daos
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardSprites
|
||||
|
||||
@Dao
|
||||
interface CardDao {
|
||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||
suspend fun insertNewCard(card: Card): Long
|
||||
|
||||
@Query("SELECT * FROM Card WHERE cardId = :id")
|
||||
fun getCardByCardId(id: Int): List<Card>
|
||||
|
||||
@Query("SELECT * FROM Card WHERE id = :id")
|
||||
fun getCardById(id: Long): Card?
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT ca.*
|
||||
FROM Card ca
|
||||
JOIN CardCharacter ch ON ca.id = ch.cardId
|
||||
JOIN UserCharacter uc ON ch.id = uc.charId
|
||||
WHERE uc.id = :id
|
||||
"""
|
||||
)
|
||||
suspend fun getCardByCharacterId(id: Long): Card
|
||||
|
||||
@Query("UPDATE Card SET name = :newName WHERE id = :id")
|
||||
suspend fun renameCard(id: Int, newName: String)
|
||||
|
||||
@Query("DELETE FROM Card WHERE id = :id")
|
||||
suspend fun deleteCard(id: Long)
|
||||
|
||||
@Insert
|
||||
suspend fun insertSprites(vararg sprites: CardSprites)
|
||||
|
||||
@Query("SELECT * FROM CardSprites")
|
||||
suspend fun getSprites(): List<CardSprites>
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.github.nacabaro.vbhelper.daos
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
|
||||
@Dao
|
||||
interface CardFusionsDao {
|
||||
@Query(
|
||||
"""
|
||||
INSERT INTO
|
||||
CardFusions (
|
||||
fromCharaId,
|
||||
toVirusFusion,
|
||||
toDataFusion,
|
||||
toVaccineFusion,
|
||||
toFreeFusion
|
||||
)
|
||||
SELECT
|
||||
(SELECT id FROM CardCharacter WHERE cardId = :cardId AND charaIndex = :fromCharaId),
|
||||
(SELECT id FROM CardCharacter WHERE cardId = :cardId AND charaIndex = :toCharaIdVirus),
|
||||
(SELECT id FROM CardCharacter WHERE cardId = :cardId AND charaIndex = :toCharaIdData),
|
||||
(SELECT id FROM CardCharacter WHERE cardId = :cardId AND charaIndex = :toCharaIdVaccine),
|
||||
(SELECT id FROM CardCharacter WHERE cardId = :cardId AND charaIndex = :toCharaIdFree)
|
||||
"""
|
||||
)
|
||||
suspend fun insertNewFusion(
|
||||
cardId: Long,
|
||||
fromCharaId: Int,
|
||||
toCharaIdVirus: Int,
|
||||
toCharaIdData: Int,
|
||||
toCharaIdVaccine: Int,
|
||||
toCharaIdFree: Int
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.github.nacabaro.vbhelper.daos
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import androidx.room.Upsert
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardProgress
|
||||
|
||||
@Dao
|
||||
interface CardProgressDao {
|
||||
@Upsert
|
||||
fun updateDimProgress(vararg cardProgresses: CardProgress)
|
||||
|
||||
@Query(
|
||||
"SELECT currentStage FROM CardProgress WHERE cardId = :cardId"
|
||||
)
|
||||
fun getCardProgress(cardId: Long): Int
|
||||
}
|
||||
@@ -3,49 +3,85 @@ package com.github.nacabaro.vbhelper.daos
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Character
|
||||
import com.github.nacabaro.vbhelper.domain.Sprites
|
||||
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: Character)
|
||||
suspend fun insertCharacter(vararg characterData: CardCharacter)
|
||||
|
||||
@Query("SELECT * FROM Character")
|
||||
suspend fun getAllCharacters(): List<Character>
|
||||
|
||||
@Query("SELECT * FROM Character WHERE dimId = :dimId")
|
||||
suspend fun getCharacterByDimId(dimId: Int): List<Character>
|
||||
|
||||
@Query("SELECT * FROM Character WHERE monIndex = :monIndex AND dimId = :dimId LIMIT 1")
|
||||
fun getCharacterByMonIndex(monIndex: Int, dimId: Long): Character
|
||||
@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: Sprites)
|
||||
|
||||
@Query("SELECT * FROM Sprites")
|
||||
suspend fun getAllSprites(): List<Sprites>
|
||||
suspend fun insertSprite(vararg sprite: Sprite)
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT
|
||||
d.dimId as cardId,
|
||||
c.monIndex as charId
|
||||
FROM Character c
|
||||
d.cardId as cardId,
|
||||
c.charaIndex as charId,
|
||||
c.stage as stage,
|
||||
c.attribute as attribute
|
||||
FROM CardCharacter c
|
||||
JOIN UserCharacter uc ON c.id = uc.charId
|
||||
JOIN Card d ON c.dimId = d.id
|
||||
WHERE uc.id = :charId
|
||||
JOIN Card d ON c.cardId = d.id
|
||||
WHERE c.id = :charId
|
||||
"""
|
||||
)
|
||||
suspend fun getCharacterInfo(charId: Long): CharacterDtos.DiMInfo
|
||||
suspend fun getCharacterInfo(charId: Long): CharacterDtos.CardCharacterInfo
|
||||
|
||||
@Query("""
|
||||
INSERT INTO TransformationHistory(monId, stageId, transformationDate)
|
||||
VALUES
|
||||
(:monId,
|
||||
(SELECT id FROM Character WHERE monIndex = :stage AND dimId = :dimId),
|
||||
:transformationDate)
|
||||
""")
|
||||
fun insertTransformation(monId: Long, stage: Int, dimId: Long, transformationDate: Long)
|
||||
@Query(
|
||||
"""
|
||||
INSERT INTO CardTransformations (charaId, requiredVitals, requiredTrophies, requiredBattles, requiredWinRate, changeTimerHours, requiredAdventureLevelCompleted, toCharaId)
|
||||
SELECT
|
||||
(SELECT id FROM CardCharacter WHERE charaIndex = :fromChraraIndex AND cardId = :cardId),
|
||||
:requiredVitals,
|
||||
:requiredTrophies,
|
||||
:requiredBattles,
|
||||
:requiredWinRate,
|
||||
:changeTimerHours,
|
||||
:requiredAdventureLevelCompleted,
|
||||
(SELECT id FROM CardCharacter WHERE charaIndex = :toChraraIndex AND cardId = :cardId)
|
||||
"""
|
||||
)
|
||||
suspend fun insertPossibleTransformation(
|
||||
fromChraraIndex: Int,
|
||||
toChraraIndex: Int,
|
||||
cardId: Long,
|
||||
requiredVitals: Int,
|
||||
requiredTrophies: Int,
|
||||
requiredBattles: Int,
|
||||
changeTimerHours: Int,
|
||||
requiredWinRate: Int,
|
||||
requiredAdventureLevelCompleted: Int
|
||||
)
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT
|
||||
pt.charaId as fromCharaId,
|
||||
pt.toCharaId as charaId,
|
||||
s.spriteIdle1 as spriteIdle,
|
||||
s.width as spriteWidth,
|
||||
s.height as spriteHeight,
|
||||
d.discoveredOn as discoveredOn,
|
||||
pt.requiredTrophies as requiredTrophies,
|
||||
pt.requiredVitals as requiredVitals,
|
||||
pt.requiredBattles as requiredBattles,
|
||||
pt.requiredWinRate as requiredWinRate,
|
||||
pt.changeTimerHours as changeTimerHours,
|
||||
pt.requiredAdventureLevelCompleted as requiredAdventureLevelCompleted
|
||||
FROM
|
||||
CardTransformations pt
|
||||
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
|
||||
c.cardId = :cardId
|
||||
"""
|
||||
)
|
||||
suspend fun getEvolutionRequirementsForCard(cardId: Long): List<CharacterDtos.EvolutionRequirementsWithSpritesAndObtained>
|
||||
}
|
||||
@@ -7,38 +7,53 @@ import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
|
||||
@Dao
|
||||
interface DexDao {
|
||||
@Query("""
|
||||
@Query(
|
||||
"""
|
||||
INSERT OR IGNORE INTO Dex(id, discoveredOn)
|
||||
VALUES (
|
||||
(SELECT id FROM Character WHERE monIndex = :charIndex AND dimId = :cardId),
|
||||
(SELECT id FROM CardCharacter WHERE charaIndex = :charIndex AND cardId = :cardId),
|
||||
:discoveredOn
|
||||
)
|
||||
""")
|
||||
"""
|
||||
)
|
||||
fun insertCharacter(charIndex: Int, cardId: Long, discoveredOn: Long)
|
||||
|
||||
@Query("""
|
||||
@Query(
|
||||
"""
|
||||
SELECT
|
||||
c.id AS id,
|
||||
c.sprite1 AS spriteIdle,
|
||||
c.spritesWidth AS spriteWidth,
|
||||
c.spritesHeight AS spriteHeight,
|
||||
d.discoveredOn AS discoveredOn
|
||||
FROM character c
|
||||
s.spriteIdle1 AS spriteIdle,
|
||||
s.width AS spriteWidth,
|
||||
s.height AS spriteHeight,
|
||||
c.nameSprite AS nameSprite,
|
||||
c.nameWidth AS nameSpriteWidth,
|
||||
c.nameHeight AS nameSpriteHeight,
|
||||
d.discoveredOn AS discoveredOn,
|
||||
c.baseHp as baseHp,
|
||||
c.baseBp as baseBp,
|
||||
c.baseAp as baseAp,
|
||||
c.stage as stage,
|
||||
c.attribute as attribute
|
||||
FROM CardCharacter c
|
||||
JOIN Sprite s ON c.spriteId = s.id
|
||||
LEFT JOIN dex d ON c.id = d.id
|
||||
WHERE c.dimId = :cardId
|
||||
""")
|
||||
suspend fun getSingleCardProgress(cardId: Long): List<CharacterDtos.CardProgress>
|
||||
WHERE c.cardId = :cardId
|
||||
"""
|
||||
)
|
||||
suspend fun getSingleCardProgress(cardId: Long): List<CharacterDtos.CardCharaProgress>
|
||||
|
||||
@Query("""
|
||||
@Query(
|
||||
"""
|
||||
SELECT
|
||||
c.id as cardId,
|
||||
c.name as cardName,
|
||||
c.logo as cardLogo,
|
||||
c.logoWidth as logoWidth,
|
||||
c.logoHeight as logoHeight,
|
||||
(SELECT COUNT(*) FROM Character cc WHERE cc.dimId = c.id) AS totalCharacters,
|
||||
(SELECT COUNT(*) FROM Dex d JOIN Character cc ON d.id = cc.id WHERE cc.dimId = 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
|
||||
""")
|
||||
"""
|
||||
)
|
||||
suspend fun getCardsWithProgress(): List<CardDtos.CardProgress>
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package com.github.nacabaro.vbhelper.daos
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Card
|
||||
|
||||
@Dao
|
||||
interface DiMDao {
|
||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||
suspend fun insertNewDim(card: Card): Long
|
||||
|
||||
@Query("SELECT * FROM Card")
|
||||
suspend fun getAllDims(): List<Card>
|
||||
|
||||
@Query("SELECT * FROM Card WHERE dimId = :id")
|
||||
fun getDimById(id: Int): Card?
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.github.nacabaro.vbhelper.daos
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Upsert
|
||||
import com.github.nacabaro.vbhelper.domain.DimProgress
|
||||
|
||||
@Dao
|
||||
interface DiMProgressDao {
|
||||
@Upsert
|
||||
suspend fun updateDimProgress(vararg dimProgress: DimProgress)
|
||||
}
|
||||
@@ -6,40 +6,48 @@ import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
|
||||
@Dao
|
||||
interface ItemDao {
|
||||
@Query("""
|
||||
SELECT Items.*, UserItems.quantity
|
||||
@Query(
|
||||
"""
|
||||
SELECT *
|
||||
FROM Items
|
||||
LEFT JOIN UserItems ON Items.id = UserItems.itemId
|
||||
ORDER BY Items.itemIcon ASC
|
||||
""")
|
||||
"""
|
||||
)
|
||||
suspend fun getAllItems(): List<ItemDtos.ItemsWithQuantities>
|
||||
|
||||
@Query("""
|
||||
SELECT Items.*, UserItems.quantity
|
||||
@Query(
|
||||
"""
|
||||
SELECT *
|
||||
FROM Items
|
||||
JOIN UserItems ON Items.id = UserItems.itemId
|
||||
""")
|
||||
WHERE quantity > 0
|
||||
"""
|
||||
)
|
||||
suspend fun getAllUserItems(): List<ItemDtos.ItemsWithQuantities>
|
||||
|
||||
@Query("""
|
||||
SELECT Items.*, UserItems.quantity
|
||||
@Query(
|
||||
"""
|
||||
SELECT *
|
||||
FROM Items
|
||||
JOIN UserItems ON Items.id = UserItems.itemId
|
||||
WHERE UserItems.itemId = :itemId
|
||||
""")
|
||||
fun getUserItem(itemId: Long): ItemDtos.ItemsWithQuantities
|
||||
WHERE Items.id = :itemId
|
||||
"""
|
||||
)
|
||||
suspend fun getItem(itemId: Long): ItemDtos.ItemsWithQuantities
|
||||
|
||||
@Query("""
|
||||
UPDATE UserItems
|
||||
@Query(
|
||||
"""
|
||||
UPDATE Items
|
||||
SET quantity = quantity - 1
|
||||
WHERE itemId = :itemId
|
||||
""")
|
||||
fun useItem(itemId: Long)
|
||||
WHERE id = :itemId
|
||||
"""
|
||||
)
|
||||
suspend fun useItem(itemId: Long)
|
||||
|
||||
@Query("""
|
||||
UPDATE UserItems
|
||||
SET quantity = quantity - :itemAmount
|
||||
WHERE itemId = :itemId
|
||||
""")
|
||||
@Query(
|
||||
"""
|
||||
UPDATE Items
|
||||
SET quantity = quantity + :itemAmount
|
||||
WHERE id = :itemId
|
||||
"""
|
||||
)
|
||||
suspend fun purchaseItem(itemId: Long, itemAmount: Int)
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.github.nacabaro.vbhelper.daos
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
|
||||
@Dao
|
||||
interface SpecialMissionDao {
|
||||
@Query("""
|
||||
UPDATE SpecialMissions SET
|
||||
missionType = "NONE",
|
||||
status = "UNAVAILABLE"
|
||||
WHERE id = :id
|
||||
""")
|
||||
suspend fun clearSpecialMission(id: Long)
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.github.nacabaro.vbhelper.daos
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Sprite
|
||||
|
||||
@Dao
|
||||
interface SpriteDao {
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insertSprite(sprite: Sprite): Long
|
||||
|
||||
@Query("SELECT * FROM Sprite")
|
||||
suspend fun getAllSprites(): List<Sprite>
|
||||
}
|
||||
@@ -5,9 +5,13 @@ import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Upsert
|
||||
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
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.TransformationHistory
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.VitalsHistory
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
|
||||
@Dao
|
||||
@@ -18,6 +22,9 @@ interface UserCharacterDao {
|
||||
@Insert
|
||||
fun insertBECharacterData(characterData: BECharacterData)
|
||||
|
||||
@Insert
|
||||
fun insertVBCharacterData(characterData: VBCharacterData)
|
||||
|
||||
@Upsert
|
||||
fun updateCharacter(character: UserCharacter)
|
||||
|
||||
@@ -27,52 +34,107 @@ interface UserCharacterDao {
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insertTransformationHistory(vararg transformationHistory: TransformationHistory)
|
||||
|
||||
@Query("""
|
||||
@Upsert
|
||||
fun insertSpecialMissions(vararg specialMissions: SpecialMissions)
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT
|
||||
c.id AS id,
|
||||
c.sprite1 AS spriteIdle,
|
||||
c.spritesWidth AS spriteWidth,
|
||||
c.spritesHeight AS spriteHeight,
|
||||
c.monIndex AS monIndex,
|
||||
s.spriteIdle1 AS spriteIdle,
|
||||
s.width AS spriteWidth,
|
||||
s.height AS spriteHeight,
|
||||
c.charaIndex AS monIndex,
|
||||
t.transformationDate AS transformationDate
|
||||
FROM TransformationHistory t
|
||||
JOIN Character 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
|
||||
""")
|
||||
fun getTransformationHistory(monId: Long): List<CharacterDtos.TransformationHistory>?
|
||||
"""
|
||||
)
|
||||
suspend fun getTransformationHistory(monId: Long): List<CharacterDtos.TransformationHistory>?
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT
|
||||
uc.*,
|
||||
c.sprite1 AS spriteIdle,
|
||||
c.spritesWidth AS spriteWidth,
|
||||
c.spritesHeight AS spriteHeight,
|
||||
d.isBEm as isBemCard
|
||||
c.stage,
|
||||
c.attribute,
|
||||
s.spriteIdle1 AS spriteIdle,
|
||||
s.spriteIdle2 AS spriteIdle2,
|
||||
s.width AS spriteWidth,
|
||||
s.height AS spriteHeight,
|
||||
c.nameSprite as nameSprite,
|
||||
c.nameWidth as nameSpriteWidth,
|
||||
c.nameHeight as nameSpriteHeight,
|
||||
d.isBEm as isBemCard,
|
||||
a.characterId = uc.id as isInAdventure
|
||||
FROM UserCharacter uc
|
||||
JOIN Character c ON uc.charId = c.id
|
||||
JOIN Card d ON c.dimId = d.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
|
||||
"""
|
||||
)
|
||||
suspend fun getAllCharacters(): List<CharacterDtos.CharacterWithSprites>
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT
|
||||
uc.*,
|
||||
c.stage,
|
||||
c.attribute,
|
||||
s.spriteIdle1 AS spriteIdle,
|
||||
s.spriteIdle2 AS spriteIdle2,
|
||||
s.width AS spriteWidth,
|
||||
s.height AS spriteHeight,
|
||||
c.nameSprite as nameSprite,
|
||||
c.nameWidth as nameSpriteWidth,
|
||||
c.nameHeight as nameSpriteHeight,
|
||||
d.isBEm as isBemCard,
|
||||
a.characterId = uc.id as isInAdventure
|
||||
FROM UserCharacter uc
|
||||
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
|
||||
WHERE uc.id = :id
|
||||
"""
|
||||
)
|
||||
suspend fun getCharacterWithSprites(id: Long): CharacterDtos.CharacterWithSprites
|
||||
|
||||
@Query("SELECT * FROM UserCharacter WHERE id = :id")
|
||||
suspend fun getCharacter(id: Long): UserCharacter
|
||||
|
||||
@Query("SELECT * FROM BECharacterData WHERE id = :id")
|
||||
suspend fun getBeData(id: Long): BECharacterData
|
||||
|
||||
@Query("SELECT * FROM VBCharacterData WHERE id = :id")
|
||||
suspend fun getVbData(id: Long): VBCharacterData
|
||||
|
||||
@Query("SELECT * FROM SpecialMissions WHERE characterId = :id")
|
||||
suspend fun getSpecialMissions(id: Long): List<SpecialMissions>
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT
|
||||
uc.*,
|
||||
c.sprite1 AS spriteIdle,
|
||||
c.spritesWidth AS spriteWidth,
|
||||
c.spritesHeight AS spriteHeight,
|
||||
d.isBEm as isBemCard
|
||||
c.stage,
|
||||
c.attribute,
|
||||
s.spriteIdle1 AS spriteIdle,
|
||||
s.spriteIdle2 AS spriteIdle2,
|
||||
s.width AS spriteWidth,
|
||||
s.height AS spriteHeight,
|
||||
c.nameSprite as nameSprite,
|
||||
c.nameWidth as nameSpriteWidth,
|
||||
c.nameHeight as nameSpriteHeight,
|
||||
d.isBEm as isBemCard,
|
||||
a.characterId as isInAdventure
|
||||
FROM UserCharacter uc
|
||||
JOIN Character c ON uc.charId = c.id
|
||||
JOIN Card d ON c.dimId = d.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
|
||||
WHERE uc.isActive = 1
|
||||
LIMIT 1
|
||||
"""
|
||||
@@ -87,4 +149,83 @@ interface UserCharacterDao {
|
||||
|
||||
@Query("UPDATE UserCharacter SET isActive = 1 WHERE id = :id")
|
||||
fun setActiveCharacter(id: Long)
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT c.*
|
||||
FROM CardCharacter c
|
||||
join UserCharacter uc on c.id = uc.charId
|
||||
where uc.id = :charId
|
||||
LIMIT 1
|
||||
"""
|
||||
)
|
||||
suspend fun getCharacterInfo(charId: Long): CardCharacter
|
||||
|
||||
|
||||
@Query(
|
||||
"""
|
||||
INSERT INTO TransformationHistory(monId, stageId, transformationDate)
|
||||
VALUES
|
||||
(:monId,
|
||||
(SELECT id FROM CardCharacter WHERE charaIndex = :stage AND cardId = :dimId),
|
||||
:transformationDate)
|
||||
"""
|
||||
)
|
||||
fun insertTransformation(monId: Long, stage: Int, dimId: Long, transformationDate: Long)
|
||||
|
||||
@Upsert
|
||||
fun insertVitals(vararg vitalsHistory: VitalsHistory)
|
||||
|
||||
@Query("""SELECT * FROM VitalsHistory WHERE charId = :charId ORDER BY id ASC""")
|
||||
suspend fun getVitalsHistory(charId: Long): List<VitalsHistory>
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT
|
||||
uc.*,
|
||||
c.stage,
|
||||
c.attribute,
|
||||
s.spriteIdle1 AS spriteIdle,
|
||||
s.spriteIdle2 AS spriteIdle2,
|
||||
s.width AS spriteWidth,
|
||||
s.height AS spriteHeight,
|
||||
c.nameSprite as nameSprite,
|
||||
c.nameWidth as nameSpriteWidth,
|
||||
c.nameHeight as nameSpriteHeight,
|
||||
d.isBEm as isBemCard,
|
||||
a.characterId = uc.id as isInAdventure
|
||||
FROM UserCharacter uc
|
||||
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
|
||||
WHERE uc.characterType = "BEDevice"
|
||||
"""
|
||||
)
|
||||
suspend fun getBECharacters(): List<CharacterDtos.CharacterWithSprites>
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT
|
||||
uc.*,
|
||||
c.stage,
|
||||
c.attribute,
|
||||
s.spriteIdle1 AS spriteIdle,
|
||||
s.spriteIdle2 AS spriteIdle2,
|
||||
s.width AS spriteWidth,
|
||||
s.height AS spriteHeight,
|
||||
c.nameSprite as nameSprite,
|
||||
c.nameWidth as nameSpriteWidth,
|
||||
c.nameHeight as nameSpriteHeight,
|
||||
d.isBEm as isBemCard,
|
||||
a.characterId = uc.id as isInAdventure
|
||||
FROM UserCharacter uc
|
||||
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
|
||||
WHERE uc.characterType = "VBDevice"
|
||||
"""
|
||||
)
|
||||
suspend fun getVBDimCharacters(): List<CharacterDtos.CharacterWithSprites>
|
||||
}
|
||||
@@ -2,39 +2,71 @@ 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.CardBackgroundDao
|
||||
import com.github.nacabaro.vbhelper.daos.CharacterDao
|
||||
import com.github.nacabaro.vbhelper.daos.DexDao
|
||||
import com.github.nacabaro.vbhelper.daos.DiMDao
|
||||
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.characters.Character
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Card
|
||||
import com.github.nacabaro.vbhelper.domain.Sprites
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardBackground
|
||||
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.CardSprites
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardTransformations
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Sprite
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Adventure
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Dex
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.TransformationHistory
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.VitalsHistory
|
||||
import com.github.nacabaro.vbhelper.domain.items.Items
|
||||
import com.github.nacabaro.vbhelper.domain.items.UserItems
|
||||
|
||||
@Database(
|
||||
version = 1,
|
||||
entities = [
|
||||
Card::class,
|
||||
Character::class,
|
||||
Sprites::class,
|
||||
CardProgress::class,
|
||||
CardCharacter::class,
|
||||
CardAdventure::class,
|
||||
CardFusions::class,
|
||||
CardSprites::class,
|
||||
Sprite::class,
|
||||
UserCharacter::class,
|
||||
BECharacterData::class,
|
||||
VBCharacterData::class,
|
||||
SpecialMissions::class,
|
||||
TransformationHistory::class,
|
||||
VitalsHistory::class,
|
||||
Dex::class,
|
||||
Items::class,
|
||||
UserItems::class
|
||||
Adventure::class,
|
||||
CardBackground::class,
|
||||
CardTransformations::class
|
||||
]
|
||||
)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
abstract fun dimDao(): DiMDao
|
||||
abstract fun cardDao(): CardDao
|
||||
abstract fun cardProgressDao(): CardProgressDao
|
||||
abstract fun characterDao(): CharacterDao
|
||||
abstract fun userCharacterDao(): UserCharacterDao
|
||||
abstract fun dexDao(): DexDao
|
||||
abstract fun itemDao(): ItemDao
|
||||
abstract fun adventureDao(): AdventureDao
|
||||
abstract fun spriteDao(): SpriteDao
|
||||
abstract fun specialMissionDao(): SpecialMissionDao
|
||||
abstract fun cardAdventureDao(): CardAdventureDao
|
||||
abstract fun cardFusionsDao(): CardFusionsDao
|
||||
abstract fun cardBackgroundDao(): CardBackgroundDao
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package com.github.nacabaro.vbhelper.domain
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Card
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = User::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["userId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
ForeignKey(
|
||||
entity = Card::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["dimId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
]
|
||||
)
|
||||
data class DimProgress(
|
||||
@PrimaryKey val dimId: Int,
|
||||
@PrimaryKey val userId: Int,
|
||||
val currentStage: Int,
|
||||
val unlocked: Boolean
|
||||
)
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.github.nacabaro.vbhelper.domain
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Character
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = Character::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["monId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
ForeignKey(
|
||||
entity = Character::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["nextMon"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
]
|
||||
)
|
||||
data class Evolutions(
|
||||
@PrimaryKey val monId: Int,
|
||||
@PrimaryKey val nextMon: Int,
|
||||
val trophies: Int,
|
||||
val vitals: Int,
|
||||
val totalBattles: Int,
|
||||
val winRate: Int // Does not need to be a floating point
|
||||
)
|
||||
@@ -3,7 +3,6 @@ package com.github.nacabaro.vbhelper.domain
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Character
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package com.github.nacabaro.vbhelper.domain.characters
|
||||
package com.github.nacabaro.vbhelper.domain.card
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
@@ -7,7 +7,7 @@ import androidx.room.PrimaryKey
|
||||
data class Card(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
val id: Long = 0,
|
||||
val dimId: Int,
|
||||
val cardId: Int,
|
||||
val logo: ByteArray,
|
||||
val logoWidth: Int,
|
||||
val logoHeight: Int,
|
||||
@@ -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?
|
||||
)
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.github.nacabaro.vbhelper.domain.card
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = Card::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["cardId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
]
|
||||
)
|
||||
data class CardBackground (
|
||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||
val cardId: Long,
|
||||
val background: ByteArray,
|
||||
val backgroundWidth: Int,
|
||||
val backgroundHeight: Int
|
||||
)
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.github.nacabaro.vbhelper.domain.card
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Sprite
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = Card::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["cardId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
ForeignKey(
|
||||
entity = Sprite::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["spriteId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
/*
|
||||
* Character represents a character on a card. There should only be one of these per dimId
|
||||
* and monIndex.
|
||||
* TODO: Customs will mean this should be unique per cardName and monIndex
|
||||
*/
|
||||
data class CardCharacter (
|
||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||
val cardId: Long,
|
||||
val spriteId: Long,
|
||||
val charaIndex: Int,
|
||||
val stage: Int, // These should be replaced with enums
|
||||
val attribute: NfcCharacter.Attribute, // This one too
|
||||
val baseHp: Int,
|
||||
val baseBp: Int,
|
||||
val baseAp: Int,
|
||||
val nameSprite: ByteArray,
|
||||
val nameWidth: Int,
|
||||
val nameHeight: Int
|
||||
)
|
||||
@@ -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 = ["toVirusFusion"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
ForeignKey(
|
||||
entity = CardCharacter::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["toDataFusion"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
ForeignKey(
|
||||
entity = CardCharacter::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["toVaccineFusion"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
ForeignKey(
|
||||
entity = CardCharacter::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["toFreeFusion"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
]
|
||||
)
|
||||
data class CardFusions(
|
||||
@PrimaryKey(autoGenerate = true) val id: Long,
|
||||
val fromCharaId: Long,
|
||||
val toVirusFusion: Long?,
|
||||
val toDataFusion: Long?,
|
||||
val toVaccineFusion: Long?,
|
||||
val toFreeFusion: Long?
|
||||
)
|
||||
+7
-6
@@ -1,4 +1,4 @@
|
||||
package com.github.nacabaro.vbhelper.domain.items
|
||||
package com.github.nacabaro.vbhelper.domain.card
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
@@ -7,14 +7,15 @@ import androidx.room.PrimaryKey
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = Items::class,
|
||||
entity = Card::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["itemId"],
|
||||
childColumns = ["cardId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
]
|
||||
)
|
||||
data class UserItems(
|
||||
@PrimaryKey val itemId: Long,
|
||||
val quantity: Int,
|
||||
data class CardProgress(
|
||||
@PrimaryKey val cardId: Long,
|
||||
val currentStage: Int,
|
||||
val unlocked: Boolean
|
||||
)
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
package com.github.nacabaro.vbhelper.domain
|
||||
package com.github.nacabaro.vbhelper.domain.card
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity
|
||||
data class Sprites(
|
||||
@PrimaryKey(autoGenerate = true) val id : Int,
|
||||
data class CardSprites(
|
||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||
val sprite: ByteArray,
|
||||
val width: Int,
|
||||
val height: Int
|
||||
@@ -0,0 +1,33 @@
|
||||
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 = ["charaId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
ForeignKey(
|
||||
entity = CardCharacter::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["toCharaId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
]
|
||||
)
|
||||
data class CardTransformations (
|
||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||
var charaId: Long,
|
||||
val requiredVitals: Int,
|
||||
val requiredTrophies: Int,
|
||||
val requiredBattles: Int,
|
||||
val requiredWinRate: Int,
|
||||
val changeTimerHours: Int,
|
||||
val requiredAdventureLevelCompleted: Int,
|
||||
val toCharaId: Long?
|
||||
)
|
||||
@@ -0,0 +1,22 @@
|
||||
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.device_data.UserCharacter
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = UserCharacter::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["characterId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
]
|
||||
)
|
||||
data class Adventure(
|
||||
@PrimaryKey val characterId: Long,
|
||||
val originalDuration: Long,
|
||||
val finishesAdventure: Long
|
||||
)
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.github.nacabaro.vbhelper.domain.characters
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import androidx.room.ForeignKey
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = Card::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["dimId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
]
|
||||
)
|
||||
data class Character (
|
||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||
val dimId: Long,
|
||||
val monIndex: Int,
|
||||
val name: ByteArray,
|
||||
val stage: Int, // These should be replaced with enums
|
||||
val attribute: Int, // This one too
|
||||
val baseHp: Int,
|
||||
val baseBp: Int,
|
||||
val baseAp: Int,
|
||||
val sprite1: ByteArray,
|
||||
val sprite2: ByteArray,
|
||||
val nameWidth: Int,
|
||||
val nameHeight: Int,
|
||||
val spritesWidth: Int,
|
||||
val spritesHeight: Int
|
||||
)
|
||||
@@ -3,11 +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.CardCharacter
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = Character::class,
|
||||
entity = CardCharacter::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["id"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.github.nacabaro.vbhelper.domain.characters
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity
|
||||
data class Sprite(
|
||||
@PrimaryKey(autoGenerate = true) val id : Int = 0,
|
||||
val spriteIdle1: ByteArray,
|
||||
val spriteIdle2: ByteArray,
|
||||
val spriteWalk1: ByteArray,
|
||||
val spriteWalk2: ByteArray,
|
||||
val spriteRun1: ByteArray,
|
||||
val spriteRun2: ByteArray,
|
||||
val spriteTrain1: ByteArray,
|
||||
val spriteTrain2: ByteArray,
|
||||
val spriteHappy: ByteArray,
|
||||
val spriteSleep: ByteArray,
|
||||
val spriteAttack: ByteArray,
|
||||
val spriteDodge: ByteArray,
|
||||
val width: Int,
|
||||
val height: Int
|
||||
)
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.github.nacabaro.vbhelper.domain.device_data
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
import com.github.cfogrady.vbnfc.vb.SpecialMission
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = UserCharacter::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["characterId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
]
|
||||
)
|
||||
data class SpecialMissions (
|
||||
@PrimaryKey(autoGenerate = true) var id: Long = 0,
|
||||
var characterId: Long,
|
||||
var goal: Int,
|
||||
val watchId: Int,
|
||||
val progress: Int,
|
||||
val status: SpecialMission.Status,
|
||||
val timeElapsedInMinutes: Int,
|
||||
val timeLimitInMinutes: Int,
|
||||
val missionType: SpecialMission.Type
|
||||
)
|
||||
+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.characters.Character
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardCharacter
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
@@ -14,7 +14,7 @@ import com.github.nacabaro.vbhelper.domain.characters.Character
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
ForeignKey(
|
||||
entity = Character::class,
|
||||
entity = CardCharacter::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["stageId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
|
||||
@@ -5,25 +5,25 @@ 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.characters.Character
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardCharacter
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = Character::class,
|
||||
entity = CardCharacter::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["charId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
]
|
||||
)
|
||||
/**
|
||||
* UserCharacter represents and instance of a character. The charId should map to a Character
|
||||
*/
|
||||
data class UserCharacter (
|
||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||
var charId: Long,
|
||||
var stage: Int,
|
||||
var attribute: NfcCharacter.Attribute,
|
||||
var ageInDays: Int,
|
||||
var nextAdventureMissionStage: Int, // next adventure mission stage on the character's dim
|
||||
var mood: Int,
|
||||
var vitalPoints: Int,
|
||||
var transformationCountdown: Int,
|
||||
|
||||
+19
-2
@@ -1,4 +1,21 @@
|
||||
package com.github.nacabaro.vbhelper.domain.device_data
|
||||
|
||||
class VBCharacterData {
|
||||
}
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = UserCharacter::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["id"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
]
|
||||
)
|
||||
data class VBCharacterData (
|
||||
@PrimaryKey val id: Long,
|
||||
val generation: Int,
|
||||
val totalTrophies: Int
|
||||
)
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.github.nacabaro.vbhelper.domain.device_data
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = UserCharacter::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["charId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
]
|
||||
)
|
||||
data class VitalsHistory (
|
||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||
val charId: Long,
|
||||
val year: Int,
|
||||
val month: Int,
|
||||
val day: Int,
|
||||
val vitalPoints: Int
|
||||
)
|
||||
@@ -3,6 +3,13 @@ package com.github.nacabaro.vbhelper.domain.items
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
enum class ItemType {
|
||||
VBITEM,
|
||||
BEITEM,
|
||||
UNIVERSAL,
|
||||
SPECIALMISSION
|
||||
}
|
||||
|
||||
@Entity
|
||||
data class Items(
|
||||
@PrimaryKey val id: Long,
|
||||
@@ -10,5 +17,7 @@ data class Items(
|
||||
val description: String,
|
||||
val itemIcon: Int,
|
||||
val itemLength: Int,
|
||||
val price: Int
|
||||
val price: Int,
|
||||
val quantity: Int,
|
||||
val itemType: ItemType
|
||||
)
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
}
|
||||
@@ -11,7 +11,74 @@ object CharacterDtos {
|
||||
var stage: Int,
|
||||
var attribute: NfcCharacter.Attribute,
|
||||
var ageInDays: Int,
|
||||
var nextAdventureMissionStage: Int, // next adventure mission stage on the character's dim
|
||||
var mood: Int,
|
||||
var vitalPoints: Int,
|
||||
var transformationCountdown: Int,
|
||||
var injuryStatus: NfcCharacter.InjuryStatus,
|
||||
var trophies: Int,
|
||||
var currentPhaseBattlesWon: Int,
|
||||
var currentPhaseBattlesLost: Int,
|
||||
var totalBattlesWon: Int,
|
||||
var totalBattlesLost: Int,
|
||||
var activityLevel: Int,
|
||||
var heartRateCurrent: Int,
|
||||
var characterType: DeviceType,
|
||||
val spriteIdle: ByteArray,
|
||||
val spriteIdle2: ByteArray,
|
||||
val spriteWidth: Int,
|
||||
val spriteHeight: Int,
|
||||
val nameSprite: ByteArray,
|
||||
val nameSpriteWidth: Int,
|
||||
val nameSpriteHeight: Int,
|
||||
val isBemCard: Boolean,
|
||||
val isInAdventure: Boolean
|
||||
)
|
||||
|
||||
data class CardCharacterInfo(
|
||||
val cardId: Long,
|
||||
val charId: Int,
|
||||
val stage: Int,
|
||||
val attribute: NfcCharacter.Attribute
|
||||
)
|
||||
|
||||
data class TransformationHistory(
|
||||
val id: Long,
|
||||
val spriteIdle: ByteArray,
|
||||
val spriteWidth: Int,
|
||||
val spriteHeight: Int,
|
||||
val monIndex: Int,
|
||||
val transformationDate: Long
|
||||
)
|
||||
|
||||
data class CardCharaProgress(
|
||||
val id: Long,
|
||||
val spriteIdle: ByteArray,
|
||||
val spriteWidth: Int,
|
||||
val spriteHeight: Int,
|
||||
val nameSprite: ByteArray,
|
||||
val nameSpriteWidth: Int,
|
||||
val nameSpriteHeight: Int,
|
||||
val discoveredOn: Long?,
|
||||
val baseHp: Int,
|
||||
val baseBp: Int,
|
||||
val baseAp: Int,
|
||||
val stage: Int,
|
||||
val attribute: NfcCharacter.Attribute,
|
||||
)
|
||||
|
||||
data class CardProgress(
|
||||
val id: Long,
|
||||
val spriteIdle: ByteArray,
|
||||
val spriteWidth: Int,
|
||||
val spriteHeight: Int,
|
||||
)
|
||||
|
||||
data class AdventureCharacterWithSprites(
|
||||
var id: Long = 0,
|
||||
var charId: Long,
|
||||
var stage: Int,
|
||||
var attribute: NfcCharacter.Attribute,
|
||||
var ageInDays: Int,
|
||||
var mood: Int,
|
||||
var vitalPoints: Int,
|
||||
var transformationCountdown: Int,
|
||||
@@ -27,28 +94,23 @@ object CharacterDtos {
|
||||
val spriteIdle: ByteArray,
|
||||
val spriteWidth: Int,
|
||||
val spriteHeight: Int,
|
||||
val isBemCard: Boolean
|
||||
val isBemCard: Boolean,
|
||||
val finishesAdventure: Long,
|
||||
val originalTimeInMinutes: Long
|
||||
)
|
||||
|
||||
data class DiMInfo(
|
||||
val cardId: Int,
|
||||
val charId: Int
|
||||
)
|
||||
|
||||
data class TransformationHistory(
|
||||
val id: Long,
|
||||
data class EvolutionRequirementsWithSpritesAndObtained(
|
||||
val charaId: Long,
|
||||
val fromCharaId: Long,
|
||||
val spriteIdle: ByteArray,
|
||||
val spriteWidth: Int,
|
||||
val spriteHeight: Int,
|
||||
val monIndex: Int,
|
||||
val transformationDate: Long
|
||||
)
|
||||
|
||||
data class CardProgress(
|
||||
val id: Long,
|
||||
val spriteIdle: ByteArray,
|
||||
val spriteWidth: Int,
|
||||
val spriteHeight: Int,
|
||||
val discoveredOn: Long?
|
||||
val discoveredOn: Long?,
|
||||
val requiredTrophies: Int,
|
||||
val requiredVitals: Int,
|
||||
val requiredBattles: Int,
|
||||
val requiredWinRate: Int,
|
||||
val changeTimerHours: Int,
|
||||
val requiredAdventureLevelCompleted: Int
|
||||
)
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.github.nacabaro.vbhelper.dtos
|
||||
|
||||
import com.github.nacabaro.vbhelper.domain.items.ItemType
|
||||
|
||||
|
||||
object ItemDtos {
|
||||
data class ItemsWithQuantities (
|
||||
data class ItemsWithQuantities(
|
||||
val id: Long,
|
||||
val name: String,
|
||||
val description: String,
|
||||
@@ -10,5 +12,16 @@ object ItemDtos {
|
||||
val itemLength: Int,
|
||||
val price: Int,
|
||||
val quantity: Int,
|
||||
val itemType: ItemType
|
||||
)
|
||||
|
||||
data class PurchasedItem(
|
||||
val itemId: Long,
|
||||
val itemName: String,
|
||||
val itemDescription: String,
|
||||
val itemIcon: Int,
|
||||
val itemLength: Int,
|
||||
val itemAmount: Int,
|
||||
val itemType: ItemType
|
||||
)
|
||||
}
|
||||
@@ -1,30 +1,55 @@
|
||||
package com.github.nacabaro.vbhelper.navigation
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.screens.BattlesScreen
|
||||
import com.github.nacabaro.vbhelper.screens.DexScreen
|
||||
import com.github.nacabaro.vbhelper.screens.DiMScreen
|
||||
import com.github.nacabaro.vbhelper.screens.cardScreen.CardsScreen
|
||||
import com.github.nacabaro.vbhelper.screens.cardScreen.CardViewScreen
|
||||
import com.github.nacabaro.vbhelper.screens.homeScreens.HomeScreen
|
||||
import com.github.nacabaro.vbhelper.screens.itemsScreen.ItemsScreen
|
||||
import com.github.nacabaro.vbhelper.screens.scanScreen.ScanScreen
|
||||
import com.github.nacabaro.vbhelper.screens.scanScreen.ScanScreenControllerImpl
|
||||
import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreen
|
||||
import com.github.nacabaro.vbhelper.screens.SpriteViewer
|
||||
import com.github.nacabaro.vbhelper.screens.StorageScreen
|
||||
import com.github.nacabaro.vbhelper.screens.spriteViewer.SpriteViewer
|
||||
import com.github.nacabaro.vbhelper.screens.homeScreens.HomeScreenControllerImpl
|
||||
import com.github.nacabaro.vbhelper.screens.storageScreen.StorageScreen
|
||||
import com.github.nacabaro.vbhelper.screens.itemsScreen.ChooseCharacterScreen
|
||||
import com.github.nacabaro.vbhelper.screens.itemsScreen.ItemsScreenControllerImpl
|
||||
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
|
||||
import com.github.nacabaro.vbhelper.screens.storageScreen.StorageScreenControllerImpl
|
||||
import com.github.nacabaro.vbhelper.source.StorageRepository
|
||||
|
||||
data class AppNavigationHandlers(
|
||||
val settingsScreenController: SettingsScreenControllerImpl,
|
||||
val scanScreenController: ScanScreenControllerImpl,
|
||||
val itemsScreenController: ItemsScreenControllerImpl
|
||||
val itemsScreenController: ItemsScreenControllerImpl,
|
||||
val adventureScreenController: AdventureScreenControllerImpl,
|
||||
val storageScreenController: StorageScreenControllerImpl,
|
||||
val homeScreenController: HomeScreenControllerImpl,
|
||||
val spriteViewerController: SpriteViewerControllerImpl,
|
||||
val cardScreenController: CardScreenControllerImpl
|
||||
)
|
||||
|
||||
@Composable
|
||||
@@ -41,35 +66,67 @@ fun AppNavigation(
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = NavigationItems.Home.route,
|
||||
enterTransition = {
|
||||
fadeIn(
|
||||
animationSpec = tween(200)
|
||||
)
|
||||
},
|
||||
exitTransition = {
|
||||
fadeOut(
|
||||
animationSpec = tween(200)
|
||||
)
|
||||
},
|
||||
modifier = Modifier
|
||||
.padding(contentPadding)
|
||||
|
||||
) {
|
||||
composable(NavigationItems.Battles.route) {
|
||||
BattlesScreen()
|
||||
}
|
||||
composable(NavigationItems.Home.route) {
|
||||
HomeScreen(
|
||||
navController = navController
|
||||
navController = navController,
|
||||
homeScreenController = applicationNavigationHandlers.homeScreenController
|
||||
)
|
||||
}
|
||||
composable(NavigationItems.Storage.route) {
|
||||
StorageScreen(
|
||||
navController = navController
|
||||
navController = navController,
|
||||
adventureScreenController = applicationNavigationHandlers.adventureScreenController,
|
||||
storageScreenController = applicationNavigationHandlers.storageScreenController
|
||||
)
|
||||
}
|
||||
composable(NavigationItems.Scan.route) {
|
||||
val characterIdString = it.arguments?.getString("characterId")
|
||||
val characterId = characterIdString?.toLongOrNull()
|
||||
var characterId by remember { mutableStateOf(characterIdString?.toLongOrNull()) }
|
||||
Log.d("ScanScreen", "characterId: $characterId")
|
||||
val launchedFromHomeScreen = (characterIdString?.toLongOrNull() == null)
|
||||
|
||||
if (characterId == null) {
|
||||
val context = LocalContext.current.applicationContext as VBHelper
|
||||
val storageRepository = StorageRepository(context.container.db)
|
||||
|
||||
LaunchedEffect(characterId) {
|
||||
if (characterId == null) {
|
||||
val characterData = storageRepository.getActiveCharacter()
|
||||
if (characterData != null) {
|
||||
characterId = characterData.id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScanScreen(
|
||||
navController = navController,
|
||||
scanScreenController = applicationNavigationHandlers.scanScreenController,
|
||||
characterId = characterId
|
||||
characterId = characterId,
|
||||
launchedFromHomeScreen = launchedFromHomeScreen
|
||||
)
|
||||
}
|
||||
composable(NavigationItems.Dex.route) {
|
||||
DexScreen(
|
||||
navController = navController
|
||||
CardsScreen(
|
||||
navController = navController,
|
||||
cardScreenController = applicationNavigationHandlers.cardScreenController
|
||||
)
|
||||
}
|
||||
composable(NavigationItems.Settings.route) {
|
||||
@@ -80,15 +137,16 @@ fun AppNavigation(
|
||||
}
|
||||
composable(NavigationItems.Viewer.route) {
|
||||
SpriteViewer(
|
||||
navController = navController
|
||||
navController = navController,
|
||||
spriteViewerController = applicationNavigationHandlers.spriteViewerController
|
||||
)
|
||||
}
|
||||
composable(NavigationItems.CardView.route) {
|
||||
val cardId = it.arguments?.getString("cardId")
|
||||
if (cardId != null) {
|
||||
DiMScreen(
|
||||
CardViewScreen(
|
||||
navController = navController,
|
||||
dimId = cardId.toLong()
|
||||
cardId = cardId.toLong()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -108,6 +166,29 @@ fun AppNavigation(
|
||||
)
|
||||
}
|
||||
}
|
||||
composable(NavigationItems.Adventure.route) {
|
||||
AdventureScreen(
|
||||
navController = navController,
|
||||
storageScreenController = applicationNavigationHandlers
|
||||
.adventureScreenController
|
||||
)
|
||||
}
|
||||
composable(NavigationItems.Credits.route) {
|
||||
CreditsScreen(
|
||||
navController = navController
|
||||
)
|
||||
}
|
||||
composable(NavigationItems.CardAdventure.route) {
|
||||
val cardId = it.arguments?.getString("cardId")
|
||||
if (cardId != null) {
|
||||
CardAdventureScreen(
|
||||
navController = navController,
|
||||
cardId = cardId.toLong(),
|
||||
cardScreenController = applicationNavigationHandlers
|
||||
.cardScreenController
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ fun BottomNavigationBar(navController: NavController) {
|
||||
NavigationItems.Dex,
|
||||
NavigationItems.Storage,
|
||||
)
|
||||
|
||||
NavigationBar {
|
||||
val currentBackStackEntry = navController.currentBackStackEntryAsState()
|
||||
val currentRoute = currentBackStackEntry.value?.destination?.route
|
||||
|
||||
@@ -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")
|
||||
@@ -19,4 +20,6 @@ sealed class NavigationItems (
|
||||
object MyItems : NavigationItems("MyItems", R.drawable.baseline_data_24, "My items")
|
||||
object ItemsStore : NavigationItems("ItemsStore", R.drawable.baseline_data_24, "Items store")
|
||||
object ApplyItem : NavigationItems("ApplyItem/{itemId}", R.drawable.baseline_data_24, "Apply item")
|
||||
object Adventure : NavigationItems("Adventure", R.drawable.baseline_fort_24, "Adventure")
|
||||
object Credits : NavigationItems("Credits", R.drawable.baseline_data_24, "Credits")
|
||||
}
|
||||
@@ -1,9 +1,33 @@
|
||||
package com.github.nacabaro.vbhelper.screens
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||
|
||||
@Composable
|
||||
fun BattlesScreen() {
|
||||
Text("Battles Screen")
|
||||
Scaffold (
|
||||
topBar = {
|
||||
TopBanner(
|
||||
text = "Online battles"
|
||||
)
|
||||
}
|
||||
) { contentPadding ->
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
modifier = Modifier
|
||||
.padding(top = contentPadding.calculateTopPadding())
|
||||
.fillMaxSize()
|
||||
) {
|
||||
Text("Coming soon")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
package com.github.nacabaro.vbhelper.screens
|
||||
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
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.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||
import com.github.nacabaro.vbhelper.components.DexDiMEntry
|
||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Card
|
||||
import com.github.nacabaro.vbhelper.dtos.CardDtos
|
||||
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||
import com.github.nacabaro.vbhelper.source.DexRepository
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun DexScreen(
|
||||
navController: NavController
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val application = LocalContext.current.applicationContext as VBHelper
|
||||
val dexRepository = DexRepository(application.container.db)
|
||||
|
||||
val cardList = remember { mutableStateOf<List<CardDtos.CardProgress>>(emptyList()) }
|
||||
|
||||
LaunchedEffect(dexRepository) {
|
||||
coroutineScope.launch {
|
||||
val newDimList = dexRepository.getAllDims()
|
||||
cardList.value = newDimList // Replace the entire list atomically
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold (
|
||||
topBar = {
|
||||
TopBanner(
|
||||
text = "Discovered characters",
|
||||
onGearClick = {
|
||||
navController.navigate(NavigationItems.Viewer.route)
|
||||
}
|
||||
)
|
||||
}
|
||||
) { contentPadding ->
|
||||
LazyColumn (
|
||||
modifier = Modifier
|
||||
.padding(top = contentPadding.calculateTopPadding())
|
||||
) {
|
||||
items(cardList.value) {
|
||||
DexDiMEntry(
|
||||
name = it.cardName,
|
||||
logo = BitmapData(
|
||||
bitmap = it.cardLogo,
|
||||
width = it.logoWidth,
|
||||
height = it.logoHeight
|
||||
),
|
||||
onClick = {
|
||||
navController
|
||||
.navigate(
|
||||
NavigationItems
|
||||
.CardView.route
|
||||
.replace("{cardId}", "${it.cardId}")
|
||||
)
|
||||
},
|
||||
obtainedCharacters = it.obtainedCharacters,
|
||||
totalCharacters = it.totalCharacters,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,194 +0,0 @@
|
||||
package com.github.nacabaro.vbhelper.screens
|
||||
|
||||
import androidx.compose.foundation.gestures.Orientation
|
||||
import androidx.compose.foundation.gestures.scrollable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import androidx.navigation.NavController
|
||||
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.domain.device_data.UserCharacter
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||
import com.github.nacabaro.vbhelper.source.StorageRepository
|
||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
|
||||
@Composable
|
||||
fun StorageScreen(
|
||||
navController: NavController
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val application = LocalContext.current.applicationContext as VBHelper
|
||||
val storageRepository = StorageRepository(application.container.db)
|
||||
val monList = remember { mutableStateOf<List<CharacterDtos.CharacterWithSprites>>(emptyList()) }
|
||||
|
||||
var selectedCharacter by remember { mutableStateOf<Long?>(null) }
|
||||
|
||||
LaunchedEffect(storageRepository) {
|
||||
coroutineScope.launch {
|
||||
val characterList = storageRepository.getAllCharacters()
|
||||
monList.value = characterList
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold (
|
||||
topBar = { TopBanner(text = "My characters") }
|
||||
) { contentPadding ->
|
||||
if (monList.value.isEmpty()) {
|
||||
Column (
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
modifier = Modifier
|
||||
.padding(top = contentPadding.calculateTopPadding())
|
||||
.fillMaxSize()
|
||||
) {
|
||||
Text(
|
||||
text = "Nothing to see here",
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Fixed(3),
|
||||
modifier = Modifier
|
||||
.scrollable(state = rememberScrollState(), orientation = Orientation.Vertical)
|
||||
.padding(top = contentPadding.calculateTopPadding())
|
||||
) {
|
||||
items(monList.value) { index ->
|
||||
CharacterEntry(
|
||||
icon = BitmapData(
|
||||
bitmap = index.spriteIdle,
|
||||
width = index.spriteWidth,
|
||||
height = index.spriteHeight
|
||||
),
|
||||
onClick = {
|
||||
selectedCharacter = index.id
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedCharacter != null) {
|
||||
StorageDialog(
|
||||
characterId = selectedCharacter!!,
|
||||
onDismissRequest = { selectedCharacter = null },
|
||||
onClickSetActive = {
|
||||
coroutineScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
storageRepository.setActiveCharacter(selectedCharacter!!)
|
||||
selectedCharacter = null
|
||||
}
|
||||
navController.navigate(NavigationItems.Home.route)
|
||||
}
|
||||
},
|
||||
onSendToBracelet = {
|
||||
navController.navigate(
|
||||
NavigationItems.Scan.route.replace(
|
||||
"{characterId}",
|
||||
selectedCharacter.toString()
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun StorageDialog(
|
||||
characterId: Long,
|
||||
onDismissRequest: () -> Unit,
|
||||
onSendToBracelet: () -> Unit,
|
||||
onClickSetActive: () -> Unit
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val application = LocalContext.current.applicationContext as VBHelper
|
||||
val storageRepository = StorageRepository(application.container.db)
|
||||
val character = remember { mutableStateOf<UserCharacter?>(null) }
|
||||
|
||||
LaunchedEffect(storageRepository) {
|
||||
coroutineScope.launch {
|
||||
character.value = storageRepository.getSingleCharacter(characterId)
|
||||
}
|
||||
}
|
||||
|
||||
Dialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
properties = DialogProperties(
|
||||
dismissOnBackPress = true,
|
||||
dismissOnClickOutside = true
|
||||
)
|
||||
) {
|
||||
Card(
|
||||
shape = RoundedCornerShape(16.dp)
|
||||
) {
|
||||
Column (
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
if (character.value != null) {
|
||||
Text(
|
||||
text = character.value?.toString() ?: "Loading...",
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
)
|
||||
}
|
||||
Row (
|
||||
modifier = Modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
Button(
|
||||
onClick = onSendToBracelet
|
||||
) {
|
||||
Text(text = "Send to bracelet")
|
||||
}
|
||||
Button(
|
||||
onClick = onClickSetActive
|
||||
) {
|
||||
Text(text = "Set active")
|
||||
}
|
||||
Button(
|
||||
onClick = onDismissRequest
|
||||
) {
|
||||
Text(text = "Close")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
package com.github.nacabaro.vbhelper.screens.adventureScreen
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Row
|
||||
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.material3.Text
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.FilterQuality
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||
import com.github.nacabaro.vbhelper.utils.getBitmap
|
||||
import java.util.Locale
|
||||
|
||||
@Composable
|
||||
fun AdventureEntry(
|
||||
icon: BitmapData,
|
||||
timeLeft: Long,
|
||||
modifier: Modifier = Modifier,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
val bitmap = remember (icon.bitmap) { icon.getBitmap() }
|
||||
val imageBitmap = remember(bitmap) { bitmap.asImageBitmap() }
|
||||
val density: Float = LocalContext.current.resources.displayMetrics.density
|
||||
val dpSize = (icon.width * 4 / density).dp
|
||||
|
||||
Card(
|
||||
onClick = onClick,
|
||||
modifier = modifier
|
||||
.padding(8.dp)
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
.height(96.dp)
|
||||
) {
|
||||
Image(
|
||||
bitmap = imageBitmap,
|
||||
contentDescription = null,
|
||||
filterQuality = FilterQuality.None,
|
||||
modifier = Modifier
|
||||
.size(dpSize)
|
||||
)
|
||||
Text(
|
||||
text = when {
|
||||
timeLeft < 0 -> "Adventure finished"
|
||||
else -> "Time left: ${formatSeconds(timeLeft)}"
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun formatSeconds(totalSeconds: Long): String {
|
||||
val hours = totalSeconds / 3600
|
||||
val minutes = (totalSeconds % 3600) / 60
|
||||
val seconds = totalSeconds % 60
|
||||
|
||||
return String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, seconds)
|
||||
}
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
package com.github.nacabaro.vbhelper.screens.adventureScreen
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.produceState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.navigation.NavController
|
||||
import com.github.nacabaro.vbhelper.screens.itemsScreen.ObtainedItemDialog
|
||||
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.dtos.ItemDtos
|
||||
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||
import com.github.nacabaro.vbhelper.source.StorageRepository
|
||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import java.time.Instant
|
||||
|
||||
@Composable
|
||||
fun AdventureScreen(
|
||||
navController: NavController,
|
||||
storageScreenController: AdventureScreenControllerImpl
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val application = LocalContext.current.applicationContext as VBHelper
|
||||
val database = application.container.db
|
||||
val storageRepository = StorageRepository(database)
|
||||
val characterList = remember {
|
||||
mutableStateOf<List<CharacterDtos.AdventureCharacterWithSprites>>(emptyList())
|
||||
}
|
||||
var obtainedItem by remember {
|
||||
mutableStateOf<ItemDtos.PurchasedItem?>(null)
|
||||
}
|
||||
|
||||
val currentTime by produceState(initialValue = Instant.now().epochSecond) {
|
||||
while (true) {
|
||||
value = Instant.now().epochSecond
|
||||
delay(1000)
|
||||
}
|
||||
}
|
||||
|
||||
var cancelAdventureDialog by remember {
|
||||
mutableStateOf<CharacterDtos.AdventureCharacterWithSprites?>(null)
|
||||
}
|
||||
|
||||
LaunchedEffect(storageRepository) {
|
||||
coroutineScope.launch {
|
||||
characterList.value = storageRepository
|
||||
.getAdventureCharacters()
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopBanner(
|
||||
text = "Adventure",
|
||||
onBackClick = {
|
||||
navController.popBackStack()
|
||||
}
|
||||
)
|
||||
}
|
||||
) { contentPadding ->
|
||||
if (characterList.value.isEmpty()) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.padding(top = contentPadding.calculateTopPadding())
|
||||
.fillMaxSize()
|
||||
) {
|
||||
Text(text = "Nothing to see here")
|
||||
}
|
||||
} else {
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.padding(top = contentPadding.calculateTopPadding())
|
||||
) {
|
||||
items(characterList.value) {
|
||||
AdventureEntry(
|
||||
icon = BitmapData(
|
||||
bitmap = it.spriteIdle,
|
||||
width = it.spriteWidth,
|
||||
height = it.spriteHeight
|
||||
),
|
||||
timeLeft = it.finishesAdventure - currentTime,
|
||||
onClick = {
|
||||
if (it.finishesAdventure < currentTime) {
|
||||
storageScreenController
|
||||
.getItemFromAdventure(it.id) { adventureResult ->
|
||||
obtainedItem = adventureResult
|
||||
}
|
||||
} else {
|
||||
cancelAdventureDialog = it
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (obtainedItem != null) {
|
||||
ObtainedItemDialog(
|
||||
obtainedItem = obtainedItem!!,
|
||||
onClickDismiss = {
|
||||
obtainedItem = null
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (cancelAdventureDialog != null) {
|
||||
CancelAdventureDialog(
|
||||
characterSprite = BitmapData(
|
||||
bitmap = cancelAdventureDialog!!.spriteIdle,
|
||||
width = cancelAdventureDialog!!.spriteWidth,
|
||||
height = cancelAdventureDialog!!.spriteHeight
|
||||
),
|
||||
onDismissRequest = {
|
||||
cancelAdventureDialog = null
|
||||
},
|
||||
onClickConfirm = {
|
||||
storageScreenController.cancelAdventure(cancelAdventureDialog!!.id) {
|
||||
navController.navigate(NavigationItems.Storage.route)
|
||||
}
|
||||
cancelAdventureDialog = null
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.github.nacabaro.vbhelper.screens.adventureScreen
|
||||
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
|
||||
interface AdventureScreenController {
|
||||
fun sendCharacterToAdventure(characterId: Long, timeInMinutes: Long)
|
||||
fun getItemFromAdventure(characterId: Long, onResult: (ItemDtos.PurchasedItem) -> Unit)
|
||||
fun cancelAdventure(characterId: Long, onResult: () -> Unit)
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
package com.github.nacabaro.vbhelper.screens.adventureScreen
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.random.Random
|
||||
|
||||
class AdventureScreenControllerImpl(
|
||||
private val componentActivity: ComponentActivity,
|
||||
) : AdventureScreenController {
|
||||
private val application = componentActivity.applicationContext as VBHelper
|
||||
private val database = application.container.db
|
||||
|
||||
override fun sendCharacterToAdventure(characterId: Long, timeInMinutes: Long) {
|
||||
val finishesAdventureAt = timeInMinutes * 60
|
||||
componentActivity.lifecycleScope.launch(Dispatchers.IO) {
|
||||
val characterData = database
|
||||
.userCharacterDao()
|
||||
.getCharacter(characterId)
|
||||
|
||||
if (characterData.isActive) {
|
||||
database
|
||||
.userCharacterDao()
|
||||
.clearActiveCharacter()
|
||||
}
|
||||
|
||||
database
|
||||
.adventureDao()
|
||||
.insertNewAdventure(characterId, timeInMinutes, finishesAdventureAt)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemFromAdventure(
|
||||
characterId: Long,
|
||||
onResult: (ItemDtos.PurchasedItem) -> Unit
|
||||
) {
|
||||
componentActivity.lifecycleScope.launch(Dispatchers.IO) {
|
||||
database
|
||||
.adventureDao()
|
||||
.deleteAdventure(characterId)
|
||||
|
||||
val generatedItem = generateItem(characterId)
|
||||
|
||||
onResult(generatedItem)
|
||||
}
|
||||
}
|
||||
|
||||
override fun cancelAdventure(characterId: Long, onResult: () -> Unit) {
|
||||
componentActivity.lifecycleScope.launch(Dispatchers.IO) {
|
||||
database
|
||||
.adventureDao()
|
||||
.deleteAdventure(characterId)
|
||||
|
||||
componentActivity
|
||||
.runOnUiThread {
|
||||
Toast.makeText(
|
||||
componentActivity,
|
||||
"Adventure canceled",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
onResult()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun generateItem(characterId: Long): ItemDtos.PurchasedItem {
|
||||
val character = database
|
||||
.userCharacterDao()
|
||||
.getCharacterInfo(characterId)
|
||||
|
||||
val randomItem = database
|
||||
.itemDao()
|
||||
.getAllItems()
|
||||
.random()
|
||||
|
||||
val random = ((Random.nextFloat() * character.stage) + 3).roundToInt()
|
||||
|
||||
database
|
||||
.itemDao()
|
||||
.purchaseItem(
|
||||
itemId = randomItem.id,
|
||||
itemAmount = random
|
||||
)
|
||||
|
||||
return ItemDtos.PurchasedItem(
|
||||
itemId = randomItem.id,
|
||||
itemAmount = random,
|
||||
itemName = randomItem.name,
|
||||
itemIcon = randomItem.itemIcon,
|
||||
itemLength = randomItem.itemLength,
|
||||
itemDescription = randomItem.description,
|
||||
itemType = randomItem.itemType
|
||||
)
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package com.github.nacabaro.vbhelper.screens.adventureScreen
|
||||
|
||||
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.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.FilterQuality
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||
import com.github.nacabaro.vbhelper.utils.getBitmap
|
||||
|
||||
@Composable
|
||||
fun CancelAdventureDialog(
|
||||
characterSprite: BitmapData,
|
||||
onDismissRequest: () -> Unit,
|
||||
onClickConfirm: () -> Unit
|
||||
) {
|
||||
val bitmap = remember (characterSprite) { characterSprite.getBitmap() }
|
||||
val imageBitmap = remember(bitmap) { bitmap.asImageBitmap() }
|
||||
val density: Float = LocalContext.current.resources.displayMetrics.density
|
||||
val dpSize = (characterSprite.width * 4 / density).dp
|
||||
|
||||
Dialog(
|
||||
onDismissRequest = onDismissRequest
|
||||
) {
|
||||
Card {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Row {
|
||||
Image(
|
||||
bitmap = imageBitmap,
|
||||
contentDescription = null,
|
||||
filterQuality = FilterQuality.None,
|
||||
modifier = Modifier
|
||||
.size(dpSize)
|
||||
)
|
||||
Text(
|
||||
text = "Are you sure you want to cancel this character's adventure?"
|
||||
)
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
) {
|
||||
Button(
|
||||
onClick = onClickConfirm
|
||||
) {
|
||||
Text(text = "Confirm")
|
||||
}
|
||||
Spacer(modifier = Modifier.padding(4.dp))
|
||||
Button(
|
||||
onClick = onDismissRequest
|
||||
) {
|
||||
Text(text = "Dismiss")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+122
@@ -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: -")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+63
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.github.nacabaro.vbhelper.screens.cardScreen
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.Edit
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.FilterQuality
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||
import com.github.nacabaro.vbhelper.utils.getBitmap
|
||||
|
||||
@Composable
|
||||
fun CardEntry(
|
||||
name: String,
|
||||
logo: BitmapData,
|
||||
obtainedCharacters: Int,
|
||||
totalCharacters: Int,
|
||||
onClick: () -> Unit,
|
||||
displayModify: Boolean,
|
||||
onClickModify: () -> Unit,
|
||||
onClickDelete: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val bitmap = remember (logo.bitmap) { logo.getBitmap() }
|
||||
val imageBitmap = remember(bitmap) { bitmap.asImageBitmap() }
|
||||
val density: Float = LocalContext.current.resources.displayMetrics.density
|
||||
val dpSize = (logo.width * 4 / density).dp
|
||||
|
||||
Card (
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
modifier = modifier,
|
||||
onClick = if (!displayModify) {
|
||||
onClick
|
||||
} else {
|
||||
{ }
|
||||
}
|
||||
) {
|
||||
Row (
|
||||
horizontalArrangement = Arrangement.Start,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
) {
|
||||
Image (
|
||||
bitmap = imageBitmap,
|
||||
contentDescription = name,
|
||||
filterQuality = FilterQuality.None,
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
.size(dpSize)
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
.weight(1f)
|
||||
) {
|
||||
Text(
|
||||
text = name,
|
||||
modifier = Modifier
|
||||
)
|
||||
Text(
|
||||
text = "$obtainedCharacters of $totalCharacters characters obtained",
|
||||
fontFamily = MaterialTheme.typography.labelSmall.fontFamily,
|
||||
fontSize = MaterialTheme.typography.labelSmall.fontSize,
|
||||
modifier = Modifier
|
||||
)
|
||||
}
|
||||
if (displayModify) {
|
||||
Row (
|
||||
modifier = Modifier,
|
||||
horizontalArrangement = Arrangement.End,
|
||||
) {
|
||||
IconButton(
|
||||
onClick = onClickModify
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Edit,
|
||||
contentDescription = "Edit"
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
onClick = onClickDelete
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Delete,
|
||||
contentDescription = "Delete"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +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
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
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(
|
||||
private val componentActivity: ComponentActivity,
|
||||
) : CardScreenController {
|
||||
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
|
||||
.cardDao()
|
||||
.renameCard(cardId.toInt(), newName)
|
||||
|
||||
onRenamed(newName)
|
||||
}
|
||||
}
|
||||
|
||||
override fun deleteCard(cardId: Long, onDeleted: () -> Unit) {
|
||||
componentActivity.lifecycleScope.launch {
|
||||
database
|
||||
.cardDao()
|
||||
.deleteCard(cardId)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
+38
-7
@@ -1,4 +1,4 @@
|
||||
package com.github.nacabaro.vbhelper.screens
|
||||
package com.github.nacabaro.vbhelper.screens.cardScreen
|
||||
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
@@ -14,27 +14,34 @@ import androidx.navigation.NavController
|
||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||
import com.github.nacabaro.vbhelper.components.CharacterEntry
|
||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Character
|
||||
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
|
||||
|
||||
@Composable
|
||||
fun DiMScreen(
|
||||
fun CardViewScreen(
|
||||
navController: NavController,
|
||||
dimId: Long
|
||||
cardId: Long
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val application = LocalContext.current.applicationContext as VBHelper
|
||||
val dexRepository = DexRepository(application.container.db)
|
||||
|
||||
val characterList = remember { mutableStateOf<List<CharacterDtos.CardProgress>>(emptyList()) }
|
||||
val characterList = remember { mutableStateOf<List<CharacterDtos.CardCharaProgress>>(emptyList()) }
|
||||
val cardPossibleTransformations = remember { mutableStateOf<List<CharacterDtos.EvolutionRequirementsWithSpritesAndObtained>>(emptyList()) }
|
||||
|
||||
val selectedCharacter = remember { mutableStateOf<CharacterDtos.CardCharaProgress?>(null) }
|
||||
|
||||
LaunchedEffect(dexRepository) {
|
||||
coroutineScope.launch {
|
||||
val newCharacterList = dexRepository.getCharactersByDimId(dimId)
|
||||
val newCharacterList = dexRepository.getCharactersByCardId(cardId)
|
||||
characterList.value = newCharacterList
|
||||
|
||||
val newCardPossibleTransformations = dexRepository.getCardPossibleTransformations(cardId)
|
||||
cardPossibleTransformations.value = newCardPossibleTransformations
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +51,17 @@ fun DiMScreen(
|
||||
text = "Discovered characters",
|
||||
onBackClick = {
|
||||
navController.popBackStack()
|
||||
},
|
||||
onAdventureClick = {
|
||||
navController
|
||||
.navigate(route = NavigationItems
|
||||
.CardAdventure
|
||||
.route
|
||||
.replace(
|
||||
"{cardId}",
|
||||
cardId.toString()
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -54,7 +72,9 @@ fun DiMScreen(
|
||||
) {
|
||||
items(characterList.value) { character ->
|
||||
CharacterEntry(
|
||||
onClick = { },
|
||||
onClick = {
|
||||
selectedCharacter.value = character
|
||||
},
|
||||
obscure = character.discoveredOn == null,
|
||||
icon = BitmapData(
|
||||
bitmap = character.spriteIdle,
|
||||
@@ -64,5 +84,16 @@ fun DiMScreen(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedCharacter.value != null) {
|
||||
DexCharaDetailsDialog(
|
||||
currentChara = selectedCharacter.value!!,
|
||||
possibleTransformations = cardPossibleTransformations.value,
|
||||
obscure = selectedCharacter.value!!.discoveredOn == null,
|
||||
onClickClose = {
|
||||
selectedCharacter.value = null
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package com.github.nacabaro.vbhelper.screens.cardScreen
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.dtos.CardDtos
|
||||
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||
import com.github.nacabaro.vbhelper.screens.cardScreen.dialogs.CardDeleteDialog
|
||||
import com.github.nacabaro.vbhelper.screens.cardScreen.dialogs.CardRenameDialog
|
||||
import com.github.nacabaro.vbhelper.source.DexRepository
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun CardsScreen(
|
||||
navController: NavController,
|
||||
cardScreenController: CardScreenControllerImpl
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val application = LocalContext.current.applicationContext as VBHelper
|
||||
val dexRepository = DexRepository(application.container.db)
|
||||
val cardList = remember { mutableStateOf<List<CardDtos.CardProgress>>(emptyList()) }
|
||||
|
||||
val selectedCard = remember { mutableStateOf<CardDtos.CardProgress?>(null) }
|
||||
var clickedDelete by remember { mutableStateOf(false) }
|
||||
var clickedRename by remember { mutableStateOf(false) }
|
||||
|
||||
var modifyCards by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(dexRepository) {
|
||||
coroutineScope.launch {
|
||||
val newDimList = dexRepository.getAllDims()
|
||||
cardList.value = newDimList
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold (
|
||||
topBar = {
|
||||
TopBanner(
|
||||
text = "My cards",
|
||||
onModifyClick = {
|
||||
modifyCards = !modifyCards
|
||||
}
|
||||
)
|
||||
}
|
||||
) { contentPadding ->
|
||||
LazyColumn (
|
||||
modifier = Modifier
|
||||
.padding(top = contentPadding.calculateTopPadding())
|
||||
) {
|
||||
items(cardList.value) {
|
||||
CardEntry(
|
||||
name = it.cardName,
|
||||
logo = BitmapData(
|
||||
bitmap = it.cardLogo,
|
||||
width = it.logoWidth,
|
||||
height = it.logoHeight
|
||||
),
|
||||
onClick = {
|
||||
navController
|
||||
.navigate(
|
||||
NavigationItems
|
||||
.CardView.route
|
||||
.replace("{cardId}", "${it.cardId}")
|
||||
)
|
||||
},
|
||||
obtainedCharacters = it.obtainedCharacters,
|
||||
totalCharacters = it.totalCharacters,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp),
|
||||
displayModify = modifyCards,
|
||||
onClickModify = {
|
||||
selectedCard.value = it
|
||||
clickedRename = true
|
||||
},
|
||||
onClickDelete = {
|
||||
selectedCard.value = it
|
||||
clickedDelete = true
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (clickedRename) {
|
||||
CardRenameDialog(
|
||||
onDismiss = {
|
||||
clickedRename = false
|
||||
selectedCard.value = null
|
||||
},
|
||||
onRename = { newName ->
|
||||
Log.d("CardsScreen", "New name: $newName")
|
||||
Log.d("CardsScreen", "Card: ${selectedCard.value.toString()}")
|
||||
cardScreenController
|
||||
.renameCard(
|
||||
cardId = selectedCard.value!!.cardId,
|
||||
newName = newName,
|
||||
onRenamed = {
|
||||
clickedRename = false
|
||||
selectedCard.value = null
|
||||
}
|
||||
)
|
||||
},
|
||||
currentName = selectedCard.value!!.cardName
|
||||
)
|
||||
}
|
||||
|
||||
if (clickedDelete) {
|
||||
CardDeleteDialog(
|
||||
cardName = selectedCard.value!!.cardName,
|
||||
onDismiss = {
|
||||
clickedDelete = false
|
||||
selectedCard.value = null
|
||||
},
|
||||
onConfirm = {
|
||||
cardScreenController
|
||||
.deleteCard(
|
||||
cardId = selectedCard.value!!.cardId,
|
||||
onDeleted = {
|
||||
clickedDelete = false
|
||||
selectedCard.value = null
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.github.nacabaro.vbhelper.screens.cardScreen.dialogs
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
|
||||
@Composable
|
||||
fun CardDeleteDialog(
|
||||
cardName: String,
|
||||
onDismiss: () -> Unit,
|
||||
onConfirm: () -> Unit
|
||||
) {
|
||||
Dialog(
|
||||
onDismissRequest = onDismiss
|
||||
|
||||
) {
|
||||
Card ( ) {
|
||||
Column (
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Text(text = "Are you sure you want to delete $cardName. This action will also delete all the characters raised from this card.")
|
||||
Spacer(modifier = Modifier.padding(8.dp))
|
||||
Row {
|
||||
Button(
|
||||
onClick = {
|
||||
onDismiss()
|
||||
}
|
||||
) {
|
||||
Text(text = "Confirm")
|
||||
}
|
||||
Button(
|
||||
onClick = {
|
||||
onConfirm()
|
||||
}
|
||||
) {
|
||||
Text(text = "Delete")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.github.nacabaro.vbhelper.screens.cardScreen.dialogs
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
|
||||
@Composable
|
||||
fun CardRenameDialog(
|
||||
onDismiss: () -> Unit,
|
||||
onRename: (String) -> Unit,
|
||||
currentName: String
|
||||
) {
|
||||
var cardName by remember { mutableStateOf(currentName) }
|
||||
|
||||
Dialog(
|
||||
onDismissRequest = onDismiss
|
||||
|
||||
) {
|
||||
Card ( ) {
|
||||
Column (
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
TextField(
|
||||
value = cardName,
|
||||
onValueChange = { cardName = it }
|
||||
)
|
||||
Spacer(modifier = Modifier.padding(8.dp))
|
||||
Button(
|
||||
onClick = {
|
||||
onRename(cardName)
|
||||
onDismiss()
|
||||
}
|
||||
) {
|
||||
Text(text = "Rename")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
package com.github.nacabaro.vbhelper.screens.cardScreen.dialogs
|
||||
|
||||
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.Button
|
||||
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.Alignment
|
||||
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 androidx.compose.ui.window.Dialog
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||
import com.github.nacabaro.vbhelper.utils.getImageBitmap
|
||||
|
||||
|
||||
@Composable
|
||||
fun DexCharaDetailsDialog(
|
||||
currentChara: CharacterDtos.CardCharaProgress,
|
||||
possibleTransformations: List<CharacterDtos.EvolutionRequirementsWithSpritesAndObtained>,
|
||||
obscure: Boolean,
|
||||
onClickClose: () -> Unit
|
||||
) {
|
||||
val nameMultiplier = 3
|
||||
val charaMultiplier = 4
|
||||
|
||||
val currentCharaPossibleTransformations = possibleTransformations.filter { it.fromCharaId == currentChara.id }
|
||||
|
||||
val romanNumeralsStage = when (currentChara.stage) {
|
||||
1 -> "II"
|
||||
2 -> "III"
|
||||
3 -> "IV"
|
||||
4 -> "V"
|
||||
5 -> "VI"
|
||||
6 -> "VII"
|
||||
else -> "I"
|
||||
}
|
||||
|
||||
val charaBitmapData = BitmapData(
|
||||
bitmap = currentChara.spriteIdle,
|
||||
width = currentChara.spriteWidth,
|
||||
height = currentChara.spriteHeight
|
||||
)
|
||||
val charaImageBitmapData = charaBitmapData.getImageBitmap(
|
||||
context = LocalContext.current,
|
||||
multiplier = charaMultiplier,
|
||||
obscure = obscure
|
||||
)
|
||||
|
||||
val nameBitmapData = BitmapData(
|
||||
bitmap = currentChara.nameSprite,
|
||||
width = currentChara.nameSpriteWidth,
|
||||
height = currentChara.nameSpriteHeight
|
||||
)
|
||||
val nameImageBitmapData = nameBitmapData.getImageBitmap(
|
||||
context = LocalContext.current,
|
||||
multiplier = nameMultiplier,
|
||||
obscure = obscure
|
||||
)
|
||||
|
||||
Dialog(
|
||||
onDismissRequest = onClickClose
|
||||
) {
|
||||
Card (
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
Column (
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Row (
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
) {
|
||||
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(16.dp)
|
||||
)
|
||||
if (!obscure) {
|
||||
Column {
|
||||
Image(
|
||||
bitmap = nameImageBitmapData.imageBitmap,
|
||||
contentDescription = "Icon",
|
||||
modifier = Modifier
|
||||
.width(nameImageBitmapData.dpWidth)
|
||||
.height(nameImageBitmapData.dpHeight),
|
||||
filterQuality = FilterQuality.None
|
||||
)
|
||||
Spacer(modifier = Modifier.padding(4.dp))
|
||||
if (currentChara.baseHp != 65535) {
|
||||
Text(
|
||||
text = "HP: ${currentChara.baseHp}, BP: ${currentChara.baseBp}, AP: ${currentChara.baseAp}"
|
||||
)
|
||||
Text(text = "Stg: ${romanNumeralsStage}, Atr: ${currentChara.attribute.toString().substring(0, 2)}")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Column {
|
||||
Text(text = "????????????????")
|
||||
Spacer(modifier = Modifier.padding(4.dp))
|
||||
Text(text = "Stg: -, Atr: -")
|
||||
Text(text = "HP: -, BP: -, AP: -")
|
||||
}
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.padding(16.dp))
|
||||
Column {
|
||||
currentCharaPossibleTransformations.map {
|
||||
val selectedCharaBitmap = BitmapData(
|
||||
bitmap = it.spriteIdle,
|
||||
width = it.spriteWidth,
|
||||
height = it.spriteHeight
|
||||
)
|
||||
val selectedCharaImageBitmap = selectedCharaBitmap.getImageBitmap(
|
||||
context = LocalContext.current,
|
||||
multiplier = 4,
|
||||
obscure = it.discoveredOn == null
|
||||
)
|
||||
|
||||
Card (
|
||||
modifier = Modifier
|
||||
.padding(vertical = 8.dp)
|
||||
) {
|
||||
Row (
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
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 = selectedCharaImageBitmap.imageBitmap,
|
||||
contentDescription = "Icon",
|
||||
modifier = Modifier
|
||||
.size(selectedCharaImageBitmap.dpWidth)
|
||||
.padding(8.dp),
|
||||
colorFilter = when (it.discoveredOn == null) {
|
||||
true -> ColorFilter.tint(color = MaterialTheme.colorScheme.secondary)
|
||||
false -> null
|
||||
},
|
||||
filterQuality = FilterQuality.None
|
||||
)
|
||||
}
|
||||
Spacer(
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
)
|
||||
Column {
|
||||
Text("Tr: ${it.requiredTrophies}; Bt: ${it.requiredBattles}; Vr: ${it.requiredVitals}; Wr: ${it.requiredWinRate}%; Ct: ${it.changeTimerHours}h")
|
||||
Text("AdvLvl ${it.requiredAdventureLevelCompleted + 1}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button(
|
||||
onClick = onClickClose
|
||||
) {
|
||||
Text("Close")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.github.nacabaro.vbhelper.screens.homeScreens
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
|
||||
@Composable
|
||||
fun BetaWarning(
|
||||
onDismissRequest: () -> Unit
|
||||
) {
|
||||
Dialog(
|
||||
onDismissRequest = onDismissRequest
|
||||
) {
|
||||
Card {
|
||||
Column (
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "This application is currently in alpha and it is not complete. Do not use to store important characters for you, as any future updates might delete all your characters. Sorry for the inconvenience!"
|
||||
)
|
||||
Spacer(modifier = Modifier.padding(8.dp))
|
||||
Text(
|
||||
text = "Application should work now with the original VB and the VH."
|
||||
)
|
||||
Spacer(modifier = Modifier.padding(8.dp))
|
||||
Text(
|
||||
text = "Thank you for your understanding and patience. Sincerely, the dev team."
|
||||
)
|
||||
Spacer(modifier = Modifier.padding(8.dp))
|
||||
Button(
|
||||
onClick = onDismissRequest
|
||||
) {
|
||||
Text(text = "Dismiss")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,50 @@
|
||||
package com.github.nacabaro.vbhelper.screens.homeScreens
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.navigation.NavController
|
||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.utils.DeviceType
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||
import com.github.nacabaro.vbhelper.screens.homeScreens.screens.BEBEmHomeScreen
|
||||
import com.github.nacabaro.vbhelper.screens.homeScreens.screens.BEDiMHomeScreen
|
||||
import com.github.nacabaro.vbhelper.screens.homeScreens.screens.VBDiMHomeScreen
|
||||
import com.github.nacabaro.vbhelper.screens.itemsScreen.ObtainedItemDialog
|
||||
import com.github.nacabaro.vbhelper.source.StorageRepository
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@Composable
|
||||
fun HomeScreen(
|
||||
navController: NavController
|
||||
navController: NavController,
|
||||
homeScreenController: HomeScreenControllerImpl
|
||||
) {
|
||||
val application = LocalContext.current.applicationContext as VBHelper
|
||||
val storageRepository = StorageRepository(application.container.db)
|
||||
@@ -35,17 +52,32 @@ fun HomeScreen(
|
||||
val transformationHistory = remember { mutableStateOf<List<CharacterDtos.TransformationHistory>?>(null) }
|
||||
val beData = remember { mutableStateOf<BECharacterData?>(null) }
|
||||
val vbData = remember { mutableStateOf<VBCharacterData?>(null) }
|
||||
val vbSpecialMissions = remember { mutableStateOf<List<SpecialMissions>>(emptyList()) }
|
||||
var adventureMissionsFinished by rememberSaveable { mutableStateOf(false) }
|
||||
var betaWarning by rememberSaveable { mutableStateOf(true) }
|
||||
var collectedItem by remember { mutableStateOf<ItemDtos.PurchasedItem?>(null) }
|
||||
|
||||
LaunchedEffect(storageRepository, activeMon) {
|
||||
LaunchedEffect(storageRepository, activeMon, collectedItem) {
|
||||
withContext(Dispatchers.IO) {
|
||||
activeMon.value = storageRepository.getActiveCharacter()
|
||||
if (activeMon.value != null) {
|
||||
if (activeMon.value != null && activeMon.value!!.characterType == DeviceType.BEDevice) {
|
||||
beData.value = storageRepository.getCharacterBeData(activeMon.value!!.id)
|
||||
transformationHistory.value = storageRepository.getTransformationHistory(activeMon.value!!.id)
|
||||
} else if (activeMon.value != null && activeMon.value!!.characterType == DeviceType.VBDevice) {
|
||||
vbData.value = storageRepository.getCharacterVbData(activeMon.value!!.id)
|
||||
vbSpecialMissions.value = storageRepository.getSpecialMissions(activeMon.value!!.id)
|
||||
transformationHistory.value = storageRepository.getTransformationHistory(activeMon.value!!.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(true) {
|
||||
homeScreenController
|
||||
.didAdventureMissionsFinish {
|
||||
adventureMissionsFinished = it
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold (
|
||||
topBar = {
|
||||
TopBanner(
|
||||
@@ -60,6 +92,7 @@ fun HomeScreen(
|
||||
}
|
||||
) { contentPadding ->
|
||||
if (activeMon.value == null || (beData.value == null && vbData.value == null) || transformationHistory.value == null) {
|
||||
Log.d("TetTet", "Something is null")
|
||||
Column (
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
@@ -70,6 +103,7 @@ fun HomeScreen(
|
||||
Text(text = "Nothing to see here")
|
||||
}
|
||||
} else {
|
||||
Log.d("TetTet", "Something is not null")
|
||||
if (activeMon.value!!.isBemCard) {
|
||||
BEBEmHomeScreen(
|
||||
activeMon = activeMon.value!!,
|
||||
@@ -89,11 +123,59 @@ fun HomeScreen(
|
||||
activeMon = activeMon.value!!,
|
||||
vbData = vbData.value!!,
|
||||
transformationHistory = transformationHistory.value!!,
|
||||
contentPadding = contentPadding
|
||||
contentPadding = contentPadding,
|
||||
specialMissions = vbSpecialMissions.value,
|
||||
homeScreenController = homeScreenController,
|
||||
onClickCollect = { item ->
|
||||
collectedItem = item
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (collectedItem != null) {
|
||||
ObtainedItemDialog(
|
||||
obtainedItem = collectedItem!!,
|
||||
onClickDismiss = {
|
||||
collectedItem = null
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (adventureMissionsFinished) {
|
||||
Dialog(
|
||||
onDismissRequest = { adventureMissionsFinished = false },
|
||||
) {
|
||||
Card {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "One of your characters has finished their adventure mission!",
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
Button(
|
||||
onClick = {
|
||||
adventureMissionsFinished = false
|
||||
},
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
Text(text = "Dismiss")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (betaWarning) {
|
||||
BetaWarning {
|
||||
betaWarning = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.github.nacabaro.vbhelper.screens.homeScreens
|
||||
|
||||
import com.github.cfogrady.vbnfc.vb.SpecialMission
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
|
||||
interface HomeScreenController {
|
||||
fun didAdventureMissionsFinish(onCompletion: (Boolean) -> Unit)
|
||||
fun clearSpecialMission(missionId: Long, missionCompletion: SpecialMission.Status, onCleared: (ItemDtos.PurchasedItem?) -> Unit)
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
package com.github.nacabaro.vbhelper.screens.homeScreens
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.cfogrady.vbnfc.vb.SpecialMission
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
import kotlinx.coroutines.launch
|
||||
import java.time.Instant
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.random.Random
|
||||
|
||||
class HomeScreenControllerImpl(
|
||||
private val componentActivity: ComponentActivity,
|
||||
): HomeScreenController {
|
||||
private val application = componentActivity.applicationContext as VBHelper
|
||||
private val database = application.container.db
|
||||
|
||||
override fun didAdventureMissionsFinish(onCompletion: (Boolean) -> Unit) {
|
||||
componentActivity.lifecycleScope.launch {
|
||||
val currentTime = Instant.now().epochSecond
|
||||
val adventureCharacters = database
|
||||
.adventureDao()
|
||||
.getAdventureCharacters()
|
||||
|
||||
val finishedAdventureCharacters = adventureCharacters.filter { character ->
|
||||
character.finishesAdventure <= currentTime
|
||||
}
|
||||
|
||||
onCompletion(finishedAdventureCharacters.isNotEmpty())
|
||||
}
|
||||
}
|
||||
|
||||
override fun clearSpecialMission(missionId: Long, missionCompletion: SpecialMission.Status, onCleared: (ItemDtos.PurchasedItem?) -> Unit) {
|
||||
componentActivity.lifecycleScope.launch {
|
||||
database
|
||||
.specialMissionDao()
|
||||
.clearSpecialMission(missionId)
|
||||
|
||||
if (missionCompletion == SpecialMission.Status.COMPLETED) {
|
||||
val randomItem = database
|
||||
.itemDao()
|
||||
.getAllItems()
|
||||
.random()
|
||||
|
||||
val randomItemAmount = (Random.nextFloat() * 5).roundToInt()
|
||||
|
||||
database
|
||||
.itemDao()
|
||||
.purchaseItem(
|
||||
itemId = randomItem.id,
|
||||
itemAmount = randomItemAmount
|
||||
)
|
||||
|
||||
val purchasedItem = ItemDtos.PurchasedItem(
|
||||
itemId = randomItem.id,
|
||||
itemName = randomItem.name,
|
||||
itemDescription = randomItem.description,
|
||||
itemIcon = randomItem.itemIcon,
|
||||
itemLength = randomItem.itemLength,
|
||||
itemAmount = randomItemAmount,
|
||||
itemType = randomItem.itemType
|
||||
)
|
||||
|
||||
onCleared(purchasedItem)
|
||||
} else {
|
||||
onCleared(null)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.github.nacabaro.vbhelper.screens.homeScreens
|
||||
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
|
||||
@Composable
|
||||
fun VBDiMHomeScreen(
|
||||
activeMon: CharacterDtos.CharacterWithSprites,
|
||||
vbData: VBCharacterData,
|
||||
transformationHistory: List<CharacterDtos.TransformationHistory>,
|
||||
contentPadding: PaddingValues
|
||||
) {
|
||||
TODO("Not implemented yet")
|
||||
}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package com.github.nacabaro.vbhelper.screens.homeScreens
|
||||
package com.github.nacabaro.vbhelper.screens.homeScreens.screens
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
@@ -15,7 +15,7 @@ import com.github.nacabaro.vbhelper.R
|
||||
import com.github.nacabaro.vbhelper.components.CharacterEntry
|
||||
import com.github.nacabaro.vbhelper.components.ItemDisplay
|
||||
import com.github.nacabaro.vbhelper.components.TransformationHistoryCard
|
||||
import com.github.nacabaro.vbhelper.components.getIconResource
|
||||
import com.github.nacabaro.vbhelper.screens.itemsScreen.getIconResource
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import com.github.nacabaro.vbhelper.screens.itemsScreen.ItemsScreenControllerImpl
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package com.github.nacabaro.vbhelper.screens.homeScreens
|
||||
package com.github.nacabaro.vbhelper.screens.homeScreens.screens
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
@@ -16,7 +16,7 @@ import com.github.nacabaro.vbhelper.R
|
||||
import com.github.nacabaro.vbhelper.components.CharacterEntry
|
||||
import com.github.nacabaro.vbhelper.components.ItemDisplay
|
||||
import com.github.nacabaro.vbhelper.components.TransformationHistoryCard
|
||||
import com.github.nacabaro.vbhelper.components.getIconResource
|
||||
import com.github.nacabaro.vbhelper.screens.itemsScreen.getIconResource
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import com.github.nacabaro.vbhelper.screens.itemsScreen.ItemsScreenControllerImpl
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
package com.github.nacabaro.vbhelper.screens.homeScreens.screens
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.github.nacabaro.vbhelper.R
|
||||
import com.github.nacabaro.vbhelper.components.CharacterEntry
|
||||
import com.github.nacabaro.vbhelper.components.ItemDisplay
|
||||
import com.github.nacabaro.vbhelper.components.SpecialMissionsEntry
|
||||
import com.github.nacabaro.vbhelper.components.TransformationHistoryCard
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
import com.github.nacabaro.vbhelper.screens.homeScreens.HomeScreenControllerImpl
|
||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||
import java.util.Locale
|
||||
|
||||
@Composable
|
||||
fun VBDiMHomeScreen(
|
||||
activeMon: CharacterDtos.CharacterWithSprites,
|
||||
vbData: VBCharacterData,
|
||||
specialMissions: List<SpecialMissions>,
|
||||
homeScreenController: HomeScreenControllerImpl,
|
||||
transformationHistory: List<CharacterDtos.TransformationHistory>,
|
||||
contentPadding: PaddingValues,
|
||||
onClickCollect: (ItemDtos.PurchasedItem?) -> Unit
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(top = contentPadding.calculateTopPadding())
|
||||
.verticalScroll(state = rememberScrollState())
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
CharacterEntry(
|
||||
icon = BitmapData(
|
||||
bitmap = activeMon.spriteIdle,
|
||||
width = activeMon.spriteWidth,
|
||||
height = activeMon.spriteHeight
|
||||
),
|
||||
multiplier = 8,
|
||||
shape = androidx.compose.material.MaterialTheme.shapes.small,
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.aspectRatio(1f)
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.weight(0.5f)
|
||||
.aspectRatio(0.5f)
|
||||
) {
|
||||
ItemDisplay(
|
||||
icon = R.drawable.baseline_vitals_24,
|
||||
textValue = activeMon.vitalPoints.toString(),
|
||||
definition = "Vitals",
|
||||
modifier = Modifier
|
||||
.weight(0.5f)
|
||||
.aspectRatio(1f)
|
||||
.padding(8.dp)
|
||||
)
|
||||
ItemDisplay(
|
||||
icon = R.drawable.baseline_trophy_24,
|
||||
textValue = activeMon.trophies.toString(),
|
||||
definition = "Trophies",
|
||||
modifier = Modifier
|
||||
.weight(0.5f)
|
||||
.aspectRatio(1f)
|
||||
.padding(8.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
ItemDisplay(
|
||||
icon = R.drawable.baseline_mood_24,
|
||||
textValue = activeMon.mood.toString(),
|
||||
definition = "Mood",
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.aspectRatio(1f)
|
||||
.padding(8.dp)
|
||||
)
|
||||
val transformationCountdownInHours = activeMon.transformationCountdown / 60
|
||||
ItemDisplay(
|
||||
icon = R.drawable.baseline_next_24,
|
||||
textValue = when (transformationCountdownInHours) {
|
||||
0 -> "${activeMon.transformationCountdown} m"
|
||||
else -> "$transformationCountdownInHours h"
|
||||
},
|
||||
definition = "Next timer",
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.aspectRatio(1f)
|
||||
.padding(8.dp)
|
||||
)
|
||||
ItemDisplay(
|
||||
icon = R.drawable.baseline_swords_24,
|
||||
textValue = when {
|
||||
activeMon.totalBattlesLost == 0 -> "0.00 %"
|
||||
else -> {
|
||||
val battleWinPercentage =
|
||||
activeMon.totalBattlesWon.toFloat() / (activeMon.totalBattlesWon + activeMon.totalBattlesLost).toFloat()
|
||||
String.format(
|
||||
Locale.getDefault(),
|
||||
"%.2f",
|
||||
battleWinPercentage * 100
|
||||
) + " %" // Specify locale
|
||||
}
|
||||
},
|
||||
definition = "Total battle win %",
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.aspectRatio(1f)
|
||||
.padding(8.dp)
|
||||
)
|
||||
ItemDisplay(
|
||||
icon = R.drawable.baseline_swords_24,
|
||||
textValue = when {
|
||||
activeMon.totalBattlesLost == 0 -> "0.00 %"
|
||||
else -> {
|
||||
val battleWinPercentage =
|
||||
activeMon.currentPhaseBattlesWon.toFloat() / (activeMon.currentPhaseBattlesWon + activeMon.currentPhaseBattlesLost).toFloat()
|
||||
String.format(
|
||||
Locale.getDefault(),
|
||||
"%.2f",
|
||||
battleWinPercentage * 100
|
||||
) + " %" // Specify locale
|
||||
}
|
||||
},
|
||||
definition = "Current phase win %",
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.aspectRatio(1f)
|
||||
.padding(8.dp)
|
||||
)
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
TransformationHistoryCard(
|
||||
transformationHistory = transformationHistory,
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(8.dp)
|
||||
)
|
||||
}
|
||||
Row (
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "Special missions",
|
||||
fontSize = 24.sp
|
||||
)
|
||||
}
|
||||
for (mission in specialMissions) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
SpecialMissionsEntry(
|
||||
specialMission = mission,
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(8.dp),
|
||||
) {
|
||||
homeScreenController
|
||||
.clearSpecialMission(mission.id, mission.status, onClickCollect)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
-1
@@ -19,7 +19,9 @@ import androidx.navigation.NavController
|
||||
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.domain.items.ItemType
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
import com.github.nacabaro.vbhelper.source.StorageRepository
|
||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -39,10 +41,25 @@ fun ChooseCharacterScreen(
|
||||
}
|
||||
|
||||
var selectedCharacter by remember { mutableStateOf<Long?>(null) }
|
||||
var selectedItem by remember { mutableStateOf<ItemDtos.ItemsWithQuantities?>(null) }
|
||||
|
||||
LaunchedEffect(storageRepository) {
|
||||
coroutineScope.launch {
|
||||
characterList.value = storageRepository.getAllCharacters()
|
||||
selectedItem = storageRepository.getItem(itemId)
|
||||
when (selectedItem?.itemType) {
|
||||
ItemType.BEITEM -> {
|
||||
characterList.value = storageRepository.getBECharacters()
|
||||
}
|
||||
ItemType.VBITEM -> {
|
||||
characterList.value = storageRepository.getVBCharacters()
|
||||
}
|
||||
ItemType.SPECIALMISSION-> {
|
||||
characterList.value = storageRepository.getVBCharacters()
|
||||
}
|
||||
else -> {
|
||||
characterList.value = storageRepository.getAllCharacters()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -1,4 +1,4 @@
|
||||
package com.github.nacabaro.vbhelper.components
|
||||
package com.github.nacabaro.vbhelper.screens.itemsScreen
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@@ -25,7 +25,6 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import com.github.nacabaro.vbhelper.R
|
||||
import com.github.nacabaro.vbhelper.screens.itemsScreen.ItemsScreenControllerImpl
|
||||
import com.github.nacabaro.vbhelper.ui.theme.VBHelperTheme
|
||||
|
||||
@Composable
|
||||
@@ -123,7 +122,10 @@ fun ItemDialog(
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = MaterialTheme.typography.bodyMedium.fontSize,
|
||||
fontFamily = MaterialTheme.typography.bodyMedium.fontFamily,
|
||||
text = description
|
||||
text = description,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(4.dp)
|
||||
)
|
||||
Text(
|
||||
textAlign = TextAlign.Center,
|
||||
@@ -132,7 +134,7 @@ fun ItemDialog(
|
||||
text = "You have $amount of this item",
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
.padding(8.dp)
|
||||
)
|
||||
Row (
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
+96
-13
@@ -2,9 +2,12 @@ package com.github.nacabaro.vbhelper.screens.itemsScreen
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.cfogrady.vbnfc.vb.SpecialMission
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions
|
||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
import com.github.nacabaro.vbhelper.utils.DeviceType
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -24,7 +27,15 @@ class ItemsScreenControllerImpl (
|
||||
AllTraining(5),
|
||||
EvoTimer(6),
|
||||
LimitTimer(7),
|
||||
Vitals(8)
|
||||
Vitals(8),
|
||||
Step8k(9),
|
||||
Step4k(10),
|
||||
Vitals1000(11),
|
||||
Vitals250(12),
|
||||
Battle20(13),
|
||||
Battle5(14),
|
||||
Win10(15),
|
||||
Win4(16)
|
||||
}
|
||||
|
||||
init {
|
||||
@@ -37,17 +48,20 @@ class ItemsScreenControllerImpl (
|
||||
withContext(Dispatchers.IO) {
|
||||
val item = getItem(itemId)
|
||||
val characterData = database.userCharacterDao().getCharacter(characterId)
|
||||
val beCharacterData: BECharacterData
|
||||
//var vbCharacterData: VBCharacterData
|
||||
var beCharacterData: BECharacterData? = null
|
||||
var vbCharacterData: VBCharacterData? = null
|
||||
|
||||
if (characterData.characterType == DeviceType.BEDevice) {
|
||||
beCharacterData = database.userCharacterDao().getBeData(characterId)
|
||||
} else {
|
||||
TODO("Not implemented")
|
||||
//vbCharacterData = database.userCharacterDao().getVbData(characterId)
|
||||
} else if (characterData.characterType == DeviceType.VBDevice) {
|
||||
vbCharacterData = database.userCharacterDao().getVbData(characterId)
|
||||
}
|
||||
|
||||
if (item.itemIcon in 1 .. 5 && characterData.characterType == DeviceType.BEDevice) {
|
||||
if (
|
||||
item.itemIcon in 1 .. 5 &&
|
||||
characterData.characterType == DeviceType.BEDevice &&
|
||||
beCharacterData != null
|
||||
) {
|
||||
beCharacterData.itemType = item.itemIcon
|
||||
beCharacterData.itemMultiplier = 3
|
||||
beCharacterData.itemRemainingTime = item.itemLength
|
||||
@@ -72,7 +86,11 @@ class ItemsScreenControllerImpl (
|
||||
.userCharacterDao()
|
||||
.updateCharacter(characterData)
|
||||
|
||||
} else if (item.itemIcon == ItemTypes.LimitTimer.id) {
|
||||
} else if (
|
||||
item.itemIcon == ItemTypes.LimitTimer.id &&
|
||||
characterData.characterType == DeviceType.BEDevice &&
|
||||
beCharacterData != null
|
||||
) {
|
||||
beCharacterData.remainingTrainingTimeInMinutes += item.itemLength
|
||||
if (beCharacterData.remainingTrainingTimeInMinutes > 6000) {
|
||||
beCharacterData.remainingTrainingTimeInMinutes = 6000
|
||||
@@ -93,6 +111,12 @@ class ItemsScreenControllerImpl (
|
||||
database
|
||||
.userCharacterDao()
|
||||
.updateCharacter(characterData)
|
||||
|
||||
} else if (item.itemIcon in ItemTypes.Step8k.id .. ItemTypes.Win4.id &&
|
||||
characterData.characterType == DeviceType.VBDevice &&
|
||||
vbCharacterData != null
|
||||
) {
|
||||
applySpecialMission(item.itemIcon, item.itemLength, characterId)
|
||||
}
|
||||
|
||||
consumeItem(item.id)
|
||||
@@ -104,13 +128,72 @@ class ItemsScreenControllerImpl (
|
||||
}
|
||||
}
|
||||
|
||||
private fun getItem(itemId: Long): ItemDtos.ItemsWithQuantities {
|
||||
return database
|
||||
.itemDao()
|
||||
.getUserItem(itemId)
|
||||
private suspend fun applySpecialMission(itemIcon: Int, itemLength: Int, characterId: Long) {
|
||||
// Hello, it's me, naca! No! I don't like this, I'll see how I can improve it later on...
|
||||
val specialMissionType = when (itemIcon) {
|
||||
ItemTypes.Step8k.id -> SpecialMission.Type.STEPS
|
||||
ItemTypes.Step4k.id -> SpecialMission.Type.STEPS
|
||||
ItemTypes.Vitals1000.id -> SpecialMission.Type.VITALS
|
||||
ItemTypes.Vitals250.id -> SpecialMission.Type.VITALS
|
||||
ItemTypes.Battle20.id -> SpecialMission.Type.BATTLES
|
||||
ItemTypes.Battle5.id -> SpecialMission.Type.BATTLES
|
||||
ItemTypes.Win10.id -> SpecialMission.Type.WINS
|
||||
ItemTypes.Win4.id -> SpecialMission.Type.WINS
|
||||
else -> SpecialMission.Type.NONE
|
||||
}
|
||||
|
||||
val specialMissionGoal = when (itemIcon) {
|
||||
ItemTypes.Step8k.id -> 8000
|
||||
ItemTypes.Step4k.id -> 4000
|
||||
ItemTypes.Vitals1000.id -> 1000
|
||||
ItemTypes.Vitals250.id -> 250
|
||||
ItemTypes.Battle20.id -> 20
|
||||
ItemTypes.Battle5.id -> 5
|
||||
ItemTypes.Win10.id -> 10
|
||||
ItemTypes.Win4.id -> 4
|
||||
else -> 0
|
||||
}
|
||||
|
||||
val availableSpecialMissions = database
|
||||
.userCharacterDao()
|
||||
.getSpecialMissions(characterId)
|
||||
|
||||
var firstUnavailableMissionSlot: Long = 0
|
||||
var watchId = 0
|
||||
|
||||
for ((index, mission) in availableSpecialMissions.withIndex()) {
|
||||
if (
|
||||
mission.status == SpecialMission.Status.UNAVAILABLE
|
||||
) {
|
||||
firstUnavailableMissionSlot = mission.id
|
||||
watchId = index + 1
|
||||
}
|
||||
}
|
||||
|
||||
val newSpecialMission = SpecialMissions(
|
||||
id = firstUnavailableMissionSlot,
|
||||
characterId = characterId,
|
||||
missionType = specialMissionType,
|
||||
goal = specialMissionGoal,
|
||||
timeLimitInMinutes = itemLength,
|
||||
watchId = watchId,
|
||||
status = SpecialMission.Status.AVAILABLE,
|
||||
progress = 0,
|
||||
timeElapsedInMinutes = 0
|
||||
)
|
||||
|
||||
database
|
||||
.userCharacterDao()
|
||||
.insertSpecialMissions(newSpecialMission)
|
||||
}
|
||||
|
||||
private fun consumeItem(itemId: Long) {
|
||||
private suspend fun getItem(itemId: Long): ItemDtos.ItemsWithQuantities {
|
||||
return database
|
||||
.itemDao()
|
||||
.getItem(itemId)
|
||||
}
|
||||
|
||||
private suspend fun consumeItem(itemId: Long) {
|
||||
database
|
||||
.itemDao()
|
||||
.useItem(itemId)
|
||||
|
||||
@@ -15,10 +15,6 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import com.github.nacabaro.vbhelper.components.ItemDialog
|
||||
import com.github.nacabaro.vbhelper.components.ItemElement
|
||||
import com.github.nacabaro.vbhelper.components.getIconResource
|
||||
import com.github.nacabaro.vbhelper.components.getLengthResource
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
import com.github.nacabaro.vbhelper.source.ItemsRepository
|
||||
|
||||
@@ -19,10 +19,6 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import com.github.nacabaro.vbhelper.components.ItemDialog
|
||||
import com.github.nacabaro.vbhelper.components.ItemElement
|
||||
import com.github.nacabaro.vbhelper.components.getIconResource
|
||||
import com.github.nacabaro.vbhelper.components.getLengthResource
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
package com.github.nacabaro.vbhelper.screens.itemsScreen
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import com.github.nacabaro.vbhelper.dtos.ItemDtos
|
||||
|
||||
@Composable
|
||||
fun ObtainedItemDialog(
|
||||
obtainedItem: ItemDtos.PurchasedItem,
|
||||
onClickDismiss: () -> Unit
|
||||
) {
|
||||
Dialog(
|
||||
onDismissRequest = onClickDismiss
|
||||
) {
|
||||
Card {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Column (
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Row {
|
||||
Box(modifier = Modifier) {
|
||||
Icon(
|
||||
painter = painterResource(id = getIconResource(obtainedItem.itemIcon)),
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.size(96.dp)
|
||||
.align(Alignment.Center)
|
||||
)
|
||||
Icon(
|
||||
painter = painterResource(id = getLengthResource(obtainedItem.itemLength)),
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.outline,
|
||||
modifier = Modifier
|
||||
.size(64.dp)
|
||||
.align(Alignment.BottomEnd)
|
||||
)
|
||||
}
|
||||
Column (
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Text(
|
||||
fontSize = MaterialTheme.typography.titleLarge.fontSize,
|
||||
text = obtainedItem.itemName,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
}
|
||||
Text(
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = MaterialTheme.typography.bodyMedium.fontSize,
|
||||
fontFamily = MaterialTheme.typography.bodyMedium.fontFamily,
|
||||
text = obtainedItem.itemDescription,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(4.dp)
|
||||
|
||||
)
|
||||
Text(
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = MaterialTheme.typography.bodySmall.fontSize,
|
||||
fontFamily = MaterialTheme.typography.bodySmall.fontFamily,
|
||||
text = "You have obtained ${obtainedItem.itemAmount} of this item",
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(5.dp)
|
||||
)
|
||||
Button(
|
||||
onClick = onClickDismiss,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
Text(text = "Dismiss")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,11 +30,12 @@ import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
import com.github.nacabaro.vbhelper.ActivityLifecycleListener
|
||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||
import com.github.nacabaro.vbhelper.screens.cardScreen.ChooseCard
|
||||
import com.github.nacabaro.vbhelper.source.StorageRepository
|
||||
import com.github.nacabaro.vbhelper.source.isMissingSecrets
|
||||
import com.github.nacabaro.vbhelper.source.proto.Secrets
|
||||
import com.github.nacabaro.vbhelper.utils.characterToNfc
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -46,45 +47,89 @@ fun ScanScreen(
|
||||
navController: NavController,
|
||||
characterId: Long?,
|
||||
scanScreenController: ScanScreenController,
|
||||
launchedFromHomeScreen: Boolean
|
||||
) {
|
||||
val secrets by scanScreenController.secretsFlow.collectAsState(null)
|
||||
var readingScreen by remember { mutableStateOf(false) }
|
||||
var writingScreen by remember { mutableStateOf(false) }
|
||||
var isDoneReadingCharacter by remember { mutableStateOf(false) }
|
||||
var isDoneSendingCard by remember { mutableStateOf(false) }
|
||||
var isDoneWritingCharacter by remember { mutableStateOf(false) }
|
||||
|
||||
val application = LocalContext.current.applicationContext as VBHelper
|
||||
val storageRepository = StorageRepository(application.container.db)
|
||||
var nfcCharacter by remember { mutableStateOf<NfcCharacter?>(null) }
|
||||
|
||||
var cardsRead by remember { mutableStateOf<List<Card>?>(null) }
|
||||
|
||||
val context = LocalContext.current
|
||||
|
||||
LaunchedEffect(storageRepository) {
|
||||
withContext(Dispatchers.IO) {
|
||||
if(characterId != null && nfcCharacter == null) {
|
||||
nfcCharacter = characterToNfc(context, characterId)
|
||||
/*
|
||||
First check if there is a character sent through the navigation system
|
||||
If there is not, that means we got here through the home screen nfc button
|
||||
If we got here through the home screen, it does not hurt to check if there is
|
||||
an active character.
|
||||
*/
|
||||
if (characterId != null && nfcCharacter == null) {
|
||||
nfcCharacter = scanScreenController.characterToNfc(characterId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DisposableEffect(readingScreen || writingScreen, isDoneSendingCard) {
|
||||
if(readingScreen) {
|
||||
scanScreenController.registerActivityLifecycleListener(SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER, object: ActivityLifecycleListener {
|
||||
override fun onPause() {
|
||||
scanScreenController.cancelRead()
|
||||
}
|
||||
var readingScreen by remember { mutableStateOf(false) }
|
||||
var writingScreen by remember { mutableStateOf(false) }
|
||||
var cardSelectScreen by remember { mutableStateOf(false) }
|
||||
var isDoneReadingCharacter by remember { mutableStateOf(false) }
|
||||
var isDoneSendingCard by remember { mutableStateOf(false) }
|
||||
var isDoneWritingCharacter by remember { mutableStateOf(false) }
|
||||
|
||||
override fun onResume() {
|
||||
scanScreenController.onClickRead(secrets!!) {
|
||||
isDoneReadingCharacter = true
|
||||
DisposableEffect(readingScreen) {
|
||||
if(readingScreen) {
|
||||
scanScreenController.registerActivityLifecycleListener(
|
||||
SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER,
|
||||
object: ActivityLifecycleListener {
|
||||
override fun onPause() {
|
||||
scanScreenController.cancelRead()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
scanScreenController.onClickRead(
|
||||
secrets = secrets!!,
|
||||
onComplete = {
|
||||
isDoneReadingCharacter = true
|
||||
},
|
||||
onMultipleCards = { cards ->
|
||||
cardsRead = cards
|
||||
readingScreen = false
|
||||
cardSelectScreen = true
|
||||
isDoneReadingCharacter = true
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
scanScreenController.onClickRead(secrets!!) {
|
||||
isDoneReadingCharacter = true
|
||||
)
|
||||
scanScreenController.onClickRead(
|
||||
secrets = secrets!!,
|
||||
onComplete = {
|
||||
isDoneReadingCharacter = true
|
||||
},
|
||||
onMultipleCards = { cards ->
|
||||
cardsRead = cards
|
||||
readingScreen = false
|
||||
cardSelectScreen = true
|
||||
isDoneReadingCharacter = true
|
||||
}
|
||||
)
|
||||
}
|
||||
onDispose {
|
||||
if(readingScreen) {
|
||||
scanScreenController.unregisterActivityLifecycleListener(
|
||||
SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER
|
||||
)
|
||||
scanScreenController.cancelRead()
|
||||
}
|
||||
} else if (writingScreen) {
|
||||
}
|
||||
}
|
||||
|
||||
DisposableEffect(writingScreen, isDoneSendingCard) {
|
||||
if (writingScreen) {
|
||||
scanScreenController.registerActivityLifecycleListener(
|
||||
SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER,
|
||||
object : ActivityLifecycleListener {
|
||||
@@ -105,6 +150,9 @@ fun ScanScreen(
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (secrets != null && nfcCharacter != null) {
|
||||
if (!isDoneSendingCard) {
|
||||
scanScreenController.onClickCheckCard(secrets!!, nfcCharacter!!) {
|
||||
isDoneSendingCard = true
|
||||
@@ -115,15 +163,16 @@ fun ScanScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onDispose {
|
||||
if(readingScreen || writingScreen) {
|
||||
if(writingScreen) {
|
||||
scanScreenController.unregisterActivityLifecycleListener(SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER)
|
||||
scanScreenController.cancelRead()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isDoneReadingCharacter) {
|
||||
if (isDoneReadingCharacter && !cardSelectScreen) {
|
||||
readingScreen = false
|
||||
navController.navigate(NavigationItems.Home.route)
|
||||
} else if (isDoneSendingCard && isDoneWritingCharacter) {
|
||||
@@ -155,10 +204,18 @@ fun ScanScreen(
|
||||
scanScreenController.cancelRead()
|
||||
}
|
||||
}
|
||||
} else if (cardSelectScreen) {
|
||||
ChooseCard(
|
||||
cards = cardsRead!!,
|
||||
onCardSelected = { card ->
|
||||
cardSelectScreen = false
|
||||
scanScreenController.flushCharacter(card.id)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
ChooseConnectOption(
|
||||
onClickRead = when {
|
||||
characterId != null -> null
|
||||
!launchedFromHomeScreen -> null
|
||||
else -> {
|
||||
{
|
||||
if(secrets == null) {
|
||||
@@ -184,7 +241,8 @@ fun ScanScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
navController = navController
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -193,9 +251,17 @@ fun ScanScreen(
|
||||
fun ChooseConnectOption(
|
||||
onClickRead: (() -> Unit)? = null,
|
||||
onClickWrite: (() -> Unit)? = null,
|
||||
navController: NavController
|
||||
) {
|
||||
Scaffold(
|
||||
topBar = { TopBanner(text = "Scan a Vital Bracelet") }
|
||||
topBar = {
|
||||
TopBanner(
|
||||
text = "Scan a Vital Bracelet",
|
||||
onBackClick = {
|
||||
navController.popBackStack()
|
||||
}
|
||||
)
|
||||
}
|
||||
) { contentPadding ->
|
||||
Column(
|
||||
verticalArrangement = Arrangement.Center,
|
||||
@@ -255,11 +321,15 @@ fun ScanScreenPreview() {
|
||||
) {
|
||||
|
||||
}
|
||||
override fun onClickRead(secrets: Secrets, onComplete: ()->Unit) {}
|
||||
override fun flushCharacter(cardId: Long) {}
|
||||
override fun onClickRead(secrets: Secrets, onComplete: ()->Unit, onMultipleCards: (List<Card>) -> Unit) {}
|
||||
override fun onClickCheckCard(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit) {}
|
||||
override fun onClickWrite(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit) {}
|
||||
override fun cancelRead() {}
|
||||
override fun characterFromNfc(nfcCharacter: NfcCharacter, onMultipleCards: (List<Card>, NfcCharacter) -> Unit): String { return "" }
|
||||
override suspend fun characterToNfc(characterId: Long): NfcCharacter? { return null }
|
||||
},
|
||||
characterId = null
|
||||
characterId = null,
|
||||
launchedFromHomeScreen = false
|
||||
)
|
||||
}
|
||||
+10
-1
@@ -2,12 +2,13 @@ package com.github.nacabaro.vbhelper.screens.scanScreen
|
||||
|
||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
import com.github.nacabaro.vbhelper.ActivityLifecycleListener
|
||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||
import com.github.nacabaro.vbhelper.source.proto.Secrets
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface ScanScreenController {
|
||||
val secretsFlow: Flow<Secrets>
|
||||
fun onClickRead(secrets: Secrets, onComplete: ()->Unit)
|
||||
fun onClickRead(secrets: Secrets, onComplete: ()->Unit, onMultipleCards: (List<Card>) -> Unit)
|
||||
fun onClickCheckCard(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit)
|
||||
fun onClickWrite(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit)
|
||||
|
||||
@@ -15,4 +16,12 @@ interface ScanScreenController {
|
||||
|
||||
fun registerActivityLifecycleListener(key: String, activityLifecycleListener: ActivityLifecycleListener)
|
||||
fun unregisterActivityLifecycleListener(key: String)
|
||||
|
||||
fun flushCharacter(cardId: Long)
|
||||
|
||||
fun characterFromNfc(
|
||||
nfcCharacter: NfcCharacter,
|
||||
onMultipleCards: (List<Card>, NfcCharacter) -> Unit
|
||||
): String
|
||||
suspend fun characterToNfc(characterId: Long): NfcCharacter?
|
||||
}
|
||||
+43
-100
@@ -15,18 +15,16 @@ import com.github.cfogrady.vbnfc.be.BENfcCharacter
|
||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
import com.github.cfogrady.vbnfc.vb.VBNfcCharacter
|
||||
import com.github.nacabaro.vbhelper.ActivityLifecycleListener
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
|
||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||
import com.github.nacabaro.vbhelper.screens.scanScreen.converters.FromNfcConverter
|
||||
import com.github.nacabaro.vbhelper.screens.scanScreen.converters.ToNfcConverter
|
||||
import com.github.nacabaro.vbhelper.source.getCryptographicTransformerMap
|
||||
import com.github.nacabaro.vbhelper.source.isMissingSecrets
|
||||
import com.github.nacabaro.vbhelper.source.proto.Secrets
|
||||
import com.github.nacabaro.vbhelper.utils.DeviceType
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.GregorianCalendar
|
||||
|
||||
class ScanScreenControllerImpl(
|
||||
override val secretsFlow: Flow<Secrets>,
|
||||
@@ -34,7 +32,7 @@ class ScanScreenControllerImpl(
|
||||
private val registerActivityLifecycleListener: (String, ActivityLifecycleListener)->Unit,
|
||||
private val unregisterActivityLifecycleListener: (String)->Unit,
|
||||
): ScanScreenController {
|
||||
|
||||
private var lastScannedCharacter: NfcCharacter? = null
|
||||
private val nfcAdapter: NfcAdapter
|
||||
|
||||
init {
|
||||
@@ -46,10 +44,14 @@ class ScanScreenControllerImpl(
|
||||
checkSecrets()
|
||||
}
|
||||
|
||||
override fun onClickRead(secrets: Secrets, onComplete: ()->Unit) {
|
||||
override fun onClickRead(secrets: Secrets, onComplete: ()->Unit, onMultipleCards: (List<Card>) -> Unit) {
|
||||
handleTag(secrets) { tagCommunicator ->
|
||||
val character = tagCommunicator.receiveCharacter()
|
||||
val resultMessage = addCharacterScannedIntoDatabase(character)
|
||||
val resultMessage = characterFromNfc(character) { cards, nfcCharacter ->
|
||||
lastScannedCharacter = nfcCharacter
|
||||
onMultipleCards(cards)
|
||||
|
||||
}
|
||||
onComplete.invoke()
|
||||
resultMessage
|
||||
}
|
||||
@@ -123,7 +125,15 @@ class ScanScreenControllerImpl(
|
||||
) {
|
||||
handleTag(secrets) { tagCommunicator ->
|
||||
try {
|
||||
tagCommunicator.sendCharacter(nfcCharacter)
|
||||
if (nfcCharacter is VBNfcCharacter) {
|
||||
Log.d("SendCharacter", "VBNfcCharacter")
|
||||
val castNfcCharacter: VBNfcCharacter = nfcCharacter
|
||||
tagCommunicator.sendCharacter(castNfcCharacter)
|
||||
} else if (nfcCharacter is BENfcCharacter) {
|
||||
Log.d("SendCharacter", "BENfcCharacter")
|
||||
val castNfcCharacter: BENfcCharacter = nfcCharacter
|
||||
tagCommunicator.sendCharacter(castNfcCharacter)
|
||||
}
|
||||
onComplete.invoke()
|
||||
"Sent character successfully!"
|
||||
} catch (e: Throwable) {
|
||||
@@ -151,103 +161,36 @@ class ScanScreenControllerImpl(
|
||||
componentActivity.startActivity(Intent(Settings.ACTION_WIRELESS_SETTINGS))
|
||||
}
|
||||
|
||||
private fun addCharacterScannedIntoDatabase(nfcCharacter: NfcCharacter): String {
|
||||
val application = componentActivity.applicationContext as VBHelper
|
||||
val storageRepository = application.container.db
|
||||
override fun characterFromNfc(
|
||||
nfcCharacter: NfcCharacter,
|
||||
onMultipleCards: (List<Card>, NfcCharacter) -> Unit
|
||||
): String {
|
||||
val nfcConverter = FromNfcConverter(
|
||||
componentActivity = componentActivity
|
||||
)
|
||||
return nfcConverter.addCharacter(nfcCharacter, onMultipleCards)
|
||||
}
|
||||
|
||||
val dimData = storageRepository
|
||||
.dimDao()
|
||||
.getDimById(nfcCharacter.dimId.toInt())
|
||||
|
||||
if (dimData == null) return "Card not found"
|
||||
|
||||
val cardCharData = storageRepository
|
||||
.characterDao()
|
||||
.getCharacterByMonIndex(nfcCharacter.charIndex.toInt(), dimData.id)
|
||||
|
||||
val characterData = UserCharacter(
|
||||
charId = cardCharData.id,
|
||||
stage = nfcCharacter.stage.toInt(),
|
||||
attribute = nfcCharacter.attribute,
|
||||
ageInDays = nfcCharacter.ageInDays.toInt(),
|
||||
nextAdventureMissionStage = nfcCharacter.nextAdventureMissionStage.toInt(),
|
||||
mood = nfcCharacter.mood.toInt(),
|
||||
vitalPoints = nfcCharacter.vitalPoints.toInt(),
|
||||
transformationCountdown = nfcCharacter.transformationCountdownInMinutes.toInt(),
|
||||
injuryStatus = nfcCharacter.injuryStatus,
|
||||
trophies = nfcCharacter.trophies.toInt(),
|
||||
currentPhaseBattlesWon = nfcCharacter.currentPhaseBattlesWon.toInt(),
|
||||
currentPhaseBattlesLost = nfcCharacter.currentPhaseBattlesLost.toInt(),
|
||||
totalBattlesWon = nfcCharacter.totalBattlesWon.toInt(),
|
||||
totalBattlesLost = nfcCharacter.totalBattlesLost.toInt(),
|
||||
activityLevel = nfcCharacter.activityLevel.toInt(),
|
||||
heartRateCurrent = nfcCharacter.heartRateCurrent.toInt(),
|
||||
characterType = when (nfcCharacter) {
|
||||
is BENfcCharacter -> DeviceType.BEDevice
|
||||
else -> DeviceType.VBDevice
|
||||
},
|
||||
isActive = true
|
||||
override suspend fun characterToNfc(characterId: Long): NfcCharacter {
|
||||
val nfcGenerator = ToNfcConverter(
|
||||
componentActivity = componentActivity
|
||||
)
|
||||
|
||||
storageRepository
|
||||
.userCharacterDao()
|
||||
.clearActiveCharacter()
|
||||
val character = nfcGenerator.characterToNfc(characterId)
|
||||
Log.d("CharacterType", character.toString())
|
||||
return character
|
||||
}
|
||||
|
||||
val characterId: Long = storageRepository
|
||||
.userCharacterDao()
|
||||
.insertCharacterData(characterData)
|
||||
override fun flushCharacter(cardId: Long) {
|
||||
val nfcConverter = FromNfcConverter(
|
||||
componentActivity = componentActivity
|
||||
)
|
||||
|
||||
if (nfcCharacter is BENfcCharacter) {
|
||||
val extraCharacterData = BECharacterData(
|
||||
id = characterId,
|
||||
trainingHp = nfcCharacter.trainingHp.toInt(),
|
||||
trainingAp = nfcCharacter.trainingAp.toInt(),
|
||||
trainingBp = nfcCharacter.trainingBp.toInt(),
|
||||
remainingTrainingTimeInMinutes = nfcCharacter.remainingTrainingTimeInMinutes.toInt(),
|
||||
itemEffectActivityLevelValue = nfcCharacter.itemEffectActivityLevelValue.toInt(),
|
||||
itemEffectMentalStateValue = nfcCharacter.itemEffectMentalStateValue.toInt(),
|
||||
itemEffectMentalStateMinutesRemaining = nfcCharacter.itemEffectMentalStateMinutesRemaining.toInt(),
|
||||
itemEffectActivityLevelMinutesRemaining = nfcCharacter.itemEffectActivityLevelMinutesRemaining.toInt(),
|
||||
itemEffectVitalPointsChangeValue = nfcCharacter.itemEffectVitalPointsChangeValue.toInt(),
|
||||
itemEffectVitalPointsChangeMinutesRemaining = nfcCharacter.itemEffectVitalPointsChangeMinutesRemaining.toInt(),
|
||||
abilityRarity = nfcCharacter.abilityRarity,
|
||||
abilityType = nfcCharacter.abilityType.toInt(),
|
||||
abilityBranch = nfcCharacter.abilityBranch.toInt(),
|
||||
abilityReset = nfcCharacter.abilityReset.toInt(),
|
||||
rank = nfcCharacter.abilityReset.toInt(),
|
||||
itemType = nfcCharacter.itemType.toInt(),
|
||||
itemMultiplier = nfcCharacter.itemMultiplier.toInt(),
|
||||
itemRemainingTime = nfcCharacter.itemRemainingTime.toInt(),
|
||||
otp0 = "", //nfcCharacter.value!!.otp0.toString(),
|
||||
otp1 = "", //nfcCharacter.value!!.otp1.toString(),
|
||||
minorVersion = nfcCharacter.characterCreationFirmwareVersion.minorVersion.toInt(),
|
||||
majorVersion = nfcCharacter.characterCreationFirmwareVersion.majorVersion.toInt(),
|
||||
)
|
||||
|
||||
storageRepository
|
||||
.userCharacterDao()
|
||||
.insertBECharacterData(extraCharacterData)
|
||||
|
||||
val transformationHistoryWatch = nfcCharacter.transformationHistory
|
||||
transformationHistoryWatch.map { item ->
|
||||
if (item.toCharIndex.toInt() != 255) {
|
||||
val date = GregorianCalendar(item.year.toInt(), item.month.toInt(), item.day.toInt())
|
||||
.time
|
||||
.time
|
||||
|
||||
storageRepository
|
||||
.characterDao()
|
||||
.insertTransformation(characterId, item.toCharIndex.toInt(), dimData.id, date)
|
||||
|
||||
storageRepository
|
||||
.dexDao()
|
||||
.insertCharacter(item.toCharIndex.toInt(), dimData.id, date)
|
||||
}
|
||||
componentActivity.lifecycleScope.launch(Dispatchers.IO) {
|
||||
if (lastScannedCharacter != null) {
|
||||
nfcConverter.addCharacterUsingCard(lastScannedCharacter!!, cardId)
|
||||
lastScannedCharacter = null
|
||||
}
|
||||
} else if (nfcCharacter is VBNfcCharacter) {
|
||||
return "Not implemented yet"
|
||||
}
|
||||
|
||||
return "Done reading character!"
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package com.github.nacabaro.vbhelper.screens.cardScreen
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||
import com.github.nacabaro.vbhelper.screens.scanScreen.cardSelect.ScanCardEntry
|
||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||
|
||||
@Composable
|
||||
fun ChooseCard(
|
||||
cards: List<Card>,
|
||||
onCardSelected: (Card) -> Unit
|
||||
) {
|
||||
Scaffold (
|
||||
topBar = {
|
||||
TopBanner(
|
||||
text = "Choose card",
|
||||
)
|
||||
}
|
||||
) { contentPadding ->
|
||||
LazyColumn (
|
||||
modifier = Modifier
|
||||
.padding(top = contentPadding.calculateTopPadding())
|
||||
) {
|
||||
items(cards) {
|
||||
ScanCardEntry(
|
||||
name = it.name,
|
||||
logo = BitmapData(
|
||||
it.logo,
|
||||
it.logoWidth,
|
||||
it.logoHeight
|
||||
),
|
||||
onClick = {
|
||||
onCardSelected(it)
|
||||
},
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-10
@@ -1,4 +1,4 @@
|
||||
package com.github.nacabaro.vbhelper.components
|
||||
package com.github.nacabaro.vbhelper.screens.scanScreen.cardSelect
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
@@ -21,11 +21,9 @@ import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||
import com.github.nacabaro.vbhelper.utils.getBitmap
|
||||
|
||||
@Composable
|
||||
fun DexDiMEntry(
|
||||
fun ScanCardEntry(
|
||||
name: String,
|
||||
logo: BitmapData,
|
||||
obtainedCharacters: Int,
|
||||
totalCharacters: Int,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
@@ -56,17 +54,12 @@ fun DexDiMEntry(
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
.weight(1f)
|
||||
) {
|
||||
Text(
|
||||
text = name,
|
||||
modifier = Modifier
|
||||
)
|
||||
Text(
|
||||
text = "$obtainedCharacters of $totalCharacters characters obtained",
|
||||
fontFamily = MaterialTheme.typography.labelSmall.fontFamily,
|
||||
fontSize = MaterialTheme.typography.labelSmall.fontSize,
|
||||
modifier = Modifier
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+306
@@ -0,0 +1,306 @@
|
||||
package com.github.nacabaro.vbhelper.screens.scanScreen.converters
|
||||
|
||||
import android.util.Log
|
||||
import androidx.activity.ComponentActivity
|
||||
import com.github.cfogrady.vbnfc.be.BENfcCharacter
|
||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
import com.github.cfogrady.vbnfc.vb.VBNfcCharacter
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardProgress
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.VitalsHistory
|
||||
import com.github.nacabaro.vbhelper.utils.DeviceType
|
||||
import java.util.GregorianCalendar
|
||||
|
||||
class FromNfcConverter (
|
||||
componentActivity: ComponentActivity
|
||||
) {
|
||||
private val application = componentActivity.applicationContext as VBHelper
|
||||
private val database = application.container.db
|
||||
|
||||
|
||||
fun addCharacterUsingCard(
|
||||
nfcCharacter: NfcCharacter,
|
||||
cardId: Long
|
||||
): String {
|
||||
val cardData = database
|
||||
.cardDao()
|
||||
.getCardById(cardId)
|
||||
|
||||
if (cardData == null) {
|
||||
return "Card not found"
|
||||
}
|
||||
|
||||
return insertCharacter(nfcCharacter, cardData)
|
||||
}
|
||||
|
||||
|
||||
fun addCharacter(
|
||||
nfcCharacter: NfcCharacter,
|
||||
onMultipleCards: (List<Card>, NfcCharacter) -> Unit
|
||||
): String {
|
||||
val appReservedCardId = nfcCharacter
|
||||
.appReserved2[0].toLong()
|
||||
|
||||
var cardData: Card? = null
|
||||
|
||||
if (appReservedCardId != 0L) {
|
||||
val fetchedCard = database
|
||||
.cardDao()
|
||||
.getCardById(appReservedCardId)
|
||||
|
||||
if (fetchedCard == null) {
|
||||
return "Card not found"
|
||||
} else if (fetchedCard.cardId == nfcCharacter.dimId.toInt()) {
|
||||
cardData = fetchedCard
|
||||
}
|
||||
}
|
||||
|
||||
if (cardData == null) {
|
||||
val allCards = database
|
||||
.cardDao()
|
||||
.getCardByCardId(nfcCharacter.dimId.toInt())
|
||||
|
||||
if (allCards.isEmpty())
|
||||
return "Card not found"
|
||||
|
||||
if (allCards.size > 1) {
|
||||
onMultipleCards(allCards, nfcCharacter)
|
||||
return "Multiple cards found"
|
||||
}
|
||||
|
||||
cardData = allCards[0]
|
||||
}
|
||||
|
||||
return insertCharacter(nfcCharacter, cardData)
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun insertCharacter(
|
||||
nfcCharacter: NfcCharacter,
|
||||
cardData: Card
|
||||
): String {
|
||||
val cardCharData = database
|
||||
.characterDao()
|
||||
.getCharacterByMonIndex(nfcCharacter.charIndex.toInt(), cardData.id)
|
||||
|
||||
updateCardProgress(nfcCharacter, cardData)
|
||||
|
||||
val characterData = UserCharacter(
|
||||
charId = cardCharData.id,
|
||||
ageInDays = nfcCharacter.ageInDays.toInt(),
|
||||
mood = nfcCharacter.mood.toInt(),
|
||||
vitalPoints = nfcCharacter.vitalPoints.toInt(),
|
||||
transformationCountdown = nfcCharacter.transformationCountdownInMinutes.toInt(),
|
||||
injuryStatus = nfcCharacter.injuryStatus,
|
||||
trophies = nfcCharacter.trophies.toInt(),
|
||||
currentPhaseBattlesWon = nfcCharacter.currentPhaseBattlesWon.toInt(),
|
||||
currentPhaseBattlesLost = nfcCharacter.currentPhaseBattlesLost.toInt(),
|
||||
totalBattlesWon = nfcCharacter.totalBattlesWon.toInt(),
|
||||
totalBattlesLost = nfcCharacter.totalBattlesLost.toInt(),
|
||||
activityLevel = nfcCharacter.activityLevel.toInt(),
|
||||
heartRateCurrent = nfcCharacter.heartRateCurrent.toInt(),
|
||||
characterType = when (nfcCharacter) {
|
||||
is BENfcCharacter -> DeviceType.BEDevice
|
||||
else -> DeviceType.VBDevice
|
||||
},
|
||||
isActive = true
|
||||
)
|
||||
|
||||
database
|
||||
.userCharacterDao()
|
||||
.clearActiveCharacter()
|
||||
|
||||
val characterId: Long = database
|
||||
.userCharacterDao()
|
||||
.insertCharacterData(characterData)
|
||||
|
||||
if (nfcCharacter is BENfcCharacter) {
|
||||
addBeCharacterToDatabase(
|
||||
characterId = characterId,
|
||||
nfcCharacter = nfcCharacter
|
||||
)
|
||||
} else if (nfcCharacter is VBNfcCharacter) {
|
||||
addVbCharacterToDatabase(
|
||||
characterId = characterId,
|
||||
nfcCharacter = nfcCharacter
|
||||
)
|
||||
}
|
||||
|
||||
addTransformationHistoryToDatabase(
|
||||
characterId = characterId,
|
||||
nfcCharacter = nfcCharacter,
|
||||
dimData = cardData
|
||||
)
|
||||
|
||||
addVitalsHistoryToDatabase(
|
||||
characterId = characterId,
|
||||
nfcCharacter = nfcCharacter
|
||||
)
|
||||
|
||||
return "Done reading character!"
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun updateCardProgress(
|
||||
nfcCharacter: NfcCharacter,
|
||||
cardData: Card
|
||||
) {
|
||||
val currentCardProgress = CardProgress(
|
||||
cardId = cardData.id,
|
||||
currentStage = nfcCharacter.nextAdventureMissionStage.toInt(),
|
||||
unlocked = nfcCharacter.nextAdventureMissionStage.toInt() > cardData.stageCount
|
||||
)
|
||||
|
||||
database
|
||||
.cardProgressDao()
|
||||
.updateDimProgress(currentCardProgress)
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun addVbCharacterToDatabase(
|
||||
characterId: Long,
|
||||
nfcCharacter: VBNfcCharacter
|
||||
) {
|
||||
val extraCharacterData = VBCharacterData(
|
||||
id = characterId,
|
||||
generation = nfcCharacter.generation.toInt(),
|
||||
totalTrophies = nfcCharacter.totalTrophies.toInt()
|
||||
)
|
||||
|
||||
database
|
||||
.userCharacterDao()
|
||||
.insertVBCharacterData(extraCharacterData)
|
||||
|
||||
addSpecialMissionsToDatabase(nfcCharacter, characterId)
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun addSpecialMissionsToDatabase(
|
||||
nfcCharacter: VBNfcCharacter,
|
||||
characterId: Long
|
||||
) {
|
||||
val specialMissionsWatch = nfcCharacter.specialMissions
|
||||
val specialMissionsDb = specialMissionsWatch.map { item ->
|
||||
SpecialMissions(
|
||||
characterId = characterId,
|
||||
goal = item.goal.toInt(),
|
||||
watchId = item.id.toInt(),
|
||||
progress = item.progress.toInt(),
|
||||
status = item.status,
|
||||
timeElapsedInMinutes = item.timeElapsedInMinutes.toInt(),
|
||||
timeLimitInMinutes = item.timeLimitInMinutes.toInt(),
|
||||
missionType = item.type,
|
||||
)
|
||||
}
|
||||
|
||||
database
|
||||
.userCharacterDao()
|
||||
.insertSpecialMissions(*specialMissionsDb.toTypedArray())
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun addBeCharacterToDatabase(
|
||||
characterId: Long,
|
||||
nfcCharacter: BENfcCharacter
|
||||
) {
|
||||
val extraCharacterData = BECharacterData(
|
||||
id = characterId,
|
||||
trainingHp = nfcCharacter.trainingHp.toInt(),
|
||||
trainingAp = nfcCharacter.trainingAp.toInt(),
|
||||
trainingBp = nfcCharacter.trainingBp.toInt(),
|
||||
remainingTrainingTimeInMinutes = nfcCharacter.remainingTrainingTimeInMinutes.toInt(),
|
||||
itemEffectActivityLevelValue = nfcCharacter.itemEffectActivityLevelValue.toInt(),
|
||||
itemEffectMentalStateValue = nfcCharacter.itemEffectMentalStateValue.toInt(),
|
||||
itemEffectMentalStateMinutesRemaining = nfcCharacter.itemEffectMentalStateMinutesRemaining.toInt(),
|
||||
itemEffectActivityLevelMinutesRemaining = nfcCharacter.itemEffectActivityLevelMinutesRemaining.toInt(),
|
||||
itemEffectVitalPointsChangeValue = nfcCharacter.itemEffectVitalPointsChangeValue.toInt(),
|
||||
itemEffectVitalPointsChangeMinutesRemaining = nfcCharacter.itemEffectVitalPointsChangeMinutesRemaining.toInt(),
|
||||
abilityRarity = nfcCharacter.abilityRarity,
|
||||
abilityType = nfcCharacter.abilityType.toInt(),
|
||||
abilityBranch = nfcCharacter.abilityBranch.toInt(),
|
||||
abilityReset = nfcCharacter.abilityReset.toInt(),
|
||||
rank = nfcCharacter.abilityReset.toInt(),
|
||||
itemType = nfcCharacter.itemType.toInt(),
|
||||
itemMultiplier = nfcCharacter.itemMultiplier.toInt(),
|
||||
itemRemainingTime = nfcCharacter.itemRemainingTime.toInt(),
|
||||
otp0 = "", //nfcCharacter.value!!.otp0.toString(),
|
||||
otp1 = "", //nfcCharacter.value!!.otp1.toString(),
|
||||
minorVersion = nfcCharacter.characterCreationFirmwareVersion.minorVersion.toInt(),
|
||||
majorVersion = nfcCharacter.characterCreationFirmwareVersion.majorVersion.toInt(),
|
||||
)
|
||||
|
||||
database
|
||||
.userCharacterDao()
|
||||
.insertBECharacterData(extraCharacterData)
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun addVitalsHistoryToDatabase(
|
||||
characterId: Long,
|
||||
nfcCharacter: NfcCharacter
|
||||
) {
|
||||
val vitalsHistoryWatch = nfcCharacter.vitalHistory
|
||||
val vitalsHistory = vitalsHistoryWatch.map { historyElement ->
|
||||
Log.d("VitalsHistory", "${historyElement.year.toInt()} ${historyElement.month.toInt()} ${historyElement.day.toInt()}")
|
||||
VitalsHistory(
|
||||
charId = characterId,
|
||||
year = historyElement.year.toInt(),
|
||||
month = historyElement.month.toInt(),
|
||||
day = historyElement.day.toInt(),
|
||||
vitalPoints = historyElement.vitalsGained.toInt()
|
||||
)
|
||||
}
|
||||
|
||||
database
|
||||
.userCharacterDao()
|
||||
.insertVitals(*vitalsHistory.toTypedArray())
|
||||
}
|
||||
|
||||
|
||||
private fun addTransformationHistoryToDatabase(
|
||||
characterId: Long,
|
||||
nfcCharacter: NfcCharacter,
|
||||
dimData: Card
|
||||
) {
|
||||
val transformationHistoryWatch = nfcCharacter.transformationHistory
|
||||
transformationHistoryWatch.map { item ->
|
||||
if (item.toCharIndex.toInt() != 255) {
|
||||
val date = GregorianCalendar(
|
||||
item.year.toInt(),
|
||||
item.month.toInt(),
|
||||
item.day.toInt()
|
||||
)
|
||||
.time
|
||||
.time
|
||||
|
||||
database
|
||||
.userCharacterDao()
|
||||
.insertTransformation(
|
||||
characterId,
|
||||
item.toCharIndex.toInt(),
|
||||
dimData.id,
|
||||
date
|
||||
)
|
||||
|
||||
database
|
||||
.dexDao()
|
||||
.insertCharacter(
|
||||
item.toCharIndex.toInt(),
|
||||
dimData.id,
|
||||
date
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+298
@@ -0,0 +1,298 @@
|
||||
package com.github.nacabaro.vbhelper.screens.scanScreen.converters
|
||||
|
||||
import android.icu.util.Calendar
|
||||
import android.icu.util.TimeZone
|
||||
import android.util.Log
|
||||
import androidx.activity.ComponentActivity
|
||||
import com.github.cfogrady.vbnfc.be.BENfcCharacter
|
||||
import com.github.cfogrady.vbnfc.be.FirmwareVersion
|
||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
import com.github.cfogrady.vbnfc.vb.SpecialMission
|
||||
import com.github.cfogrady.vbnfc.vb.VBNfcCharacter
|
||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import com.github.nacabaro.vbhelper.utils.DeviceType
|
||||
import java.util.Date
|
||||
|
||||
class ToNfcConverter(
|
||||
private val componentActivity: ComponentActivity
|
||||
) {
|
||||
private val application: VBHelper = componentActivity.applicationContext as VBHelper
|
||||
private val database: AppDatabase = application.container.db
|
||||
|
||||
|
||||
|
||||
suspend fun characterToNfc(
|
||||
characterId: Long
|
||||
): NfcCharacter {
|
||||
val app = componentActivity.applicationContext as VBHelper
|
||||
val database = app.container.db
|
||||
|
||||
val userCharacter = database
|
||||
.userCharacterDao()
|
||||
.getCharacter(characterId)
|
||||
|
||||
val characterInfo = database
|
||||
.characterDao()
|
||||
.getCharacterInfo(userCharacter.charId)
|
||||
|
||||
val currentCardStage = database
|
||||
.cardProgressDao()
|
||||
.getCardProgress(characterInfo.cardId)
|
||||
|
||||
return if (userCharacter.characterType == DeviceType.BEDevice)
|
||||
nfcToBENfc(characterId, characterInfo, currentCardStage, userCharacter)
|
||||
else
|
||||
nfcToVBNfc(characterId, characterInfo, currentCardStage, userCharacter)
|
||||
}
|
||||
|
||||
|
||||
|
||||
private suspend fun nfcToVBNfc(
|
||||
characterId: Long,
|
||||
characterInfo: CharacterDtos.CardCharacterInfo,
|
||||
currentCardStage: Int,
|
||||
userCharacter: UserCharacter
|
||||
): VBNfcCharacter {
|
||||
val vbData = database
|
||||
.userCharacterDao()
|
||||
.getVbData(characterId)
|
||||
|
||||
val paddedTransformationArray = generateTransformationHistory(characterId, 9)
|
||||
|
||||
val watchSpecialMissions = generateSpecialMissionsArray(characterId)
|
||||
|
||||
val nfcData = VBNfcCharacter(
|
||||
dimId = characterInfo.cardId.toUShort(),
|
||||
charIndex = characterInfo.charId.toUShort(),
|
||||
stage = characterInfo.stage.toByte(),
|
||||
attribute = characterInfo.attribute,
|
||||
ageInDays = userCharacter.ageInDays.toByte(),
|
||||
nextAdventureMissionStage = currentCardStage.toByte(),
|
||||
mood = userCharacter.mood.toByte(),
|
||||
vitalPoints = userCharacter.vitalPoints.toUShort(),
|
||||
transformationCountdownInMinutes = userCharacter.transformationCountdown.toUShort(),
|
||||
injuryStatus = userCharacter.injuryStatus,
|
||||
trophies = userCharacter.trophies.toUShort(),
|
||||
currentPhaseBattlesWon = userCharacter.currentPhaseBattlesWon.toUShort(),
|
||||
currentPhaseBattlesLost = userCharacter.currentPhaseBattlesLost.toUShort(),
|
||||
totalBattlesWon = userCharacter.totalBattlesWon.toUShort(),
|
||||
totalBattlesLost = userCharacter.totalBattlesLost.toUShort(),
|
||||
activityLevel = userCharacter.activityLevel.toByte(),
|
||||
heartRateCurrent = userCharacter.heartRateCurrent.toUByte(),
|
||||
transformationHistory = paddedTransformationArray,
|
||||
vitalHistory = generateVitalsHistoryArray(characterId),
|
||||
appReserved1 = ByteArray(12) {0},
|
||||
appReserved2 = generateUShortAppReserved(userCharacter),
|
||||
generation = vbData.generation.toUShort(),
|
||||
totalTrophies = vbData.totalTrophies.toUShort(),
|
||||
specialMissions = watchSpecialMissions.toTypedArray()
|
||||
)
|
||||
|
||||
return nfcData
|
||||
}
|
||||
|
||||
|
||||
private suspend fun generateUShortAppReserved(
|
||||
userCharacter: UserCharacter
|
||||
): Array<UShort> {
|
||||
val cardData = database
|
||||
.cardDao()
|
||||
.getCardByCharacterId(userCharacter.id)
|
||||
|
||||
val appReserved = Array<UShort>(3) {
|
||||
0u
|
||||
}
|
||||
|
||||
appReserved[0] = cardData.id.toUShort()
|
||||
|
||||
return appReserved
|
||||
}
|
||||
|
||||
|
||||
|
||||
private suspend fun generateSpecialMissionsArray(
|
||||
characterId: Long
|
||||
): List<SpecialMission> {
|
||||
val specialMissions = database
|
||||
.userCharacterDao()
|
||||
.getSpecialMissions(characterId)
|
||||
|
||||
val watchSpecialMissions = specialMissions.map {
|
||||
SpecialMission(
|
||||
goal = it.goal.toUShort(),
|
||||
id = it.watchId.toUShort(),
|
||||
progress = it.progress.toUShort(),
|
||||
status = it.status,
|
||||
timeElapsedInMinutes = it.timeElapsedInMinutes.toUShort(),
|
||||
timeLimitInMinutes = it.timeLimitInMinutes.toUShort(),
|
||||
type = it.missionType
|
||||
)
|
||||
}
|
||||
|
||||
return watchSpecialMissions
|
||||
}
|
||||
|
||||
|
||||
|
||||
private suspend fun generateVitalsHistoryArray(
|
||||
characterId: Long
|
||||
): Array<NfcCharacter.DailyVitals> {
|
||||
val vitalsHistory = database
|
||||
.userCharacterDao()
|
||||
.getVitalsHistory(characterId)
|
||||
|
||||
val nfcVitalsHistory = Array(7) {
|
||||
NfcCharacter.DailyVitals(0u, 0u, 0u, 0u)
|
||||
}
|
||||
|
||||
vitalsHistory.mapIndexed { index, historyElement ->
|
||||
var actualYear = 0
|
||||
if (historyElement.year != 2000) {
|
||||
actualYear = historyElement.year
|
||||
}
|
||||
nfcVitalsHistory[index] = NfcCharacter.DailyVitals(
|
||||
day = historyElement.day.toUByte(),
|
||||
month = historyElement.month.toUByte(),
|
||||
year = actualYear.toUShort(),
|
||||
vitalsGained = vitalsHistory[index].vitalPoints.toUShort()
|
||||
)
|
||||
}
|
||||
|
||||
nfcVitalsHistory.map {
|
||||
Log.d("NFC", it.toString())
|
||||
}
|
||||
|
||||
return nfcVitalsHistory
|
||||
}
|
||||
|
||||
|
||||
|
||||
private suspend fun nfcToBENfc(
|
||||
characterId: Long,
|
||||
characterInfo: CharacterDtos.CardCharacterInfo,
|
||||
currentCardStage: Int,
|
||||
userCharacter: UserCharacter
|
||||
): BENfcCharacter {
|
||||
val beData = database
|
||||
.userCharacterDao()
|
||||
.getBeData(characterId)
|
||||
|
||||
val paddedTransformationArray = generateTransformationHistory(characterId)
|
||||
|
||||
val nfcData = BENfcCharacter(
|
||||
dimId = characterInfo.cardId.toUShort(),
|
||||
charIndex = characterInfo.charId.toUShort(),
|
||||
stage = characterInfo.stage.toByte(),
|
||||
attribute = characterInfo.attribute,
|
||||
ageInDays = userCharacter.ageInDays.toByte(),
|
||||
nextAdventureMissionStage = currentCardStage.toByte(),
|
||||
mood = userCharacter.mood.toByte(),
|
||||
vitalPoints = userCharacter.vitalPoints.toUShort(),
|
||||
itemEffectMentalStateValue = beData.itemEffectMentalStateValue.toByte(),
|
||||
itemEffectMentalStateMinutesRemaining = beData.itemEffectMentalStateMinutesRemaining.toByte(),
|
||||
itemEffectActivityLevelValue = beData.itemEffectActivityLevelValue.toByte(),
|
||||
itemEffectActivityLevelMinutesRemaining = beData.itemEffectActivityLevelMinutesRemaining.toByte(),
|
||||
itemEffectVitalPointsChangeValue = beData.itemEffectVitalPointsChangeValue.toByte(),
|
||||
itemEffectVitalPointsChangeMinutesRemaining = beData.itemEffectVitalPointsChangeMinutesRemaining.toByte(),
|
||||
transformationCountdownInMinutes = userCharacter.transformationCountdown.toUShort(),
|
||||
injuryStatus = userCharacter.injuryStatus,
|
||||
trainingPp = userCharacter.trophies.toUShort(),
|
||||
currentPhaseBattlesWon = userCharacter.currentPhaseBattlesWon.toUShort(),
|
||||
currentPhaseBattlesLost = userCharacter.currentPhaseBattlesLost.toUShort(),
|
||||
totalBattlesWon = userCharacter.totalBattlesWon.toUShort(),
|
||||
totalBattlesLost = userCharacter.totalBattlesLost.toUShort(),
|
||||
activityLevel = userCharacter.activityLevel.toByte(),
|
||||
heartRateCurrent = userCharacter.heartRateCurrent.toUByte(),
|
||||
transformationHistory = paddedTransformationArray,
|
||||
vitalHistory = generateVitalsHistoryArray(characterId),
|
||||
appReserved1 = ByteArray(12) {0},
|
||||
appReserved2 = Array(3) {0u},
|
||||
trainingHp = beData.trainingHp.toUShort(),
|
||||
trainingAp = beData.trainingAp.toUShort(),
|
||||
trainingBp = beData.trainingBp.toUShort(),
|
||||
remainingTrainingTimeInMinutes = beData.remainingTrainingTimeInMinutes.toUShort(),
|
||||
abilityRarity = beData.abilityRarity,
|
||||
abilityType = beData.abilityType.toUShort(),
|
||||
abilityBranch = beData.abilityBranch.toUShort(),
|
||||
abilityReset = beData.abilityReset.toByte(),
|
||||
rank = beData.rank.toByte(),
|
||||
itemType = beData.itemType.toByte(),
|
||||
itemMultiplier = beData.itemMultiplier.toByte(),
|
||||
itemRemainingTime = beData.itemRemainingTime.toByte(),
|
||||
otp0 = byteArrayOf(8),
|
||||
otp1 = byteArrayOf(8),
|
||||
characterCreationFirmwareVersion = FirmwareVersion(
|
||||
minorVersion = beData.minorVersion.toByte(),
|
||||
majorVersion = beData.majorVersion.toByte()
|
||||
)
|
||||
)
|
||||
|
||||
return nfcData
|
||||
}
|
||||
|
||||
|
||||
|
||||
private suspend fun generateTransformationHistory(
|
||||
characterId: Long,
|
||||
length: Int = 8
|
||||
): Array<NfcCharacter.Transformation> {
|
||||
val transformationHistory = database
|
||||
.userCharacterDao()
|
||||
.getTransformationHistory(characterId)!!
|
||||
.map {
|
||||
val date = Date(it.transformationDate)
|
||||
val calendar = android.icu.util.GregorianCalendar(TimeZone.getTimeZone("UTC"))
|
||||
calendar.time = date
|
||||
|
||||
Log.d(
|
||||
"TransformationHistory",
|
||||
"Year: ${calendar.get(Calendar.YEAR)}, " +
|
||||
"Month: ${calendar.get(Calendar.MONTH) + 1}, " +
|
||||
"Day: ${calendar.get(Calendar.DAY_OF_MONTH)}"
|
||||
)
|
||||
|
||||
NfcCharacter.Transformation(
|
||||
toCharIndex = it.monIndex.toUByte(),
|
||||
year = calendar
|
||||
.get(Calendar.YEAR)
|
||||
.toUShort(),
|
||||
month = (calendar
|
||||
.get(Calendar.MONTH) + 1)
|
||||
.toUByte(),
|
||||
day = calendar
|
||||
.get(Calendar.DAY_OF_MONTH)
|
||||
.toUByte()
|
||||
)
|
||||
}.toTypedArray()
|
||||
|
||||
val paddedTransformationArray = padTransformationArray(transformationHistory, length)
|
||||
|
||||
return paddedTransformationArray
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun padTransformationArray(
|
||||
transformationArray: Array<NfcCharacter.Transformation>,
|
||||
length: Int
|
||||
): Array<NfcCharacter.Transformation> {
|
||||
if (transformationArray.size >= 8) {
|
||||
return transformationArray
|
||||
}
|
||||
|
||||
val paddedArray = Array(length) {
|
||||
NfcCharacter.Transformation(
|
||||
toCharIndex = 255u,
|
||||
year = 65535u,
|
||||
month = 255u,
|
||||
day = 255u
|
||||
)
|
||||
}
|
||||
|
||||
System.arraycopy(transformationArray, 0, paddedArray, 0, transformationArray.size)
|
||||
return paddedArray
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.github.nacabaro.vbhelper.screens.settingsScreen
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.navigation.NavController
|
||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||
|
||||
@Composable
|
||||
fun CreditsScreen(
|
||||
navController: NavController
|
||||
) {
|
||||
Scaffold (
|
||||
topBar = {
|
||||
TopBanner(
|
||||
text = "Credits",
|
||||
onBackClick = {
|
||||
navController.popBackStack()
|
||||
},
|
||||
onGearClick = {
|
||||
navController.navigate(NavigationItems.Viewer.route)
|
||||
}
|
||||
)
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
) { contentPadding ->
|
||||
Column (
|
||||
modifier = Modifier
|
||||
.padding(top = contentPadding.calculateTopPadding())
|
||||
) {
|
||||
SettingsSection("Reverse engineering")
|
||||
SettingsEntry(title = "cyanic", description = "Reversed the firmware and helped us during development.") { }
|
||||
SettingsSection("Application development")
|
||||
SettingsEntry(title = "cfogrady", description = "Developed vb-lib-nfc and part of this application.") { }
|
||||
SettingsEntry(title = "nacabaro", description = "Developed this application.") { }
|
||||
SettingsEntry(title = "lightheel", description = "Developing the battling part for this application, including server. Still in the works.") { }
|
||||
SettingsEntry(title = "shvstrz", description = "Designing the app icon in SVG.") { }
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-8
@@ -18,6 +18,7 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.navigation.NavController
|
||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||
import com.github.nacabaro.vbhelper.navigation.NavigationItems
|
||||
|
||||
@Composable
|
||||
fun SettingsScreen(
|
||||
@@ -46,6 +47,16 @@ fun SettingsScreen(
|
||||
SettingsEntry(title = "Import APK", description = "Import Secrets From Vital Arean 2.1.0 APK") {
|
||||
settingsScreenController.onClickImportApk()
|
||||
}
|
||||
SettingsSection("DiM/BEm management")
|
||||
SettingsEntry(title = "Import card", description = "Import DiM/BEm card file") {
|
||||
settingsScreenController.onClickImportCard()
|
||||
}
|
||||
SettingsEntry(title = "Rename DiM/BEm", description = "Set card name") { }
|
||||
SettingsSection("About and credits")
|
||||
SettingsEntry(title = "Credits", description = "Credits") {
|
||||
navController.navigate(NavigationItems.Credits.route)
|
||||
}
|
||||
SettingsEntry(title = "About", description = "About") { }
|
||||
SettingsSection("Data management")
|
||||
SettingsEntry(title = "Export data", description = "Export application database") {
|
||||
settingsScreenController.onClickOpenDirectory()
|
||||
@@ -53,14 +64,6 @@ fun SettingsScreen(
|
||||
SettingsEntry(title = "Import data", description = "Import application database") {
|
||||
settingsScreenController.onClickImportDatabase()
|
||||
}
|
||||
SettingsSection("DiM/BEm management")
|
||||
SettingsEntry(title = "Import DiM card", description = "Import DiM/BEm card file") {
|
||||
settingsScreenController.onClickImportCard()
|
||||
}
|
||||
SettingsEntry(title = "Rename DiM/BEm", description = "Set card name") { }
|
||||
SettingsSection("About and credits")
|
||||
SettingsEntry(title = "Credits", description = "Credits") { }
|
||||
SettingsEntry(title = "About", description = "About") { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+302
-56
@@ -10,12 +10,17 @@ import androidx.activity.ComponentActivity
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import com.github.cfogrady.vb.dim.card.BemCard
|
||||
import com.github.cfogrady.vb.dim.card.DimCard
|
||||
import com.github.cfogrady.vb.dim.card.DimReader
|
||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.domain.Sprites
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Card
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Character
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Sprite
|
||||
import com.github.nacabaro.vbhelper.domain.card.Card
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardBackground
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardProgress
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardCharacter
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardSprites
|
||||
import com.github.nacabaro.vbhelper.source.ApkSecretsImporter
|
||||
import com.github.nacabaro.vbhelper.source.SecretsImporter
|
||||
import com.github.nacabaro.vbhelper.source.SecretsRepository
|
||||
@@ -106,83 +111,324 @@ class SettingsScreenControllerImpl(
|
||||
filePickerCard.launch(arrayOf("*/*"))
|
||||
}
|
||||
|
||||
private suspend fun importEvoData(
|
||||
cardId: Long,
|
||||
card: com.github.cfogrady.vb.dim.card.Card<*, *, *, *, *, *>
|
||||
) {
|
||||
for (index in 0 until card.transformationRequirements.transformationEntries.size) {
|
||||
val evo = card.transformationRequirements.transformationEntries[index]
|
||||
|
||||
var transformationTimerHours: Int
|
||||
var unlockAdventureLevel: Int
|
||||
|
||||
if (card is BemCard) {
|
||||
transformationTimerHours = card
|
||||
.transformationRequirements
|
||||
.transformationEntries[index]
|
||||
.minutesUntilTransformation / 60
|
||||
unlockAdventureLevel = if (
|
||||
card
|
||||
.transformationRequirements
|
||||
.transformationEntries[index]
|
||||
.requiredCompletedAdventureLevel == 65535
|
||||
) {
|
||||
0
|
||||
} else {
|
||||
card
|
||||
.transformationRequirements
|
||||
.transformationEntries[index]
|
||||
.requiredCompletedAdventureLevel
|
||||
}
|
||||
} else {
|
||||
transformationTimerHours = (card as DimCard)
|
||||
.transformationRequirements
|
||||
.transformationEntries[index]
|
||||
.hoursUntilEvolution
|
||||
unlockAdventureLevel = if (
|
||||
card
|
||||
.adventureLevels
|
||||
.levels
|
||||
.last()
|
||||
.bossCharacterIndex == card.transformationRequirements.transformationEntries[index].toCharacterIndex
|
||||
) {
|
||||
14
|
||||
/*
|
||||
Magic number incoming!!
|
||||
|
||||
In the case of DiMCards, stage 15 is the one that unlocks the locked character.
|
||||
We know it is a locked character if the last adventure level's boss character index
|
||||
is the current index. If it is, we add stage 15 complete as a requirement for transformation.
|
||||
*/
|
||||
} else {
|
||||
0
|
||||
/*
|
||||
Another magic number...
|
||||
|
||||
The rest of the characters are not locked.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
database
|
||||
.characterDao()
|
||||
.insertPossibleTransformation(
|
||||
cardId = cardId,
|
||||
fromChraraIndex = evo.fromCharacterIndex,
|
||||
toChraraIndex = evo.toCharacterIndex,
|
||||
requiredVitals = evo.requiredVitalValues,
|
||||
requiredTrophies = evo.requiredTrophies,
|
||||
requiredBattles = evo.requiredBattles,
|
||||
requiredWinRate = evo.requiredWinRatio,
|
||||
requiredAdventureLevelCompleted = unlockAdventureLevel,
|
||||
changeTimerHours = transformationTimerHours
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun importCharacterData(
|
||||
cardId: Long,
|
||||
card: com.github.cfogrady.vb.dim.card.Card<*, *, *, *, *, *>
|
||||
) {
|
||||
var spriteCounter = when (card is BemCard) {
|
||||
true -> 54
|
||||
false -> 10
|
||||
}
|
||||
|
||||
val domainCharacters = mutableListOf<CardCharacter>()
|
||||
|
||||
val characters = card
|
||||
.characterStats
|
||||
.characterEntries
|
||||
|
||||
for (index in 0 until characters.size) {
|
||||
var domainSprite: Sprite?
|
||||
if (index < 2 && card is DimCard) {
|
||||
domainSprite = Sprite(
|
||||
width = card.spriteData.sprites[spriteCounter + 1].spriteDimensions.width,
|
||||
height = card.spriteData.sprites[spriteCounter + 1].spriteDimensions.height,
|
||||
spriteIdle1 = card.spriteData.sprites[spriteCounter + 1].pixelData,
|
||||
spriteIdle2 = card.spriteData.sprites[spriteCounter + 2].pixelData,
|
||||
spriteWalk1 = card.spriteData.sprites[spriteCounter + 1].pixelData,
|
||||
spriteWalk2 = card.spriteData.sprites[spriteCounter + 3].pixelData,
|
||||
spriteRun1 = card.spriteData.sprites[spriteCounter + 1].pixelData,
|
||||
spriteRun2 = card.spriteData.sprites[spriteCounter + 3].pixelData,
|
||||
spriteTrain1 = card.spriteData.sprites[spriteCounter + 1].pixelData,
|
||||
spriteTrain2 = card.spriteData.sprites[spriteCounter + 3].pixelData,
|
||||
spriteHappy = card.spriteData.sprites[spriteCounter + 4].pixelData,
|
||||
spriteSleep = card.spriteData.sprites[spriteCounter + 5].pixelData,
|
||||
spriteAttack = card.spriteData.sprites[spriteCounter + 2].pixelData,
|
||||
spriteDodge = card.spriteData.sprites[spriteCounter + 3].pixelData,
|
||||
)
|
||||
} else {
|
||||
domainSprite = Sprite(
|
||||
width = card.spriteData.sprites[spriteCounter + 1].spriteDimensions.width,
|
||||
height = card.spriteData.sprites[spriteCounter + 1].spriteDimensions.height,
|
||||
spriteIdle1 = card.spriteData.sprites[spriteCounter + 1].pixelData,
|
||||
spriteIdle2 = card.spriteData.sprites[spriteCounter + 2].pixelData,
|
||||
spriteWalk1 = card.spriteData.sprites[spriteCounter + 3].pixelData,
|
||||
spriteWalk2 = card.spriteData.sprites[spriteCounter + 4].pixelData,
|
||||
spriteRun1 = card.spriteData.sprites[spriteCounter + 5].pixelData,
|
||||
spriteRun2 = card.spriteData.sprites[spriteCounter + 6].pixelData,
|
||||
spriteTrain1 = card.spriteData.sprites[spriteCounter + 7].pixelData,
|
||||
spriteTrain2 = card.spriteData.sprites[spriteCounter + 8].pixelData,
|
||||
spriteHappy = card.spriteData.sprites[spriteCounter + 9].pixelData,
|
||||
spriteSleep = card.spriteData.sprites[spriteCounter + 10].pixelData,
|
||||
spriteAttack = card.spriteData.sprites[spriteCounter + 11].pixelData,
|
||||
spriteDodge = card.spriteData.sprites[spriteCounter + 12].pixelData
|
||||
)
|
||||
}
|
||||
|
||||
val spriteId = database
|
||||
.spriteDao()
|
||||
.insertSprite(domainSprite)
|
||||
|
||||
|
||||
domainCharacters.add(
|
||||
CardCharacter(
|
||||
cardId = cardId,
|
||||
spriteId = spriteId,
|
||||
charaIndex = index,
|
||||
nameSprite = card.spriteData.sprites[spriteCounter].pixelData,
|
||||
stage = characters[index].stage,
|
||||
attribute = NfcCharacter.Attribute.entries[characters[index].attribute],
|
||||
baseHp = characters[index].hp,
|
||||
baseBp = characters[index].dp,
|
||||
baseAp = characters[index].ap,
|
||||
nameWidth = card.spriteData.sprites[spriteCounter].spriteDimensions.width,
|
||||
nameHeight = card.spriteData.sprites[spriteCounter].spriteDimensions.height
|
||||
)
|
||||
)
|
||||
|
||||
spriteCounter += if (card is BemCard) {
|
||||
14
|
||||
} else {
|
||||
when (index) {
|
||||
0 -> 6
|
||||
1 -> 7
|
||||
else -> 14
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
database
|
||||
.characterDao()
|
||||
.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,
|
||||
toCharaIdVirus = it.attribute1Fusion,
|
||||
toCharaIdData = it.attribute2Fusion,
|
||||
toCharaIdVaccine = it.attribute3Fusion,
|
||||
toCharaIdFree = it.attribute4Fusion
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateCardProgress(
|
||||
cardId: Long,
|
||||
) {
|
||||
val cardProgress = CardProgress(
|
||||
cardId = cardId,
|
||||
currentStage = 0,
|
||||
unlocked = false
|
||||
)
|
||||
|
||||
database
|
||||
.cardProgressDao()
|
||||
.updateDimProgress(cardProgress)
|
||||
}
|
||||
|
||||
private suspend fun importBackgrounds(
|
||||
cardId: Long,
|
||||
card: com.github.cfogrady.vb.dim.card.Card<*, *, *, *, *, *>
|
||||
) {
|
||||
val backgrounds = mutableListOf<CardBackground>()
|
||||
|
||||
if (card is DimCard) {
|
||||
backgrounds.add(
|
||||
CardBackground(
|
||||
cardId = cardId,
|
||||
background = card.spriteData.sprites[1].pixelData,
|
||||
backgroundWidth = card.spriteData.sprites[1].width,
|
||||
backgroundHeight = card.spriteData.sprites[1].height
|
||||
)
|
||||
)
|
||||
} else if (card is BemCard) {
|
||||
val possibleBackgroundsIds = listOf(1, 10, 30, 31, 32, 33)
|
||||
for (id in possibleBackgroundsIds) {
|
||||
backgrounds.add(
|
||||
CardBackground(
|
||||
cardId = cardId,
|
||||
background = card.spriteData.sprites[id].pixelData,
|
||||
backgroundWidth = card.spriteData.sprites[id].width,
|
||||
backgroundHeight = card.spriteData.sprites[id].height
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
database
|
||||
.cardBackgroundDao()
|
||||
.insertCardBackground(*backgrounds.toTypedArray())
|
||||
}
|
||||
|
||||
private fun importCard(uri: Uri) {
|
||||
context.lifecycleScope.launch(Dispatchers.IO) {
|
||||
val contentResolver = context.contentResolver
|
||||
val inputStream = contentResolver.openInputStream(uri)
|
||||
|
||||
inputStream.use { fileReader ->
|
||||
val dimReader = DimReader()
|
||||
val card = dimReader.readCard(fileReader, false)
|
||||
|
||||
val cardModel = Card(
|
||||
dimId = card.header.dimId,
|
||||
cardId = card.header.dimId,
|
||||
logo = card.spriteData.sprites[0].pixelData,
|
||||
name = card.spriteData.text, // TODO Make user write card name// TODO Make user write card name
|
||||
name = card.spriteData.text,
|
||||
stageCount = card.adventureLevels.levels.size,
|
||||
logoHeight = card.spriteData.sprites[0].height,
|
||||
logoWidth = card.spriteData.sprites[0].width,
|
||||
isBEm = card is BemCard
|
||||
)
|
||||
|
||||
val dimId = database
|
||||
.dimDao()
|
||||
.insertNewDim(cardModel)
|
||||
val cardId = database
|
||||
.cardDao()
|
||||
.insertNewCard(cardModel)
|
||||
|
||||
val characters = card.characterStats.characterEntries
|
||||
updateCardProgress(cardId = cardId)
|
||||
|
||||
var spriteCounter = when (card is BemCard) {
|
||||
true -> 55
|
||||
false -> 10
|
||||
}
|
||||
importCharacterData(cardId, card)
|
||||
|
||||
val domainCharacters = mutableListOf<Character>()
|
||||
importEvoData(cardId, card)
|
||||
|
||||
for (index in 0 until characters.size) {
|
||||
domainCharacters.add(
|
||||
Character(
|
||||
dimId = dimId,
|
||||
monIndex = index,
|
||||
name = card.spriteData.sprites[spriteCounter].pixelData,
|
||||
stage = characters[index].stage,
|
||||
attribute = characters[index].attribute,
|
||||
baseHp = characters[index].hp,
|
||||
baseBp = characters[index].dp,
|
||||
baseAp = characters[index].ap,
|
||||
sprite1 = card.spriteData.sprites[spriteCounter + 1].pixelData,
|
||||
sprite2 = card.spriteData.sprites[spriteCounter + 2].pixelData,
|
||||
nameWidth = card.spriteData.sprites[spriteCounter].width,
|
||||
nameHeight = card.spriteData.sprites[spriteCounter].height,
|
||||
spritesWidth = card.spriteData.sprites[spriteCounter + 1].width,
|
||||
spritesHeight = card.spriteData.sprites[spriteCounter + 1].height
|
||||
)
|
||||
importAdventureMissions(cardId, card)
|
||||
|
||||
importCardFusions(cardId, card)
|
||||
|
||||
importBackgrounds(cardId, card)
|
||||
|
||||
val cardSprites: List<CardSprites> = card.spriteData.sprites.map {
|
||||
CardSprites(
|
||||
sprite = it.pixelData,
|
||||
width = it.width,
|
||||
height = it.height
|
||||
)
|
||||
|
||||
spriteCounter += if (card is BemCard) {
|
||||
14
|
||||
} else {
|
||||
when (index) {
|
||||
0 -> 6
|
||||
1 -> 7
|
||||
else -> 14
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
database
|
||||
.characterDao()
|
||||
.insertCharacter(*domainCharacters.toTypedArray())
|
||||
|
||||
val sprites = card.spriteData.sprites.map { sprite ->
|
||||
Sprites(
|
||||
id = 0,
|
||||
sprite = sprite.pixelData,
|
||||
width = sprite.width,
|
||||
height = sprite.height
|
||||
)
|
||||
}
|
||||
database
|
||||
.characterDao()
|
||||
.insertSprite(*sprites.toTypedArray())
|
||||
.cardDao()
|
||||
.insertSprites(*cardSprites.toTypedArray())
|
||||
}
|
||||
|
||||
inputStream?.close()
|
||||
|
||||
+9
-32
@@ -1,55 +1,38 @@
|
||||
package com.github.nacabaro.vbhelper.screens
|
||||
package com.github.nacabaro.vbhelper.screens.spriteViewer
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
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.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
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.mutableStateListOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import com.github.nacabaro.vbhelper.components.TopBanner
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.domain.Sprites
|
||||
import com.github.nacabaro.vbhelper.source.SpriteRepo
|
||||
import kotlinx.coroutines.launch
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
@Composable
|
||||
fun SpriteViewer(
|
||||
navController: NavController
|
||||
navController: NavController,
|
||||
spriteViewerController: SpriteViewerController
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val application = LocalContext.current.applicationContext as VBHelper
|
||||
val db = application.container.db
|
||||
val spriteRepo = SpriteRepo(db)
|
||||
|
||||
val spriteList = remember { mutableStateListOf<Sprites>() }
|
||||
val spriteList = remember { mutableStateListOf<Bitmap>() }
|
||||
|
||||
Log.d("SpriteViewer", "spriteList: $spriteList")
|
||||
|
||||
LaunchedEffect(spriteRepo) {
|
||||
coroutineScope.launch {
|
||||
spriteList.clear()
|
||||
spriteList.addAll(spriteRepo.getAllSprites())
|
||||
}
|
||||
LaunchedEffect(spriteViewerController) {
|
||||
val sprites = spriteViewerController.getAllSprites()
|
||||
val bitmapData = spriteViewerController.convertToBitmap(sprites)
|
||||
spriteList.addAll(bitmapData)
|
||||
}
|
||||
|
||||
Scaffold (
|
||||
@@ -69,13 +52,7 @@ fun SpriteViewer(
|
||||
.padding(top = contentPadding.calculateTopPadding())
|
||||
) {
|
||||
items(spriteList) { sprite ->
|
||||
val bitmap = remember (sprite.sprite) {
|
||||
Log.d("SpriteViewer", "sprite: $sprite")
|
||||
Bitmap.createBitmap(sprite.width, sprite.height, Bitmap.Config.RGB_565).apply {
|
||||
copyPixelsFromBuffer(ByteBuffer.wrap(sprite.sprite))
|
||||
}
|
||||
}
|
||||
val imageBitmap = remember(bitmap) { bitmap.asImageBitmap() }
|
||||
val imageBitmap = remember(sprite) { sprite.asImageBitmap() }
|
||||
Image(
|
||||
bitmap = imageBitmap,
|
||||
contentDescription = "Sprite",
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.github.nacabaro.vbhelper.screens.spriteViewer
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardBackground
|
||||
|
||||
interface SpriteViewerController {
|
||||
suspend fun getAllSprites(): List<CardBackground>
|
||||
fun convertToBitmap(sprites: List<CardBackground>): List<Bitmap>
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.github.nacabaro.vbhelper.screens.spriteViewer
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import androidx.activity.ComponentActivity
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import java.nio.ByteBuffer
|
||||
import androidx.core.graphics.createBitmap
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardBackground
|
||||
|
||||
class SpriteViewerControllerImpl(
|
||||
private val context: ComponentActivity
|
||||
) : SpriteViewerController {
|
||||
override suspend fun getAllSprites(): List<CardBackground> {
|
||||
val applicationContext = context.applicationContext as VBHelper
|
||||
val db = applicationContext.container.db
|
||||
val sprites = db.cardBackgroundDao().getBackgrounds()
|
||||
return sprites
|
||||
}
|
||||
|
||||
// I don't like this, chief
|
||||
override fun convertToBitmap(sprites: List<CardBackground>): List<Bitmap> {
|
||||
val bitmapList = mutableListOf<Bitmap>()
|
||||
|
||||
for (sprite in sprites) {
|
||||
bitmapList.add(createBitmap(sprite.backgroundWidth, sprite.backgroundHeight, Bitmap.Config.RGB_565).apply {
|
||||
copyPixelsFromBuffer(ByteBuffer.wrap(sprite.background))
|
||||
})
|
||||
}
|
||||
|
||||
return bitmapList
|
||||
}
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
package com.github.nacabaro.vbhelper.screens.storageScreen
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import com.github.nacabaro.vbhelper.R
|
||||
|
||||
fun getAdventureTime(time: Int): String {
|
||||
return when (time) {
|
||||
360 -> "6 hours"
|
||||
720 -> "12 hours"
|
||||
1440 -> "24 hours"
|
||||
else -> "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun StorageAdventureTimeDialog(
|
||||
onClickSendToAdventure: (time: Long) -> Unit,
|
||||
onDismissRequest: () -> Unit
|
||||
) {
|
||||
val times = arrayOf(360, 720, 1440)
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
var itemPosition by remember { mutableIntStateOf(-1) }
|
||||
|
||||
Dialog(
|
||||
onDismissRequest = onDismissRequest
|
||||
) {
|
||||
Card {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Row (
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
modifier = Modifier
|
||||
.width(256.dp)
|
||||
.clickable(true) {
|
||||
expanded = true
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
text = when (itemPosition) {
|
||||
-1 -> "Choose time"
|
||||
else -> getAdventureTime(times[itemPosition])
|
||||
}
|
||||
)
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.baseline_single_arrow_down),
|
||||
contentDescription = "Show more"
|
||||
)
|
||||
}
|
||||
DropdownMenu(
|
||||
expanded = expanded,
|
||||
onDismissRequest = { expanded = false },
|
||||
modifier = Modifier
|
||||
.width(256.dp)
|
||||
) {
|
||||
times.forEach { time ->
|
||||
DropdownMenuItem(
|
||||
text = { Text(getAdventureTime(time)) },
|
||||
onClick = {
|
||||
itemPosition = times.indexOf(time)
|
||||
expanded = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Button(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
onClick = {
|
||||
if (itemPosition != -1) {
|
||||
onClickSendToAdventure(times[itemPosition].toLong())
|
||||
onDismissRequest()
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text(text = "Send on adventure")
|
||||
}
|
||||
Button(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
onClick = onDismissRequest
|
||||
) {
|
||||
Text(text = "Dismiss")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
package com.github.nacabaro.vbhelper.screens.storageScreen
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
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.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.FilterQuality
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import com.github.nacabaro.vbhelper.source.StorageRepository
|
||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||
import com.github.nacabaro.vbhelper.utils.getBitmap
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun StorageDialog(
|
||||
characterId: Long,
|
||||
onDismissRequest: () -> Unit,
|
||||
onSendToBracelet: () -> Unit,
|
||||
onClickSetActive: () -> Unit,
|
||||
onClickSendToAdventure: (time: Long) -> Unit
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val application = LocalContext.current.applicationContext as VBHelper
|
||||
val storageRepository = StorageRepository(application.container.db)
|
||||
val character = remember { mutableStateOf<CharacterDtos.CharacterWithSprites?>(null) }
|
||||
val characterSprite = remember { mutableStateOf<BitmapData?>(null) }
|
||||
val characterName = remember { mutableStateOf<BitmapData?>(null) }
|
||||
var onSendToAdventureClicked by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(storageRepository) {
|
||||
coroutineScope.launch {
|
||||
character.value = storageRepository.getSingleCharacter(characterId)
|
||||
characterSprite.value = BitmapData(
|
||||
bitmap = character.value!!.spriteIdle,
|
||||
width = character.value!!.spriteWidth,
|
||||
height = character.value!!.spriteHeight
|
||||
)
|
||||
characterName.value = BitmapData(
|
||||
bitmap = character.value!!.nameSprite,
|
||||
width = character.value!!.nameSpriteWidth,
|
||||
height = character.value!!.nameSpriteHeight
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Dialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
properties = DialogProperties(
|
||||
dismissOnBackPress = true,
|
||||
dismissOnClickOutside = true
|
||||
)
|
||||
) {
|
||||
Card(
|
||||
shape = RoundedCornerShape(16.dp)
|
||||
) {
|
||||
Column (
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
) {
|
||||
if (character.value != null &&
|
||||
characterSprite.value != null &&
|
||||
characterName.value != null
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
val bitmap = remember (characterSprite.value!!) { characterSprite.value!!.getBitmap() }
|
||||
val imageBitmap = remember(bitmap) { bitmap.asImageBitmap() }
|
||||
val density: Float = LocalContext.current.resources.displayMetrics.density
|
||||
val dpSize = (characterSprite.value!!.width * 4 / density).dp
|
||||
Image(
|
||||
bitmap = imageBitmap,
|
||||
contentDescription = "Character image",
|
||||
filterQuality = FilterQuality.None,
|
||||
modifier = Modifier
|
||||
.size(dpSize)
|
||||
)
|
||||
val nameBitmap = remember (characterName.value!!) { characterName.value!!.getBitmap() }
|
||||
val nameImageBitmap = remember(nameBitmap) { nameBitmap.asImageBitmap() }
|
||||
val nameDpSize = (characterName.value!!.width * 4 / density).dp
|
||||
Image(
|
||||
bitmap = nameImageBitmap,
|
||||
contentDescription = "Character image",
|
||||
filterQuality = FilterQuality.None,
|
||||
modifier = Modifier
|
||||
.size(nameDpSize)
|
||||
)
|
||||
}
|
||||
}
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
Button(
|
||||
onClick = onSendToBracelet,
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
) {
|
||||
Text(text = "Send to watch")
|
||||
}
|
||||
Spacer(
|
||||
modifier = Modifier
|
||||
.padding(4.dp)
|
||||
)
|
||||
Button(
|
||||
onClick = onClickSetActive,
|
||||
) {
|
||||
Text(text = "Set active")
|
||||
}
|
||||
}
|
||||
Button(
|
||||
onClick = {
|
||||
onSendToAdventureClicked = true
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
Text(text = "Send on adventure")
|
||||
}
|
||||
Button(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
onClick = onDismissRequest
|
||||
) {
|
||||
Text(text = "Close")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (onSendToAdventureClicked) {
|
||||
StorageAdventureTimeDialog(
|
||||
onClickSendToAdventure = { time ->
|
||||
onClickSendToAdventure(time)
|
||||
},
|
||||
onDismissRequest = { onSendToAdventureClicked = false }
|
||||
)
|
||||
}
|
||||
}
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
package com.github.nacabaro.vbhelper.screens.storageScreen
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.gestures.Orientation
|
||||
import androidx.compose.foundation.gestures.scrollable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.navigation.NavController
|
||||
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.adventureScreen.AdventureScreenControllerImpl
|
||||
import com.github.nacabaro.vbhelper.source.StorageRepository
|
||||
import com.github.nacabaro.vbhelper.utils.BitmapData
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
@Composable
|
||||
fun StorageScreen(
|
||||
navController: NavController,
|
||||
storageScreenController: StorageScreenControllerImpl,
|
||||
adventureScreenController: AdventureScreenControllerImpl
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val application = LocalContext.current.applicationContext as VBHelper
|
||||
val storageRepository = StorageRepository(application.container.db)
|
||||
val monList = remember { mutableStateOf<List<CharacterDtos.CharacterWithSprites>>(emptyList()) }
|
||||
var selectedCharacter by remember { mutableStateOf<Long?>(null) }
|
||||
|
||||
LaunchedEffect(storageRepository, selectedCharacter) {
|
||||
coroutineScope.launch {
|
||||
val characterList = storageRepository.getAllCharacters()
|
||||
monList.value = characterList
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold (
|
||||
topBar = {
|
||||
TopBanner(
|
||||
text = "My characters",
|
||||
onAdventureClick = {
|
||||
navController.navigate(NavigationItems.Adventure.route)
|
||||
}
|
||||
)
|
||||
}
|
||||
) { contentPadding ->
|
||||
if (monList.value.isEmpty()) {
|
||||
Column (
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
modifier = Modifier
|
||||
.padding(top = contentPadding.calculateTopPadding())
|
||||
.fillMaxSize()
|
||||
) {
|
||||
Text(
|
||||
text = "Nothing to see here",
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
)
|
||||
}
|
||||
} else {
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Fixed(3),
|
||||
modifier = Modifier
|
||||
.scrollable(state = rememberScrollState(), orientation = Orientation.Vertical)
|
||||
.padding(top = contentPadding.calculateTopPadding())
|
||||
) {
|
||||
items(monList.value) { index ->
|
||||
CharacterEntry(
|
||||
icon = BitmapData(
|
||||
bitmap = index.spriteIdle,
|
||||
width = index.spriteWidth,
|
||||
height = index.spriteHeight
|
||||
),
|
||||
onClick = {
|
||||
if (!index.isInAdventure) {
|
||||
selectedCharacter = index.id
|
||||
} else {
|
||||
Toast.makeText(
|
||||
application,
|
||||
"This character is in an adventure",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
navController.navigate(
|
||||
NavigationItems.Adventure.route
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedCharacter != null) {
|
||||
StorageDialog(
|
||||
characterId = selectedCharacter!!,
|
||||
onDismissRequest = { selectedCharacter = null },
|
||||
onClickSetActive = {
|
||||
storageScreenController
|
||||
.setActive(selectedCharacter!!) {
|
||||
selectedCharacter = null
|
||||
navController.navigate(NavigationItems.Home.route)
|
||||
}
|
||||
},
|
||||
onSendToBracelet = {
|
||||
navController.navigate(
|
||||
NavigationItems.Scan.route.replace(
|
||||
"{characterId}",
|
||||
selectedCharacter.toString()
|
||||
)
|
||||
)
|
||||
},
|
||||
onClickSendToAdventure = { time ->
|
||||
adventureScreenController
|
||||
.sendCharacterToAdventure(
|
||||
characterId = selectedCharacter!!,
|
||||
timeInMinutes = time
|
||||
)
|
||||
selectedCharacter = null
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package com.github.nacabaro.vbhelper.screens.storageScreen
|
||||
|
||||
interface StorageScreenController {
|
||||
fun setActive(characterId: Long, onCompletion: () -> Unit)
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.github.nacabaro.vbhelper.screens.storageScreen
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class StorageScreenControllerImpl(
|
||||
private val componentActivity: ComponentActivity
|
||||
): StorageScreenController {
|
||||
private val application = componentActivity.applicationContext as VBHelper
|
||||
private val database = application.container.db
|
||||
|
||||
override fun setActive(characterId: Long, onCompletion: () -> Unit) {
|
||||
componentActivity.lifecycleScope.launch(Dispatchers.IO) {
|
||||
database.userCharacterDao().clearActiveCharacter()
|
||||
database.userCharacterDao().setActiveCharacter(characterId)
|
||||
|
||||
componentActivity.runOnUiThread {
|
||||
Toast.makeText(
|
||||
componentActivity,
|
||||
"Active character updated!",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
onCompletion()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.github.nacabaro.vbhelper.source
|
||||
|
||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Card
|
||||
import com.github.nacabaro.vbhelper.dtos.CardDtos
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
|
||||
@@ -12,7 +11,11 @@ class DexRepository (
|
||||
return db.dexDao().getCardsWithProgress()
|
||||
}
|
||||
|
||||
suspend fun getCharactersByDimId(cardId: Long): List<CharacterDtos.CardProgress> {
|
||||
suspend fun getCharactersByCardId(cardId: Long): List<CharacterDtos.CardCharaProgress> {
|
||||
return db.dexDao().getSingleCardProgress(cardId)
|
||||
}
|
||||
|
||||
suspend fun getCardPossibleTransformations(cardId: Long): List<CharacterDtos.EvolutionRequirementsWithSpritesAndObtained> {
|
||||
return db.characterDao().getEvolutionRequirementsForCard(cardId)
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.github.nacabaro.vbhelper.source
|
||||
|
||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||
import com.github.nacabaro.vbhelper.domain.Sprites
|
||||
|
||||
class SpriteRepo (
|
||||
private val db: AppDatabase
|
||||
) {
|
||||
suspend fun getAllSprites(): List<Sprites> {
|
||||
return db.characterDao().getAllSprites()
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user