Merge pull request #15 from nacabaro/ui/home_screen

A few things, again...
This commit is contained in:
nacabaro 2025-01-12 10:22:57 +01:00 committed by GitHub
commit dd893a08da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 343 additions and 73 deletions

View File

@ -5,6 +5,7 @@ import androidx.room.Insert
import androidx.room.Query
import com.github.nacabaro.vbhelper.domain.Character
import com.github.nacabaro.vbhelper.domain.Sprites
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
@Dao
interface CharacterDao {
@ -25,4 +26,15 @@ interface CharacterDao {
@Query("SELECT * FROM Sprites")
suspend fun getAllSprites(): List<Sprites>
@Query("""
SELECT
d.dimId as cardId,
c.monIndex as charId
FROM Character c
JOIN UserCharacter uc ON c.id = uc.charId
JOIN Dim d ON c.dimId = d.id
WHERE uc.id = :charId
""")
suspend fun getCharacterInfo(charId: Long): CharacterDtos.DiMInfo
}

View File

@ -21,7 +21,7 @@ interface UserCharacterDao {
fun insertTransformationHistory(vararg transformationHistory: TransformationHistory)
@Query("SELECT * FROM TransformationHistory WHERE monId = :monId")
fun getTransformationHistory(monId: Int): List<TransformationHistory>
fun getTransformationHistory(monId: Long): List<TransformationHistory>
@Query("""
SELECT
@ -36,4 +36,7 @@ interface UserCharacterDao {
@Query("SELECT * FROM UserCharacter WHERE id = :id")
suspend fun getCharacter(id: Long): UserCharacter
@Query("SELECT * FROM BECharacterData WHERE id = :id")
suspend fun getBeData(id: Long): BECharacterData
}

View File

@ -1,6 +1,5 @@
package com.github.nacabaro.vbhelper.dtos
import androidx.room.PrimaryKey
import com.github.cfogrady.vbnfc.data.NfcCharacter
import com.github.nacabaro.vbhelper.domain.DeviceType
@ -29,4 +28,9 @@ object CharacterDtos {
val spriteWidth: Int,
val spriteHeight: Int
)
data class DiMInfo(
val cardId: Int,
val charId: Int
)
}

View File

@ -35,45 +35,51 @@ fun AppNavigation(
) { contentPadding ->
NavHost(
navController = navController,
startDestination = BottomNavItem.Home.route,
startDestination = NavigationItems.Home.route,
modifier = Modifier
.padding(contentPadding)
) {
composable(BottomNavItem.Battles.route) {
composable(NavigationItems.Battles.route) {
BattlesScreen()
}
composable(BottomNavItem.Home.route) {
composable(NavigationItems.Home.route) {
HomeScreen(
navController = navController
)
}
composable(BottomNavItem.Storage.route) {
StorageScreen()
composable(NavigationItems.Storage.route) {
StorageScreen(
navController = navController
)
}
composable(BottomNavItem.Scan.route) {
composable(NavigationItems.Scan.route) {
val characterIdString = it.arguments?.getString("characterId")
val characterId = characterIdString?.toLongOrNull()
ScanScreen(
navController = navController,
scanScreenController = applicationNavigationHandlers.scanScreenController,
characterId = characterId
)
}
composable(BottomNavItem.Dex.route) {
composable(NavigationItems.Dex.route) {
DexScreen(
navController = navController
)
}
composable(BottomNavItem.Settings.route) {
composable(NavigationItems.Settings.route) {
SettingsScreen(
navController = navController,
settingsScreenController = applicationNavigationHandlers.settingsScreenController,
onClickImportCard = onClickImportCard
)
}
composable(BottomNavItem.Viewer.route) {
composable(NavigationItems.Viewer.route) {
SpriteViewer(
navController = navController
)
}
composable(BottomNavItem.CardView.route) {
composable(NavigationItems.CardView.route) {
val dimId = it.arguments?.getString("dimId")
Log.d("dimId", dimId.toString())
if (dimId != null) {

View File

@ -1,18 +0,0 @@
package com.github.nacabaro.vbhelper.navigation
import com.github.nacabaro.vbhelper.R
sealed class BottomNavItem (
var route: String,
var icon: Int,
var label: String
) {
object Scan : BottomNavItem("Scan", R.drawable.baseline_nfc_24, "Scan")
object Battles : BottomNavItem("Battle", R.drawable.baseline_swords_24, "Battle")
object Home : BottomNavItem("Home", R.drawable.baseline_cottage_24, "Home")
object Dex : BottomNavItem("Dex", R.drawable.baseline_menu_book_24, "Dex")
object Storage : BottomNavItem("Storage", R.drawable.baseline_catching_pokemon_24, "Storage")
object Settings : BottomNavItem("Settings", R.drawable.baseline_settings_24, "Settings")
object Viewer : BottomNavItem("Viewer", R.drawable.baseline_image_24, "Viewer")
object CardView : BottomNavItem("Card/{dimId}", R.drawable.baseline_image_24, "Card")
}

View File

@ -13,11 +13,11 @@ import androidx.navigation.compose.currentBackStackEntryAsState
@Composable
fun BottomNavigationBar(navController: NavController) {
val items = listOf(
BottomNavItem.Scan,
BottomNavItem.Battles,
BottomNavItem.Home,
BottomNavItem.Dex,
BottomNavItem.Storage,
NavigationItems.Scan,
NavigationItems.Battles,
NavigationItems.Home,
NavigationItems.Dex,
NavigationItems.Storage,
)
NavigationBar {
val currentBackStackEntry = navController.currentBackStackEntryAsState()

View File

@ -0,0 +1,18 @@
package com.github.nacabaro.vbhelper.navigation
import com.github.nacabaro.vbhelper.R
sealed class NavigationItems (
var route: String,
var icon: Int,
var label: String
) {
object Scan : NavigationItems("Scan/{characterId}", R.drawable.baseline_nfc_24, "Scan")
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 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")
object CardView : NavigationItems("Card/{dimId}", R.drawable.baseline_image_24, "Card")
}

View File

@ -19,7 +19,7 @@ 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.Dim
import com.github.nacabaro.vbhelper.navigation.BottomNavItem
import com.github.nacabaro.vbhelper.navigation.NavigationItems
import com.github.nacabaro.vbhelper.source.DexRepository
import kotlinx.coroutines.launch
@ -45,7 +45,7 @@ fun DexScreen(
TopBanner(
text = "Discovered Digimon",
onGearClick = {
navController.navigate(BottomNavItem.Viewer.route)
navController.navigate(NavigationItems.Viewer.route)
}
)
}
@ -65,7 +65,7 @@ fun DexScreen(
onClick = {
navController
.navigate(
BottomNavItem
NavigationItems
.CardView.route
.replace("{dimId}", "${it.id}")
)

View File

@ -8,7 +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.BottomNavItem
import com.github.nacabaro.vbhelper.navigation.NavigationItems
@Composable
fun HomeScreen(
@ -19,7 +19,7 @@ fun HomeScreen(
TopBanner(
text = "VB Helper",
onGearClick = {
navController.navigate(BottomNavItem.Settings.route)
navController.navigate(NavigationItems.Settings.route)
}
)
}

View File

@ -1,11 +1,11 @@
package com.github.nacabaro.vbhelper.screens
import android.util.Log
import androidx.compose.foundation.Image
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
@ -21,11 +21,9 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -34,18 +32,22 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.navigation.NavController
import com.github.nacabaro.vbhelper.components.CharacterEntry
import com.github.nacabaro.vbhelper.components.TopBanner
import com.github.nacabaro.vbhelper.di.VBHelper
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
import com.github.nacabaro.vbhelper.navigation.NavigationItems
import com.github.nacabaro.vbhelper.source.StorageRepository
import com.github.nacabaro.vbhelper.utils.BitmapData
import kotlinx.coroutines.launch
@Composable
fun StorageScreen() {
fun StorageScreen(
navController: NavController
) {
val coroutineScope = rememberCoroutineScope()
val application = LocalContext.current.applicationContext as VBHelper
val storageRepository = StorageRepository(application.container.db)
@ -96,14 +98,24 @@ fun StorageScreen() {
),
modifier = Modifier
.padding(8.dp)
.size(96.dp)
.size(96.dp),
onClick = {
selectedCharacter = index.id
}
)
if (selectedCharacter != null) {
StorageDialog(
characterId = selectedCharacter!!,
onDismissRequest = { selectedCharacter = null }
onDismissRequest = { selectedCharacter = null },
onSendToBracelet = {
navController.navigate(
NavigationItems.Scan.route.replace(
"{characterId}",
selectedCharacter.toString()
)
)
}
)
}
}
@ -114,7 +126,8 @@ fun StorageScreen() {
@Composable
fun StorageDialog(
characterId: Long,
onDismissRequest: () -> Unit
onDismissRequest: () -> Unit,
onSendToBracelet: () -> Unit
) {
val coroutineScope = rememberCoroutineScope()
val application = LocalContext.current.applicationContext as VBHelper
@ -149,10 +162,17 @@ fun StorageDialog(
.padding(8.dp)
)
}
Button(
onClick = onDismissRequest
) {
Text(text = "Close")
Row {
Button(
onClick = onSendToBracelet
) {
Text(text = "Send to bracelet")
}
Button(
onClick = onDismissRequest
) {
Text(text = "Close")
}
}
}
}

View File

@ -15,11 +15,12 @@ import com.github.nacabaro.vbhelper.components.TopBanner
@Composable
fun ReadingCharacterScreen(
topBannerText: String,
onClickCancel: () -> Unit,
) {
Scaffold (
topBar = {
TopBanner("Reading Character")
TopBanner(topBannerText)
}
) { innerPadding ->
Column (

View File

@ -12,6 +12,7 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@ -25,25 +26,48 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
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.navigation.BottomNavItem
import com.github.nacabaro.vbhelper.di.VBHelper
import com.github.nacabaro.vbhelper.navigation.NavigationItems
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
const val SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER = "SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER"
@Composable
fun ScanScreen(
navController: NavController,
characterId: Long?,
scanScreenController: ScanScreenController,
) {
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) }
DisposableEffect(readingScreen) {
val application = LocalContext.current.applicationContext as VBHelper
val storageRepository = StorageRepository(application.container.db)
var nfcCharacter by remember { mutableStateOf<NfcCharacter?>(null) }
val context = LocalContext.current
LaunchedEffect(storageRepository) {
withContext(Dispatchers.IO) {
if(characterId != null) {
nfcCharacter = characterToNfc(context, characterId)
}
}
}
DisposableEffect(readingScreen || writingScreen) {
if(readingScreen) {
scanScreenController.registerActivityLifecycleListener(SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER, object: ActivityLifecycleListener {
override fun onPause() {
@ -60,9 +84,39 @@ fun ScanScreen(
scanScreenController.onClickRead(secrets!!) {
isDoneReadingCharacter = true
}
} else if (writingScreen) {
scanScreenController.registerActivityLifecycleListener(
SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER,
object : ActivityLifecycleListener {
override fun onPause() {
scanScreenController.cancelRead()
}
override fun onResume() {
if (!isDoneSendingCard) {
scanScreenController.onClickCheckCard(secrets!!, nfcCharacter!!) {
isDoneSendingCard = true
}
} else if (!isDoneWritingCharacter) {
scanScreenController.onClickWrite(secrets!!, nfcCharacter!!) {
isDoneWritingCharacter = true
}
}
}
}
)
if (!isDoneSendingCard) {
scanScreenController.onClickCheckCard(secrets!!, nfcCharacter!!) {
isDoneSendingCard = true
}
} else if (!isDoneWritingCharacter) {
scanScreenController.onClickWrite(secrets!!, nfcCharacter!!) {
isDoneWritingCharacter = true
}
}
}
onDispose {
if(readingScreen) {
if(readingScreen || writingScreen) {
scanScreenController.unregisterActivityLifecycleListener(SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER)
scanScreenController.cancelRead()
}
@ -71,33 +125,68 @@ fun ScanScreen(
if (isDoneReadingCharacter) {
readingScreen = false
navController.navigate(BottomNavItem.Home.route)
navController.navigate(NavigationItems.Home.route)
} else if (isDoneSendingCard && isDoneWritingCharacter) {
writingScreen = false
navController.navigate(NavigationItems.Home.route)
}
if (readingScreen) {
ReadingCharacterScreen {
ReadingCharacterScreen("Reading character") {
readingScreen = false
scanScreenController.cancelRead()
}
} else if (writingScreen) {
if (!isDoneSendingCard) {
ReadingCharacterScreen("Sending card") {
isDoneSendingCard = true
scanScreenController.cancelRead()
}
} else if (!isDoneWritingCharacter) {
ReadingCharacterScreen("Writing character") {
isDoneWritingCharacter = true
writingScreen = false
scanScreenController.cancelRead()
}
}
} else {
val context = LocalContext.current
ChooseConnectOption(
onClickRead = {
if(secrets == null) {
Toast.makeText(context, "Secrets is not yet initialized. Try again.", Toast.LENGTH_SHORT).show()
} else if(secrets?.isMissingSecrets() == true) {
Toast.makeText(context, "Secrets not yet imported. Go to Settings and Import APK", Toast.LENGTH_SHORT).show()
} else {
readingScreen = true // kicks off nfc adapter in DisposableEffect
onClickRead = when {
characterId != null -> null
else -> {
{
if(secrets == null) {
Toast.makeText(context, "Secrets is not yet initialized. Try again.", Toast.LENGTH_SHORT).show()
} else if(secrets?.isMissingSecrets() == true) {
Toast.makeText(context, "Secrets not yet imported. Go to Settings and Import APK", Toast.LENGTH_SHORT).show()
} else {
readingScreen = true // kicks off nfc adapter in DisposableEffect
}
}
}
},
onClickWrite = when {
nfcCharacter == null -> null
else -> {
{
if(secrets == null) {
Toast.makeText(context, "Secrets is not yet initialized. Try again.", Toast.LENGTH_SHORT).show()
} else if(secrets?.isMissingSecrets() == true) {
Toast.makeText(context, "Secrets not yet imported. Go to Settings and Import APK", Toast.LENGTH_SHORT).show()
} else {
writingScreen = true // kicks off nfc adapter in DisposableEffect
}
}
}
}
)
}
}
@Composable
private fun ChooseConnectOption(
onClickRead: () -> Unit,
fun ChooseConnectOption(
onClickRead: (() -> Unit)? = null,
onClickWrite: (() -> Unit)? = null,
) {
Scaffold(
topBar = { TopBanner(text = "Scan a Vital Bracelet") }
@ -111,12 +200,14 @@ private fun ChooseConnectOption(
) {
ScanButton(
text = "Vital Bracelet to App",
onClick = onClickRead,
disabled = onClickRead == null,
onClick = onClickRead?: { },
)
Spacer(modifier = Modifier.height(16.dp))
ScanButton(
text = "App to Vital Bracelet",
onClick = {}
disabled = onClickWrite == null,
onClick = onClickWrite?: { },
)
}
}
@ -127,11 +218,13 @@ private fun ChooseConnectOption(
fun ScanButton(
text: String,
onClick: () -> Unit,
modifier: Modifier = Modifier
modifier: Modifier = Modifier,
disabled: Boolean = false,
) {
Button(
onClick = onClick,
modifier = modifier
modifier = modifier,
enabled = !disabled,
) {
Text(
text = text,
@ -157,7 +250,10 @@ fun ScanScreenPreview() {
}
override fun onClickRead(secrets: Secrets, onComplete: ()->Unit) {}
override fun onClickCheckCard(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit) {}
override fun onClickWrite(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit) {}
override fun cancelRead() {}
}
},
characterId = null
)
}

View File

@ -1,5 +1,6 @@
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.source.proto.Secrets
import kotlinx.coroutines.flow.Flow
@ -7,6 +8,9 @@ import kotlinx.coroutines.flow.Flow
interface ScanScreenController {
val secretsFlow: Flow<Secrets>
fun onClickRead(secrets: Secrets, onComplete: ()->Unit)
fun onClickCheckCard(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit)
fun onClickWrite(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit)
fun cancelRead()
fun registerActivityLifecycleListener(key: String, activityLifecycleListener: ActivityLifecycleListener)

View File

@ -109,6 +109,30 @@ class ScanScreenControllerImpl(
}
}
override fun onClickWrite(
secrets: Secrets,
nfcCharacter: NfcCharacter,
onComplete: () -> Unit
) {
handleTag(secrets) { tagCommunicator ->
tagCommunicator.sendCharacter(nfcCharacter)
onComplete.invoke()
"Sent character successfully!"
}
}
override fun onClickCheckCard(
secrets: Secrets,
nfcCharacter: NfcCharacter,
onComplete: () -> Unit
) {
handleTag(secrets) { tagCommunicator ->
tagCommunicator.prepareDIMForCharacter(nfcCharacter.dimId)
onComplete.invoke()
"Sent DIM successfully!"
}
}
// EXTRACTED DIRECTLY FROM EXAMPLE APP
private fun showWirelessSettings() {
Toast.makeText(context, "NFC must be enabled", Toast.LENGTH_SHORT).show()

View File

@ -1,6 +1,8 @@
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.TransformationHistory
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
@ -14,4 +16,16 @@ class StorageRepository (
suspend fun getSingleCharacter(id: Long): UserCharacter {
return db.userCharacterDao().getCharacter(id)
}
suspend fun getCharacterBeData(id: Long): BECharacterData {
return db.userCharacterDao().getBeData(id)
}
fun getTransformationHistory(characterId: Long): List<TransformationHistory> {
return db.userCharacterDao().getTransformationHistory(characterId)
}
suspend fun getCharacterData(id: Long): CharacterDtos.DiMInfo {
return db.characterDao().getCharacterInfo(id)
}
}

View File

@ -0,0 +1,86 @@
package com.github.nacabaro.vbhelper.utils
import android.content.Context
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.domain.DeviceType
import com.github.nacabaro.vbhelper.source.StorageRepository
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 {
NfcCharacter.Transformation(
toCharIndex = it.toCharIndex.toUByte(),
year = it.year.toUShort(),
month = it.month.toUByte(),
day = it.day.toUByte()
)
}.toTypedArray()
// Maybe this is the issue?
val dummyVitalHistory = arrayOf<NfcCharacter.DailyVitals>()
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 = transformationHistory,
vitalHistory = arrayOf(),
appReserved1 = byteArrayOf(),
appReserved2 = Array(2, { 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
}