Working items

- Click on use item > then choose the mon you want to apply the item to
This commit is contained in:
Nacho 2025-01-20 14:45:28 +01:00
parent 3e41f82273
commit b4a73031e7
10 changed files with 238 additions and 62 deletions

View File

@ -24,6 +24,7 @@ import com.github.nacabaro.vbhelper.domain.characters.Character
import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
import com.github.nacabaro.vbhelper.navigation.AppNavigationHandlers import com.github.nacabaro.vbhelper.navigation.AppNavigationHandlers
import com.github.nacabaro.vbhelper.screens.itemsScreen.ItemsScreenControllerImpl
import com.github.nacabaro.vbhelper.screens.scanScreen.ScanScreenControllerImpl import com.github.nacabaro.vbhelper.screens.scanScreen.ScanScreenControllerImpl
import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreenControllerImpl import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreenControllerImpl
import com.github.nacabaro.vbhelper.ui.theme.VBHelperTheme import com.github.nacabaro.vbhelper.ui.theme.VBHelperTheme
@ -63,12 +64,17 @@ class MainActivity : ComponentActivity() {
this::unregisterActivityLifecycleListener this::unregisterActivityLifecycleListener
) )
val settingsScreenController = SettingsScreenControllerImpl(this) val settingsScreenController = SettingsScreenControllerImpl(this)
val itemsScreenController = ItemsScreenControllerImpl(this)
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
setContent { setContent {
VBHelperTheme { VBHelperTheme {
MainApplication(scanScreenController, settingsScreenController) MainApplication(
scanScreenController = scanScreenController,
settingsScreenController = settingsScreenController,
itemsScreenController = itemsScreenController
)
} }
} }
Log.i("MainActivity", "Activity onCreated") Log.i("MainActivity", "Activity onCreated")
@ -189,13 +195,15 @@ class MainActivity : ComponentActivity() {
@Composable @Composable
private fun MainApplication( private fun MainApplication(
scanScreenController: ScanScreenControllerImpl, scanScreenController: ScanScreenControllerImpl,
settingsScreenController: SettingsScreenControllerImpl settingsScreenController: SettingsScreenControllerImpl,
itemsScreenController: ItemsScreenControllerImpl
) { ) {
AppNavigation( AppNavigation(
applicationNavigationHandlers = AppNavigationHandlers( applicationNavigationHandlers = AppNavigationHandlers(
settingsScreenController, settingsScreenController,
scanScreenController, scanScreenController,
itemsScreenController
), ),
onClickImportCard = { onClickImportCard = {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply { val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {

View File

@ -166,6 +166,7 @@ fun getIconResource(index: Int): Int {
5 -> R.drawable.baseline_arrow_up_24 5 -> R.drawable.baseline_arrow_up_24
6 -> R.drawable.baseline_timer_24 6 -> R.drawable.baseline_timer_24
7 -> R.drawable.baseline_rank_24 7 -> R.drawable.baseline_rank_24
8 -> R.drawable.baseline_vitals_24
else -> R.drawable.baseline_question_mark_24 else -> R.drawable.baseline_question_mark_24
} }
} }

View File

@ -21,6 +21,14 @@ interface ItemDao {
""") """)
suspend fun getAllUserItems(): List<ItemDtos.ItemsWithQuantities> suspend fun getAllUserItems(): List<ItemDtos.ItemsWithQuantities>
@Query("""
SELECT Items.*, UserItems.quantity
FROM Items
JOIN UserItems ON Items.id = UserItems.itemId
WHERE UserItems.itemId = :itemId
""")
fun getUserItem(itemId: Long): ItemDtos.ItemsWithQuantities
@Query(""" @Query("""
UPDATE UserItems UPDATE UserItems
SET quantity = quantity - 1 SET quantity = quantity - 1

View File

@ -17,11 +17,14 @@ import com.github.nacabaro.vbhelper.screens.scanScreen.ScanScreenControllerImpl
import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreen import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreen
import com.github.nacabaro.vbhelper.screens.SpriteViewer import com.github.nacabaro.vbhelper.screens.SpriteViewer
import com.github.nacabaro.vbhelper.screens.StorageScreen import com.github.nacabaro.vbhelper.screens.StorageScreen
import com.github.nacabaro.vbhelper.screens.itemsScreen.ChooseCharacterScreen
import com.github.nacabaro.vbhelper.screens.itemsScreen.ItemsScreenControllerImpl
import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreenControllerImpl import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreenControllerImpl
data class AppNavigationHandlers( data class AppNavigationHandlers(
val settingsScreenController: SettingsScreenControllerImpl, val settingsScreenController: SettingsScreenControllerImpl,
val scanScreenController: ScanScreenControllerImpl, val scanScreenController: ScanScreenControllerImpl,
val itemsScreenController: ItemsScreenControllerImpl
) )
@Composable @Composable
@ -96,6 +99,17 @@ fun AppNavigation(
navController = navController navController = navController
) )
} }
composable(NavigationItems.ApplyItem.route) {
val itemId = it.arguments?.getString("itemId")
if (itemId != null) {
ChooseCharacterScreen(
itemsScreenController = applicationNavigationHandlers
.itemsScreenController,
navController = navController,
itemId = itemId.toLong()
)
}
}
} }
} }
} }

