Compare 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 | ||
|
|
9f5f806786 | ||
|
|
f7b3b7256a |
@@ -15,7 +15,7 @@ android {
|
||||
minSdk = 28
|
||||
targetSdk = 35
|
||||
versionCode = 1
|
||||
versionName = "Alpha 0.1"
|
||||
versionName = "Alpha 0.6.1"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 17 KiB |
@@ -14,6 +14,8 @@ import com.github.nacabaro.vbhelper.screens.itemsScreen.ItemsScreenControllerImp
|
||||
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
|
||||
|
||||
@@ -45,6 +47,8 @@ class MainActivity : ComponentActivity() {
|
||||
val adventureScreenController = AdventureScreenControllerImpl(this)
|
||||
val storageScreenController = StorageScreenControllerImpl(this)
|
||||
val homeScreenController = HomeScreenControllerImpl(this)
|
||||
val spriteViewerController = SpriteViewerControllerImpl(this)
|
||||
val cardScreenController = CardScreenControllerImpl(this)
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
@@ -58,7 +62,9 @@ class MainActivity : ComponentActivity() {
|
||||
itemsScreenController = itemsScreenController,
|
||||
adventureScreenController = adventureScreenController,
|
||||
homeScreenController = homeScreenController,
|
||||
storageScreenController = storageScreenController
|
||||
storageScreenController = storageScreenController,
|
||||
spriteViewerController = spriteViewerController,
|
||||
cardScreenController = cardScreenController
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -90,8 +96,9 @@ class MainActivity : ComponentActivity() {
|
||||
adventureScreenController: AdventureScreenControllerImpl,
|
||||
storageScreenController: StorageScreenControllerImpl,
|
||||
homeScreenController: HomeScreenControllerImpl,
|
||||
|
||||
) {
|
||||
spriteViewerController: SpriteViewerControllerImpl,
|
||||
cardScreenController: CardScreenControllerImpl
|
||||
) {
|
||||
AppNavigation(
|
||||
applicationNavigationHandlers = AppNavigationHandlers(
|
||||
settingsScreenController,
|
||||
@@ -99,7 +106,9 @@ class MainActivity : ComponentActivity() {
|
||||
itemsScreenController,
|
||||
adventureScreenController,
|
||||
storageScreenController,
|
||||
homeScreenController
|
||||
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
|
||||
@@ -114,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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,8 @@ fun TopBanner(
|
||||
onGearClick: (() -> Unit)? = null,
|
||||
onBackClick: (() -> Unit)? = null,
|
||||
onScanClick: (() -> Unit)? = null,
|
||||
onAdventureClick: (() -> Unit)? = null
|
||||
onAdventureClick: (() -> Unit)? = null,
|
||||
onModifyClick: (() -> Unit)? = null
|
||||
) {
|
||||
Box( // Use Box to overlay elements
|
||||
modifier = modifier
|
||||
@@ -37,16 +38,16 @@ 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"
|
||||
)
|
||||
}
|
||||
@@ -54,23 +55,34 @@ fun TopBanner(
|
||||
IconButton(
|
||||
onClick = onAdventureClick,
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterEnd) // Place gear icon at the end
|
||||
.align(Alignment.CenterEnd)
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.baseline_fort_24), // Use a gear 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"
|
||||
)
|
||||
}
|
||||
@@ -78,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"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -18,22 +18,25 @@ interface AdventureDao {
|
||||
""")
|
||||
fun getAdventureCount(): Int
|
||||
|
||||
@Query("""
|
||||
@Query(
|
||||
"""
|
||||
SELECT
|
||||
uc.*,
|
||||
c.stage,
|
||||
c.attribute,
|
||||
c.sprite1 AS spriteIdle,
|
||||
c.spritesWidth AS spriteWidth,
|
||||
c.spritesHeight AS spriteHeight,
|
||||
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 Character c ON uc.charId = c.id
|
||||
JOIN Card d ON c.dimId = d.id
|
||||
JOIN CardCharacter c ON uc.charId = c.id
|
||||
JOIN Sprite s ON s.id = c.spriteId
|
||||
JOIN Card d ON c.cardId = d.id
|
||||
JOIN Adventure a ON uc.id = a.characterId
|
||||
""")
|
||||
"""
|
||||
)
|
||||
suspend fun getAdventureCharacters(): List<CharacterDtos.AdventureCharacterWithSprites>
|
||||
|
||||
@Query("""
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -31,7 +31,7 @@ interface ItemDao {
|
||||
WHERE Items.id = :itemId
|
||||
"""
|
||||
)
|
||||
fun getItem(itemId: Long): ItemDtos.ItemsWithQuantities
|
||||
suspend fun getItem(itemId: Long): ItemDtos.ItemsWithQuantities
|
||||
|
||||
@Query(
|
||||
"""
|
||||
@@ -40,7 +40,7 @@ interface ItemDao {
|
||||
WHERE id = :itemId
|
||||
"""
|
||||
)
|
||||
fun useItem(itemId: Long)
|
||||
suspend fun useItem(itemId: Long)
|
||||
|
||||
@Query(
|
||||
"""
|
||||
|
||||
@@ -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,10 +5,13 @@ import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Upsert
|
||||
import com.github.nacabaro.vbhelper.domain.characters.Character
|
||||
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
|
||||
@@ -19,6 +22,9 @@ interface UserCharacterDao {
|
||||
@Insert
|
||||
fun insertBECharacterData(characterData: BECharacterData)
|
||||
|
||||
@Insert
|
||||
fun insertVBCharacterData(characterData: VBCharacterData)
|
||||
|
||||
@Upsert
|
||||
fun updateCharacter(character: UserCharacter)
|
||||
|
||||
@@ -28,19 +34,25 @@ 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(
|
||||
"""
|
||||
@@ -48,17 +60,19 @@ interface UserCharacterDao {
|
||||
uc.*,
|
||||
c.stage,
|
||||
c.attribute,
|
||||
c.sprite1 AS spriteIdle,
|
||||
c.spritesWidth AS spriteWidth,
|
||||
c.spritesHeight AS spriteHeight,
|
||||
c.name as nameSprite,
|
||||
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
|
||||
"""
|
||||
)
|
||||
@@ -70,20 +84,23 @@ interface UserCharacterDao {
|
||||
uc.*,
|
||||
c.stage,
|
||||
c.attribute,
|
||||
c.sprite1 AS spriteIdle,
|
||||
c.spritesWidth AS spriteWidth,
|
||||
c.spritesHeight AS spriteHeight,
|
||||
c.name as nameSprite,
|
||||
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 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")
|
||||
@@ -92,27 +109,36 @@ interface UserCharacterDao {
|
||||
@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.stage,
|
||||
c.attribute,
|
||||
c.sprite1 AS spriteIdle,
|
||||
c.spritesWidth AS spriteWidth,
|
||||
c.spritesHeight AS spriteHeight,
|
||||
c.name as nameSprite,
|
||||
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
|
||||
""")
|
||||
"""
|
||||
)
|
||||
suspend fun getActiveCharacter(): CharacterDtos.CharacterWithSprites?
|
||||
|
||||
@Query("DELETE FROM UserCharacter WHERE id = :id")
|
||||
@@ -127,11 +153,79 @@ interface UserCharacterDao {
|
||||
@Query(
|
||||
"""
|
||||
SELECT c.*
|
||||
FROM Character c
|
||||
FROM CardCharacter c
|
||||
join UserCharacter uc on c.id = uc.charId
|
||||
where uc.id = :charId
|
||||
LIMIT 1
|
||||
"""
|
||||
)
|
||||
suspend fun getCharacterInfo(charId: Long): Character
|
||||
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>
|
||||
}
|
||||
@@ -3,40 +3,70 @@ 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
|
||||
|
||||
@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,
|
||||
Adventure::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 = [
|
||||
|
||||
@@ -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
|
||||
)
|
||||
@@ -1,39 +1,44 @@
|
||||
package com.github.nacabaro.vbhelper.domain.characters
|
||||
package com.github.nacabaro.vbhelper.domain.card
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
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 = ["dimId"],
|
||||
childColumns = ["cardId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
ForeignKey(
|
||||
entity = Sprite::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["spriteId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
/*
|
||||
* Character represents a character on a DIM card. There should only be one of these per dimId
|
||||
* 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 Character (
|
||||
data class CardCharacter (
|
||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||
val dimId: Long,
|
||||
val monIndex: Int,
|
||||
val name: ByteArray,
|
||||
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 sprite1: ByteArray,
|
||||
val sprite2: ByteArray,
|
||||
val nameSprite: ByteArray,
|
||||
val nameWidth: Int,
|
||||
val nameHeight: Int,
|
||||
val spritesWidth: Int,
|
||||
val spritesHeight: 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?
|
||||
)
|
||||
@@ -0,0 +1,21 @@
|
||||
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 CardProgress(
|
||||
@PrimaryKey val cardId: Long,
|
||||
val currentStage: Int,
|
||||
val unlocked: Boolean
|
||||
)
|
||||
@@ -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?
|
||||
)
|
||||
@@ -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
|
||||
)
|
||||
@@ -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,12 +5,12 @@ import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
import com.github.nacabaro.vbhelper.utils.DeviceType
|
||||
import com.github.nacabaro.vbhelper.domain.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
|
||||
@@ -24,7 +24,6 @@ data class UserCharacter (
|
||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||
var charId: Long,
|
||||
var ageInDays: Int,
|
||||
var nextAdventureMissionStage: Int, // next adventure mission stage on the character's dim
|
||||
var mood: Int,
|
||||
var vitalPoints: Int,
|
||||
var transformationCountdown: Int,
|
||||
|
||||
@@ -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,
|
||||
@@ -11,5 +18,6 @@ data class Items(
|
||||
val itemIcon: Int,
|
||||
val itemLength: Int,
|
||||
val price: Int,
|
||||
val quantity: 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,6 @@ 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,
|
||||
@@ -25,6 +24,7 @@ object CharacterDtos {
|
||||
var heartRateCurrent: Int,
|
||||
var characterType: DeviceType,
|
||||
val spriteIdle: ByteArray,
|
||||
val spriteIdle2: ByteArray,
|
||||
val spriteWidth: Int,
|
||||
val spriteHeight: Int,
|
||||
val nameSprite: ByteArray,
|
||||
@@ -34,9 +34,11 @@ object CharacterDtos {
|
||||
val isInAdventure: Boolean
|
||||
)
|
||||
|
||||
data class DiMInfo(
|
||||
val cardId: Int,
|
||||
val charId: Int
|
||||
data class CardCharacterInfo(
|
||||
val cardId: Long,
|
||||
val charId: Int,
|
||||
val stage: Int,
|
||||
val attribute: NfcCharacter.Attribute
|
||||
)
|
||||
|
||||
data class TransformationHistory(
|
||||
@@ -48,12 +50,27 @@ object CharacterDtos {
|
||||
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,
|
||||
val discoveredOn: Long?
|
||||
)
|
||||
|
||||
data class AdventureCharacterWithSprites(
|
||||
@@ -62,7 +79,6 @@ 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,
|
||||
@@ -82,4 +98,19 @@ object CharacterDtos {
|
||||
val finishesAdventure: Long,
|
||||
val originalTimeInMinutes: Long
|
||||
)
|
||||
|
||||
data class EvolutionRequirementsWithSpritesAndObtained(
|
||||
val charaId: Long,
|
||||
val fromCharaId: Long,
|
||||
val spriteIdle: ByteArray,
|
||||
val spriteWidth: Int,
|
||||
val spriteHeight: Int,
|
||||
val discoveredOn: Long?,
|
||||
val requiredTrophies: Int,
|
||||
val requiredVitals: Int,
|
||||
val requiredBattles: Int,
|
||||
val requiredWinRate: Int,
|
||||
val changeTimerHours: Int,
|
||||
val requiredAdventureLevelCompleted: Int
|
||||
)
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.github.nacabaro.vbhelper.dtos
|
||||
|
||||
import com.github.nacabaro.vbhelper.domain.items.ItemType
|
||||
|
||||
|
||||
object ItemDtos {
|
||||
data class ItemsWithQuantities(
|
||||
@@ -10,6 +12,7 @@ object ItemDtos {
|
||||
val itemLength: Int,
|
||||
val price: Int,
|
||||
val quantity: Int,
|
||||
val itemType: ItemType
|
||||
)
|
||||
|
||||
data class PurchasedItem(
|
||||
@@ -18,6 +21,7 @@ object ItemDtos {
|
||||
val itemDescription: String,
|
||||
val itemIcon: Int,
|
||||
val itemLength: Int,
|
||||
val itemAmount: Int
|
||||
val itemAmount: Int,
|
||||
val itemType: ItemType
|
||||
)
|
||||
}
|
||||
@@ -1,21 +1,32 @@
|
||||
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.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
|
||||
@@ -23,8 +34,12 @@ import com.github.nacabaro.vbhelper.screens.itemsScreen.ItemsScreenControllerImp
|
||||
import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreenControllerImpl
|
||||
import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreen
|
||||
import com.github.nacabaro.vbhelper.screens.adventureScreen.AdventureScreenControllerImpl
|
||||
import com.github.nacabaro.vbhelper.screens.cardScreen.CardAdventureScreen
|
||||
import com.github.nacabaro.vbhelper.screens.cardScreen.CardScreenControllerImpl
|
||||
import com.github.nacabaro.vbhelper.screens.settingsScreen.CreditsScreen
|
||||
import com.github.nacabaro.vbhelper.screens.spriteViewer.SpriteViewerControllerImpl
|
||||
import com.github.nacabaro.vbhelper.screens.storageScreen.StorageScreenControllerImpl
|
||||
import com.github.nacabaro.vbhelper.source.StorageRepository
|
||||
|
||||
data class AppNavigationHandlers(
|
||||
val settingsScreenController: SettingsScreenControllerImpl,
|
||||
@@ -32,7 +47,9 @@ data class AppNavigationHandlers(
|
||||
val itemsScreenController: ItemsScreenControllerImpl,
|
||||
val adventureScreenController: AdventureScreenControllerImpl,
|
||||
val storageScreenController: StorageScreenControllerImpl,
|
||||
val homeScreenController: HomeScreenControllerImpl
|
||||
val homeScreenController: HomeScreenControllerImpl,
|
||||
val spriteViewerController: SpriteViewerControllerImpl,
|
||||
val cardScreenController: CardScreenControllerImpl
|
||||
)
|
||||
|
||||
@Composable
|
||||
@@ -49,8 +66,19 @@ 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()
|
||||
@@ -70,17 +98,35 @@ fun AppNavigation(
|
||||
}
|
||||
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) {
|
||||
@@ -91,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()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -131,6 +178,17 @@ fun AppNavigation(
|
||||
navController = navController
|
||||
)
|
||||
}
|
||||
composable(NavigationItems.CardAdventure.route) {
|
||||
val cardId = it.arguments?.getString("cardId")
|
||||
if (cardId != null) {
|
||||
CardAdventureScreen(
|
||||
navController = navController,
|
||||
cardId = cardId.toLong(),
|
||||
cardScreenController = applicationNavigationHandlers
|
||||
.cardScreenController
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,8 @@ class AdventureScreenControllerImpl(
|
||||
itemName = randomItem.name,
|
||||
itemIcon = randomItem.itemIcon,
|
||||
itemLength = randomItem.itemLength,
|
||||
itemDescription = randomItem.description
|
||||
itemDescription = randomItem.description,
|
||||
itemType = randomItem.itemType
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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: -")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ fun BetaWarning(
|
||||
)
|
||||
Spacer(modifier = Modifier.padding(8.dp))
|
||||
Text(
|
||||
text = "Also, this application does not work yet with the original VB."
|
||||
text = "Application should work now with the original VB and the VH."
|
||||
)
|
||||
Spacer(modifier = Modifier.padding(8.dp))
|
||||
Text(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
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
|
||||
@@ -27,9 +28,15 @@ 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
|
||||
@@ -45,15 +52,21 @@ 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,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,
|
||||
@@ -89,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!!,
|
||||
@@ -108,12 +123,26 @@ 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 },
|
||||
|
||||
@@ -1,5 +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)
|
||||
}
|
||||
@@ -2,9 +2,13 @@ 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,
|
||||
@@ -26,4 +30,43 @@ class HomeScreenControllerImpl(
|
||||
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")
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
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 suspend fun getItem(itemId: Long): ItemDtos.ItemsWithQuantities {
|
||||
return database
|
||||
.itemDao()
|
||||
.getItem(itemId)
|
||||
}
|
||||
|
||||
private fun consumeItem(itemId: Long) {
|
||||
private suspend fun consumeItem(itemId: Long) {
|
||||
database
|
||||
.itemDao()
|
||||
.useItem(itemId)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
@@ -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?
|
||||
}
|
||||
@@ -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,101 +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,
|
||||
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!"
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ 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(
|
||||
@@ -19,6 +20,9 @@ fun CreditsScreen(
|
||||
text = "Credits",
|
||||
onBackClick = {
|
||||
navController.popBackStack()
|
||||
},
|
||||
onGearClick = {
|
||||
navController.navigate(NavigationItems.Viewer.route)
|
||||
}
|
||||
)
|
||||
},
|
||||
@@ -35,6 +39,7 @@ fun CreditsScreen(
|
||||
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.") { }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,13 +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
|
||||
@@ -107,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 -> 54
|
||||
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 = NfcCharacter.Attribute.entries[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()
|
||||
|
||||
@@ -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",
|
||||
@@ -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>
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,10 @@ package com.github.nacabaro.vbhelper.source
|
||||
|
||||
import com.github.nacabaro.vbhelper.database.AppDatabase
|
||||
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
|
||||
|
||||
class StorageRepository (
|
||||
private val db: AppDatabase
|
||||
@@ -19,12 +22,20 @@ class StorageRepository (
|
||||
return db.userCharacterDao().getBeData(id)
|
||||
}
|
||||
|
||||
fun getTransformationHistory(characterId: Long): List<CharacterDtos.TransformationHistory>? {
|
||||
suspend fun getTransformationHistory(characterId: Long): List<CharacterDtos.TransformationHistory>? {
|
||||
return db.userCharacterDao().getTransformationHistory(characterId)
|
||||
}
|
||||
|
||||
suspend fun getCharacterData(id: Long): CharacterDtos.DiMInfo {
|
||||
return db.characterDao().getCharacterInfo(id)
|
||||
suspend fun getCharacterVbData(id: Long): VBCharacterData {
|
||||
return db.userCharacterDao().getVbData(id)
|
||||
}
|
||||
|
||||
suspend fun getSpecialMissions(id: Long): List<SpecialMissions> {
|
||||
return db.userCharacterDao().getSpecialMissions(id)
|
||||
}
|
||||
|
||||
suspend fun getItem(id: Long): ItemDtos.ItemsWithQuantities {
|
||||
return db.itemDao().getItem(id)
|
||||
}
|
||||
|
||||
suspend fun getActiveCharacter(): CharacterDtos.CharacterWithSprites? {
|
||||
@@ -38,4 +49,12 @@ class StorageRepository (
|
||||
suspend fun getAdventureCharacters(): List<CharacterDtos.AdventureCharacterWithSprites> {
|
||||
return db.adventureDao().getAdventureCharacters()
|
||||
}
|
||||
|
||||
suspend fun getBECharacters(): List<CharacterDtos.CharacterWithSprites> {
|
||||
return db.userCharacterDao().getBECharacters()
|
||||
}
|
||||
|
||||
suspend fun getVBCharacters(): List<CharacterDtos.CharacterWithSprites> {
|
||||
return db.userCharacterDao().getVBDimCharacters()
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
package com.github.nacabaro.vbhelper.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import androidx.compose.ui.graphics.ImageBitmap
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.cfogrady.vb.dim.sprite.SpriteData
|
||||
|
||||
// simple, but smooth
|
||||
@@ -10,6 +15,32 @@ data class BitmapData (
|
||||
val height: Int
|
||||
)
|
||||
|
||||
data class ImageBitmapData(
|
||||
val imageBitmap: ImageBitmap,
|
||||
val dpWidth: Dp,
|
||||
val dpHeight: Dp
|
||||
)
|
||||
|
||||
fun BitmapData.getImageBitmap(
|
||||
context: Context,
|
||||
multiplier: Int,
|
||||
obscure: Boolean
|
||||
): ImageBitmapData {
|
||||
val density: Float = context.resources.displayMetrics.density
|
||||
|
||||
val imageBitmap: ImageBitmap = if (obscure) {
|
||||
this.getObscuredBitmap().asImageBitmap()
|
||||
} else {
|
||||
this.getBitmap().asImageBitmap()
|
||||
}
|
||||
|
||||
return ImageBitmapData(
|
||||
imageBitmap = imageBitmap,
|
||||
dpWidth = (this.width * multiplier / density).dp,
|
||||
dpHeight = (this.height * multiplier / density).dp
|
||||
)
|
||||
}
|
||||
|
||||
fun BitmapData.getBitmap(): Bitmap {
|
||||
return Bitmap.createBitmap(createARGBIntArray(), this.width, this.height, Bitmap.Config.HARDWARE)
|
||||
}
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
package com.github.nacabaro.vbhelper.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.icu.util.Calendar
|
||||
import android.icu.util.GregorianCalendar
|
||||
import com.github.cfogrady.vbnfc.be.BENfcCharacter
|
||||
import com.github.cfogrady.vbnfc.be.FirmwareVersion
|
||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import com.github.nacabaro.vbhelper.source.StorageRepository
|
||||
import java.util.Date
|
||||
|
||||
suspend fun characterToNfc(context: Context, characterId: Long): NfcCharacter? {
|
||||
val app = context.applicationContext as VBHelper
|
||||
val database = app.container.db
|
||||
val storageRepository = StorageRepository(database)
|
||||
val userCharacter = storageRepository.getSingleCharacter(characterId)
|
||||
val characterInfo = storageRepository.getCharacterData(characterId)
|
||||
|
||||
if (userCharacter.characterType == DeviceType.BEDevice) {
|
||||
val beData = storageRepository.getCharacterBeData(characterId)
|
||||
val transformationHistory = storageRepository
|
||||
.getTransformationHistory(characterId)!!
|
||||
.map {
|
||||
val date = Date(it.transformationDate)
|
||||
val calendar = GregorianCalendar()
|
||||
calendar.time = date
|
||||
|
||||
NfcCharacter.Transformation(
|
||||
toCharIndex = it.monIndex.toUByte(),
|
||||
year = calendar
|
||||
.get(Calendar.YEAR)
|
||||
.toUShort(),
|
||||
month = calendar
|
||||
.get(Calendar.MONTH)
|
||||
.toUByte(),
|
||||
day = calendar
|
||||
.get(Calendar.DAY_OF_MONTH)
|
||||
.toUByte()
|
||||
)
|
||||
}.toTypedArray()
|
||||
|
||||
val paddedTransformationArray = padTransformationArray(transformationHistory)
|
||||
|
||||
val nfcData = BENfcCharacter(
|
||||
dimId = characterInfo.cardId.toUShort(),
|
||||
charIndex = characterInfo.charId.toUShort(),
|
||||
stage = userCharacter.stage.toByte(),
|
||||
attribute = userCharacter.attribute,
|
||||
ageInDays = userCharacter.ageInDays.toByte(),
|
||||
nextAdventureMissionStage = userCharacter.nextAdventureMissionStage.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 = Array(7) {
|
||||
NfcCharacter.DailyVitals(0u, 0u, 0u, 0u)
|
||||
},
|
||||
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
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package com.github.nacabaro.vbhelper.utils
|
||||
|
||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
|
||||
fun padTransformationArray(
|
||||
transformationArray: Array<NfcCharacter.Transformation>
|
||||
): Array<NfcCharacter.Transformation> {
|
||||
if (transformationArray.size >= 8) {
|
||||
return transformationArray
|
||||
}
|
||||
|
||||
val paddedArray = Array(8) {
|
||||
NfcCharacter.Transformation(
|
||||
toCharIndex = 255u,
|
||||
year = 65535u,
|
||||
month = 255u,
|
||||
day = 255u
|
||||
)
|
||||
}
|
||||
|
||||
System.arraycopy(transformationArray, 0, paddedArray, 0, transformationArray.size)
|
||||
return paddedArray
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:pathData="M200,760h57l391,-391 -57,-57 -391,391v57ZM120,840v-170l528,-527q12,-11 26.5,-17t30.5,-6q16,0 31,6t26,18l55,56q12,11 17.5,26t5.5,30q0,16 -5.5,30.5T817,313L290,840L120,840ZM760,256 L704,200 760,256ZM619,341 L591,312 648,369 619,341Z"
|
||||
android:fillColor="#000000"/>
|
||||
</vector>
|
||||
@@ -1,30 +1,39 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
||||
android:viewportWidth="512"
|
||||
android:viewportHeight="512">
|
||||
<group android:scaleX="0.79"
|
||||
android:scaleY="0.79"
|
||||
android:translateX="53.76"
|
||||
android:translateY="53.76">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M0,0h512v512h-512z"/>
|
||||
<path
|
||||
android:pathData="M0,0h512v512h-512z"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M164,107L186.19,107L186.19,129C186.19,132.86 189.32,136 193.19,136L219,136L235.95,163.3C236.53,164.24 237.9,165 239,165L267,165C268.1,165 269.47,164.24 270.05,163.3L287,136L312.8,136C316.66,136 319.8,132.86 319.8,129L319.8,107L313.1,107L313.1,128C313.1,129.1 312.2,130 311.1,130L283,130L267.04,156.29C266.46,157.23 265.1,158 264,158L242,158C240.9,158 239.54,157.23 238.96,156.29L223,130L194.94,130C193.83,130 192.94,129.1 192.94,128L192.94,107L217.75,107L229,92L277,92L288,107L342,107L342,405L319.81,405L319.81,383C319.81,379.14 316.68,376 312.81,376L287,376L270.05,348.7C269.47,347.76 268.1,347 267,347L239,347C237.9,347 236.53,347.76 235.95,348.7L219,376L193.2,376C189.34,376 186.2,379.14 186.2,383L186.2,405L192.94,405L192.94,384C192.94,382.9 193.83,382 194.94,382L223,382L238.96,355.71C239.54,354.77 240.9,354 242,354L264,354C265.1,354 266.46,354.77 267.04,355.71L283,382L311.06,382C312.17,382 313.06,382.9 313.06,384L313.06,405L288.25,405L277,420L229,420L218,405L164,405L164,107Z"
|
||||
android:fillColor="#EBEBEB"/>
|
||||
<path
|
||||
android:pathData="M212.61,181.5L299.39,181.5C306.15,181.5 311.63,186.98 311.63,193.74L311.63,318.26C311.63,325.02 306.15,330.5 299.39,330.5L212.61,330.5C205.85,330.5 200.37,325.02 200.37,318.26L200.37,193.74C200.37,186.98 205.85,181.5 212.61,181.5Z"
|
||||
android:fillColor="#000000"
|
||||
android:strokeColor="#00000000"/>
|
||||
<path
|
||||
android:pathData="M0,249L192.88,249L214,208L232.38,249L253.69,171L274.85,255L296,194L310.27,249L512,249L512,269L296,269L294,261L274.85,331L262.59,283.5L253.69,249L232.38,316L213.38,255L205.75,269L0,269L0,249Z"
|
||||
android:fillColor="#EBEBEB"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M-1024,-1024h2048v2048h-2048zM0,249L192.88,249L214,208L232.38,249L253.69,171L274.85,255L296,194L310.27,249L512,249L512,269L296,269L294,261L274.85,331L262.59,283.5L253.69,249L232.38,316L213.38,255L205.75,269L0,269L0,249Z"/>
|
||||
<path
|
||||
android:pathData="M0,249L192.88,249L214,208L232.38,249L253.69,171L274.85,255L296,194L310.27,249L512,249L512,269L296,269L294,261L274.85,331L262.59,283.5L253.69,249L232.38,316L213.38,255L205.75,269L0,269L0,249Z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="10"
|
||||
android:fillColor="#EBEBEB"
|
||||
android:strokeColor="#000000"
|
||||
android:strokeLineCap="square"/>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
</vector>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 938 B |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 982 B After Width: | Height: | Size: 658 B |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 5.4 KiB |