View File

@ -18,4 +18,5 @@ sealed class NavigationItems (
object Items : NavigationItems("Items", R.drawable.baseline_data_24, "Items") object Items : NavigationItems("Items", R.drawable.baseline_data_24, "Items")
object MyItems : NavigationItems("MyItems", R.drawable.baseline_data_24, "My items") object MyItems : NavigationItems("MyItems", R.drawable.baseline_data_24, "My items")
object ItemsStore : NavigationItems("ItemsStore", R.drawable.baseline_data_24, "Items store") object ItemsStore : NavigationItems("ItemsStore", R.drawable.baseline_data_24, "Items store")
object ApplyItem : NavigationItems("ApplyItem/{itemId}", R.drawable.baseline_data_24, "Apply item")
} }

View File

@ -1,6 +1,5 @@
package com.github.nacabaro.vbhelper.screens package com.github.nacabaro.vbhelper.screens
import android.util.Log
import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.scrollable import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@ -8,7 +7,6 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.lazy.grid.items

View File

@ -0,0 +1,90 @@
package com.github.nacabaro.vbhelper.screens.itemsScreen
import android.widget.Toast
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.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.navigation.NavController
import com.github.nacabaro.vbhelper.components.CharacterEntry
import com.github.nacabaro.vbhelper.components.TopBanner
import com.github.nacabaro.vbhelper.di.VBHelper
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
import com.github.nacabaro.vbhelper.source.StorageRepository
import com.github.nacabaro.vbhelper.utils.BitmapData
import kotlinx.coroutines.launch
@Composable
fun ChooseCharacterScreen(
navController: NavController,
itemsScreenController: ItemsScreenControllerImpl,
itemId: Long
) {
val coroutineScope = rememberCoroutineScope()
val application = LocalContext.current.applicationContext as VBHelper
val storageRepository = StorageRepository(application.container.db)
val characterList = remember {
mutableStateOf<List<CharacterDtos.CharacterWithSprites>>(emptyList())
}
var selectedCharacter by remember { mutableStateOf<Long?>(null) }
LaunchedEffect(storageRepository) {
coroutineScope.launch {
characterList.value = storageRepository.getAllCharacters()
}
}
LaunchedEffect (selectedCharacter) {
if (selectedCharacter != null) {
itemsScreenController.applyItem(itemId, selectedCharacter!!) {
Toast.makeText(
application.applicationContext,
"Item applied!",
Toast.LENGTH_SHORT
).show()
navController.popBackStack()
}
}
}
Scaffold(
topBar = {
TopBanner(
text = "Choose character",
onBackClick = {
navController.popBackStack()
}
)
}
) { contentPadding ->
LazyVerticalGrid(
columns = GridCells.Fixed(3),
modifier = Modifier
.padding(top = contentPadding.calculateTopPadding())
) {
items(characterList.value) {
CharacterEntry(
icon = BitmapData(
bitmap = it.spriteIdle,
width = it.spriteWidth,
height = it.spriteHeight
)
) {
selectedCharacter = it.id
}
}
}
}
}

View File

@ -1,7 +1,6 @@
package com.github.nacabaro.vbhelper.screens.itemsScreen package com.github.nacabaro.vbhelper.screens.itemsScreen
import com.github.nacabaro.vbhelper.domain.items.Items
interface ItemsScreenController { interface ItemsScreenController {
suspend fun applyItem(item: Items, characterId: Long) fun applyItem(itemId: Long, characterId: Long, onCompletion: () -> Unit)
} }

View File

@ -1,14 +1,22 @@
package com.github.nacabaro.vbhelper.screens.itemsScreen package com.github.nacabaro.vbhelper.screens.itemsScreen
import androidx.activity.ComponentActivity
import androidx.lifecycle.lifecycleScope
import com.github.nacabaro.vbhelper.database.AppDatabase 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.BECharacterData
import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData
import com.github.nacabaro.vbhelper.domain.items.Items import com.github.nacabaro.vbhelper.dtos.ItemDtos
import com.github.nacabaro.vbhelper.utils.DeviceType import com.github.nacabaro.vbhelper.utils.DeviceType
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class ItemsScreenControllerImpl ( class ItemsScreenControllerImpl (
private val database: AppDatabase private val context: ComponentActivity,
): ItemsScreenController { ): ItemsScreenController {
private var database: AppDatabase
private enum class ItemTypes(val id: Int) { private enum class ItemTypes(val id: Int) {
PPTraining(1), PPTraining(1),
HPTraining(2), HPTraining(2),
@ -20,10 +28,19 @@ class ItemsScreenControllerImpl (
Vitals(8) Vitals(8)
} }
override suspend fun applyItem(item: Items, characterId: Long) { init {
var characterData = database.userCharacterDao().getCharacter(characterId) val application = context.applicationContext as VBHelper
var beCharacterData: BECharacterData database = application.container.db
}
override fun applyItem(itemId: Long, characterId: Long, onCompletion: () -> Unit) {
context.lifecycleScope.launch {
withContext(Dispatchers.IO) {
val item = getItem(itemId)
val characterData = database.userCharacterDao().getCharacter(characterId)
val beCharacterData: BECharacterData
var vbCharacterData: VBCharacterData var vbCharacterData: VBCharacterData
if (characterData.characterType == DeviceType.BEDevice) { if (characterData.characterType == DeviceType.BEDevice) {
beCharacterData = database.userCharacterDao().getBeData(characterId) beCharacterData = database.userCharacterDao().getBeData(characterId)
} else { } else {
@ -41,17 +58,23 @@ class ItemsScreenControllerImpl (
.updateBECharacterData(beCharacterData) .updateBECharacterData(beCharacterData)
} else if (item.itemIcon == ItemTypes.EvoTimer.id) { } else if (item.itemIcon == ItemTypes.EvoTimer.id) {
characterData.transformationCountdown = item.itemLength characterData.transformationCountdown += item.itemLength
if (characterData.transformationCountdown < 0) { if (characterData.transformationCountdown < 0) {
characterData.transformationCountdown = 0 characterData.transformationCountdown = 0
} }
// VB does not like it when the transformationCountdown is 0
if (characterData.characterType == DeviceType.VBDevice &&
characterData.transformationCountdown <= 0 ) {
characterData.transformationCountdown = 1
}
database database
.userCharacterDao() .userCharacterDao()
.updateCharacter(characterData) .updateCharacter(characterData)
} else if (item.itemIcon == ItemTypes.LimitTimer.id) { } else if (item.itemIcon == ItemTypes.LimitTimer.id) {
beCharacterData.remainingTrainingTimeInMinutes = item.itemLength beCharacterData.remainingTrainingTimeInMinutes += item.itemLength
if (beCharacterData.remainingTrainingTimeInMinutes > 6000) { if (beCharacterData.remainingTrainingTimeInMinutes > 6000) {
beCharacterData.remainingTrainingTimeInMinutes = 6000 beCharacterData.remainingTrainingTimeInMinutes = 6000
} }
@ -61,7 +84,7 @@ class ItemsScreenControllerImpl (
.updateBECharacterData(beCharacterData) .updateBECharacterData(beCharacterData)
} else if (item.itemIcon == ItemTypes.Vitals.id) { } else if (item.itemIcon == ItemTypes.Vitals.id) {
characterData.vitalPoints = item.itemLength characterData.vitalPoints += item.itemLength
if (characterData.vitalPoints < 0) { if (characterData.vitalPoints < 0) {
characterData.vitalPoints = 0 characterData.vitalPoints = 0
} else if (characterData.vitalPoints > 9999) { } else if (characterData.vitalPoints > 9999) {
@ -74,6 +97,18 @@ class ItemsScreenControllerImpl (
} }
consumeItem(item.id) consumeItem(item.id)
context.runOnUiThread {
onCompletion()
}
}
}
}
private fun getItem(itemId: Long): ItemDtos.ItemsWithQuantities {
return database
.itemDao()
.getUserItem(itemId)
} }
private fun consumeItem(itemId: Long) { private fun consumeItem(itemId: Long) {

View File

@ -1,5 +1,8 @@
package com.github.nacabaro.vbhelper.screens.itemsScreen package com.github.nacabaro.vbhelper.screens.itemsScreen
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
@ -11,6 +14,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -21,6 +25,7 @@ import com.github.nacabaro.vbhelper.components.getIconResource
import com.github.nacabaro.vbhelper.components.getLengthResource import com.github.nacabaro.vbhelper.components.getLengthResource
import com.github.nacabaro.vbhelper.di.VBHelper import com.github.nacabaro.vbhelper.di.VBHelper
import com.github.nacabaro.vbhelper.dtos.ItemDtos import com.github.nacabaro.vbhelper.dtos.ItemDtos
import com.github.nacabaro.vbhelper.navigation.NavigationItems
import com.github.nacabaro.vbhelper.source.ItemsRepository import com.github.nacabaro.vbhelper.source.ItemsRepository
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -42,7 +47,13 @@ fun MyItems(
} }
if (myItems.value.isEmpty()) { if (myItems.value.isEmpty()) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxSize()
) {
Text("No items") Text("No items")
}
} else { } else {
LazyVerticalGrid( LazyVerticalGrid(
columns = GridCells.Fixed(3), columns = GridCells.Fixed(3),
@ -67,7 +78,18 @@ fun MyItems(
itemIcon = getIconResource(myItems.value[selectedElementIndex!!].itemIcon), itemIcon = getIconResource(myItems.value[selectedElementIndex!!].itemIcon),
lengthIcon = getLengthResource(myItems.value[selectedElementIndex!!].itemLength), lengthIcon = getLengthResource(myItems.value[selectedElementIndex!!].itemLength),
amount = myItems.value[selectedElementIndex!!].quantity, amount = myItems.value[selectedElementIndex!!].quantity,
onClickUse = { }, onClickUse = {
showDialog = false
navController
.navigate(
NavigationItems
.ApplyItem.route
.replace(
"{itemId}",
myItems.value[selectedElementIndex!!].id.toString()
)
)
},
onClickCancel = { showDialog = false } onClickCancel = { showDialog = false }
) )
} }