diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 753ad0e..00f6931 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -91,4 +91,11 @@ dependencies {
implementation("com.google.android.material:material:1.2.0")
implementation(libs.protobuf.javalite)
implementation("androidx.compose.material:material")
+
+ implementation("com.squareup.retrofit2:retrofit:2.9.0")
+ implementation("com.squareup.retrofit2:converter-gson:2.9.0")
+ implementation("com.google.code.gson:gson:2.10.1")
+
+ // HTTP request logging
+ implementation("com.squareup.okhttp3:logging-interceptor:4.11.0")
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d3a5163..c28d47b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -4,6 +4,7 @@
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/battle/OpponentsDataModel.kt b/app/src/main/java/com/github/nacabaro/vbhelper/battle/OpponentsDataModel.kt
new file mode 100644
index 0000000..8bff492
--- /dev/null
+++ b/app/src/main/java/com/github/nacabaro/vbhelper/battle/OpponentsDataModel.kt
@@ -0,0 +1,5 @@
+package com.github.nacabaro.vbhelper.battle
+
+data class OpponentsDataModel (
+ val opponentsList: ArrayList
+):java.io.Serializable
\ No newline at end of file
diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/battle/PVPDataModel.kt b/app/src/main/java/com/github/nacabaro/vbhelper/battle/PVPDataModel.kt
new file mode 100644
index 0000000..e0b55f7
--- /dev/null
+++ b/app/src/main/java/com/github/nacabaro/vbhelper/battle/PVPDataModel.kt
@@ -0,0 +1,13 @@
+package com.github.nacabaro.vbhelper.battle
+
+data class PVPDataModel (
+ val status: String,
+ val state: Int,
+ val currentRound: Int,
+ val playerHP: Int,
+ val opponentHP: Int,
+ val playerAttackHit: Boolean,
+ val playerAttackDamage: Int,
+ val opponentAttackDamage: Int,
+ val winner: String
+):java.io.Serializable
\ No newline at end of file
diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/battle/PVPService.kt b/app/src/main/java/com/github/nacabaro/vbhelper/battle/PVPService.kt
new file mode 100644
index 0000000..8bc6ba2
--- /dev/null
+++ b/app/src/main/java/com/github/nacabaro/vbhelper/battle/PVPService.kt
@@ -0,0 +1,13 @@
+package com.github.nacabaro.vbhelper.battle
+
+import retrofit2.Call
+import retrofit2.http.GET
+import retrofit2.http.Query
+
+interface PVPService {
+ @GET("api/pvp")
+ // This method returns a Call object with a generic
+ // type of DataModel, which represents
+ // the data model for the response.
+ fun getwinner(@Query("apiStage") apiStage: Int, @Query("playerID") playerID: Int, @Query("playerDigi") playerDigi: String, @Query("playerStage") playerStage: Int, @Query("critBar") critBar: Int, @Query("opponentDigi") opponentDigi: String, @Query("opponentStage") opponentStage: Int): Call
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/battle/RetrofitHelper.kt b/app/src/main/java/com/github/nacabaro/vbhelper/battle/RetrofitHelper.kt
new file mode 100644
index 0000000..1cfca0e
--- /dev/null
+++ b/app/src/main/java/com/github/nacabaro/vbhelper/battle/RetrofitHelper.kt
@@ -0,0 +1,179 @@
+package com.github.nacabaro.vbhelper.battle
+
+import android.content.Context
+import retrofit2.Retrofit
+import android.widget.Toast
+import retrofit2.*
+import retrofit2.converter.gson.GsonConverterFactory
+
+class RetrofitHelper {
+
+ fun getOpponents(context: Context, stage: String, callback: (OpponentsDataModel) -> Unit) {
+ println("RetrofitHelper: Starting API call for stage: $stage")
+
+ try {
+ // Create a Retrofit instance with the base URL and
+ // a GsonConverterFactory for parsing the response.
+ val retrofit: Retrofit = Retrofit.Builder().baseUrl("http://192.168.0.230:8080/").addConverterFactory(
+ GsonConverterFactory.create()).build()
+ println("RetrofitHelper: Retrofit instance created")
+
+ // Create an ApiService instance from the Retrofit instance.
+ val service: OpponentService = retrofit.create(OpponentService::class.java)
+ println("RetrofitHelper: Service created")
+
+ // Call the getopponents() method of the ApiService
+ // to make an API request.
+ val call: Call = service.getopponents(stage)
+ println("RetrofitHelper: API call created, enqueueing...")
+
+ // Use the enqueue() method of the Call object to
+ // make an asynchronous API request.
+ call.enqueue(object : Callback {
+ override fun onFailure(call: Call, t: Throwable) {
+ println("RetrofitHelper: API call failed: ${t.message}")
+ t.printStackTrace()
+ Toast.makeText(context, "Request Fail", Toast.LENGTH_SHORT).show()
+ }
+
+ override fun onResponse(call: Call, response: Response) {
+ println("RetrofitHelper: API response received - Code: ${response.code()}")
+ println("RetrofitHelper: Response body: ${response.body()}")
+
+ if(response.isSuccessful){
+ println("RetrofitHelper: Response successful, calling callback")
+ val opponentsList: OpponentsDataModel = response.body() as OpponentsDataModel
+ callback(opponentsList)
+ } else {
+ println("RetrofitHelper: Response not successful - Error: ${response.errorBody()?.string()}")
+ }
+ }
+ })
+ } catch (e: Exception) {
+ println("RetrofitHelper: Exception in getOpponents: ${e.message}")
+ e.printStackTrace()
+ }
+ }
+
+ /*
+ fun getCombatWinner(context: Context, stage: String, callback: (CombatDataModel) -> Unit) {
+
+ // Create a Retrofit instance with the base URL and
+ // a GsonConverterFactory for parsing the response.
+ val retrofit: Retrofit = Retrofit.Builder().baseUrl("http://192.168.0.230:8080/").addConverterFactory(
+ GsonConverterFactory.create()).build()
+
+ // Create an ApiService instance from the Retrofit instance.
+ val service: CombatService = retrofit.create(CombatService::class.java)
+
+ // Call the getwinner() method of the ApiService
+ // to make an API request.
+ val call: Call = service.getwinner(stage)
+
+ // Use the enqueue() method of the Call object to
+ // make an asynchronous API request.
+ call.enqueue(object : Callback {
+ // This is an anonymous inner class that implements the Callback interface.
+
+ override fun onFailure(call: Call, t: Throwable) {
+ // This method is called when the API request fails.
+ Toast.makeText(context, "Request Fail", Toast.LENGTH_SHORT).show()
+ }
+
+ override fun onResponse(call: Call, response: Response) {
+ // This method is called when the API response is received successfully.
+
+ if(response.isSuccessful){
+ // If the response is successful, parse the
+ // response body to a DataModel object.
+ val winner: CombatDataModel = response.body() as CombatDataModel
+
+ // Call the callback function with the DataModel
+ // object as a parameter.
+ callback(winner)
+ }
+ }
+ })
+ }
+
+ fun getBattleWinner(context: Context, playerDigi: String, playerStage: Int, opponentDigi: String, opponentStage: Int, callback: (BattleDataModel) -> Unit) {
+
+ // Create a Retrofit instance with the base URL and
+ // a GsonConverterFactory for parsing the response.
+ val retrofit: Retrofit = Retrofit.Builder().baseUrl("http://192.168.0.230:8080/").addConverterFactory(
+ GsonConverterFactory.create()).build()
+
+ // Create an ApiService instance from the Retrofit instance.
+ val service: BattleService = retrofit.create(BattleService::class.java)
+
+ // Call the getwinner() method of the ApiService
+ // to make an API request.
+ val call: Call = service.getwinner(playerDigi, playerStage, opponentDigi, opponentStage)
+
+ // Use the enqueue() method of the Call object to
+ // make an asynchronous API request.
+ call.enqueue(object : Callback {
+ // This is an anonymous inner class that implements the Callback interface.
+
+ override fun onFailure(call: Call, t: Throwable) {
+ // This method is called when the API request fails.
+ Toast.makeText(context, "Request Fail", Toast.LENGTH_SHORT).show()
+ }
+
+ override fun onResponse(call: Call, response: Response) {
+ // This method is called when the API response is received successfully.
+
+ if(response.isSuccessful){
+ // If the response is successful, parse the
+ // response body to a DataModel object.
+ val winner: BattleDataModel = response.body() as BattleDataModel
+
+ // Call the callback function with the DataModel
+ // object as a parameter.
+ callback(winner)
+ }
+ }
+ })
+ }
+ */
+
+ fun getPVPWinner(context: Context, apiStage: Int, playerID: Int, playerDigi: String, playerStage: Int, critBar: Int, opponentDigi: String, opponentStage: Int, callback: (PVPDataModel) -> Unit) {
+
+ // Create a Retrofit instance with the base URL and
+ // a GsonConverterFactory for parsing the response.
+ val retrofit: Retrofit = Retrofit.Builder().baseUrl("http://192.168.0.230:8080/").addConverterFactory(
+ GsonConverterFactory.create()).build()
+
+ // Create an ApiService instance from the Retrofit instance.
+ val service: PVPService = retrofit.create(PVPService::class.java)
+
+ // Call the getwinner() method of the ApiService
+ // to make an API request.
+ val call: Call = service.getwinner(apiStage, playerID, playerDigi, playerStage, critBar, opponentDigi, opponentStage)
+
+ // Use the enqueue() method of the Call object to
+ // make an asynchronous API request.
+ call.enqueue(object : Callback {
+ // This is an anonymous inner class that implements the Callback interface.
+
+ override fun onFailure(call: Call, t: Throwable) {
+ // This method is called when the API request fails.
+ Toast.makeText(context, "Request Fail", Toast.LENGTH_SHORT).show()
+ }
+
+ override fun onResponse(call: Call, response: Response) {
+ // This method is called when the API response is received successfully.
+
+ if(response.isSuccessful){
+ // If the response is successful, parse the
+ // response body to a DataModel object.
+ val apiResults: PVPDataModel = response.body() as PVPDataModel
+
+ // Call the callback function with the DataModel
+ // object as a parameter.
+ callback(apiResults)
+ }
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/BattlesScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/BattlesScreen.kt
index b50ef12..7a334be 100644
--- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/BattlesScreen.kt
+++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/BattlesScreen.kt
@@ -9,10 +9,269 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.material3.Button
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.unit.dp
+import androidx.compose.material3.ExposedDropdownMenuBox
+import androidx.compose.material3.ExposedDropdownMenuDefaults
+import androidx.compose.material3.OutlinedTextField
+import androidx.compose.material3.DropdownMenuItem
+import androidx.compose.foundation.layout.Box
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.material3.ExperimentalMaterial3Api
+import com.github.nacabaro.vbhelper.battle.APIBattleCharacter
import com.github.nacabaro.vbhelper.components.TopBanner
+import com.github.nacabaro.vbhelper.battle.RetrofitHelper
+@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun BattlesScreen() {
+ var currentView by remember { mutableStateOf("main") }
+
+ var opponentsList by remember { mutableStateOf(ArrayList()) }
+
+ var activeCharacter by remember { mutableStateOf(null) }
+
+ var expanded by remember { mutableStateOf(false) }
+ var selectedStage by remember { mutableStateOf("") }
+
+ val context = LocalContext.current
+
+ val rookieButton = @Composable {
+ Button(
+ onClick = {
+ println("Rookie button clicked - starting API call")
+ try {
+ RetrofitHelper().getOpponents(context, "rookie") { opponents ->
+ println("API call completed successfully")
+ try {
+ println("Received opponents data: $opponents")
+ println("Opponents list size: ${opponents.opponentsList.size}")
+
+ // For loop to check opponents and print their names
+ for (opponent in opponents.opponentsList) {
+ println("Opponent: ${opponent.name}")
+ }
+
+ // Store the opponents in your ArrayList
+ opponentsList.clear()
+ opponentsList.addAll(opponents.opponentsList)
+
+ println("Updated opponentsList size: ${opponentsList.size}")
+ println("About to change view to rookie")
+ currentView = "rookie"
+ println("View changed to rookie")
+ } catch (e: Exception) {
+ println("Error processing opponents data: ${e.message}")
+ e.printStackTrace()
+ }
+ }
+ } catch (e: Exception) {
+ println("Error calling getOpponents: ${e.message}")
+ e.printStackTrace()
+ }
+ }
+ ) {
+ Text("Rookie Battles")
+ }
+ }
+
+ val championButton = @Composable {
+ Button(
+ onClick = {
+ println("Champion button clicked - starting API call")
+ try {
+ RetrofitHelper().getOpponents(context, "champion") { opponents ->
+ println("API call completed successfully")
+ try {
+ println("Received opponents data: $opponents")
+ println("Opponents list size: ${opponents.opponentsList.size}")
+
+ // For loop to check opponents and print their names
+ for (opponent in opponents.opponentsList) {
+ println("Opponent: ${opponent.name}")
+ }
+
+ // Store the opponents in your ArrayList
+ opponentsList.clear()
+ opponentsList.addAll(opponents.opponentsList)
+
+ println("Updated opponentsList size: ${opponentsList.size}")
+ println("About to change view to champion")
+ currentView = "champion"
+ println("View changed to champion")
+ } catch (e: Exception) {
+ println("Error processing opponents data: ${e.message}")
+ e.printStackTrace()
+ }
+ }
+ } catch (e: Exception) {
+ println("Error calling getOpponents: ${e.message}")
+ e.printStackTrace()
+ }
+ }
+ ) {
+ Text("Champion Battles")
+ }
+ }
+
+ val ultimateButton = @Composable {
+ Button(
+ onClick = {
+ println("Ultimate button clicked - starting API call")
+ try {
+ RetrofitHelper().getOpponents(context, "ultimate") { opponents ->
+ println("API call completed successfully")
+ try {
+ println("Received opponents data: $opponents")
+ println("Opponents list size: ${opponents.opponentsList.size}")
+
+ // For loop to check opponents and print their names
+ for (opponent in opponents.opponentsList) {
+ println("Opponent: ${opponent.name}")
+ }
+
+ // Store the opponents in your ArrayList
+ opponentsList.clear()
+ opponentsList.addAll(opponents.opponentsList)
+
+ println("Updated opponentsList size: ${opponentsList.size}")
+ println("About to change view to ultimate")
+ currentView = "ultimate"
+ println("View changed to ultimate")
+ } catch (e: Exception) {
+ println("Error processing opponents data: ${e.message}")
+ e.printStackTrace()
+ }
+ }
+ } catch (e: Exception) {
+ println("Error calling getOpponents: ${e.message}")
+ e.printStackTrace()
+ }
+ }
+ ) {
+ Text("Ultimate Battles")
+ }
+ }
+
+ val megaButton = @Composable {
+ Button(
+ onClick = {
+ println("Mega button clicked - starting API call")
+ try {
+ RetrofitHelper().getOpponents(context, "mega") { opponents ->
+ println("API call completed successfully")
+ try {
+ println("Received opponents data: $opponents")
+ println("Opponents list size: ${opponents.opponentsList.size}")
+
+ // For loop to check opponents and print their names
+ for (opponent in opponents.opponentsList) {
+ println("Opponent: ${opponent.name}")
+ }
+
+ // Store the opponents in your ArrayList
+ opponentsList.clear()
+ opponentsList.addAll(opponents.opponentsList)
+
+ println("Updated opponentsList size: ${opponentsList.size}")
+ println("About to change view to mega")
+ currentView = "mega"
+ println("View changed to mega")
+ } catch (e: Exception) {
+ println("Error processing opponents data: ${e.message}")
+ e.printStackTrace()
+ }
+ }
+ } catch (e: Exception) {
+ println("Error calling getOpponents: ${e.message}")
+ e.printStackTrace()
+ }
+ }
+ ) {
+ Text("Mega Battles")
+ }
+ }
+
+ val backButton = @Composable {
+ Button(
+ onClick = {
+ currentView = "main"
+ }
+ ) {
+ Text("Back")
+ }
+ }
+
+ val characterDropdown = @Composable { currentStage: String ->
+ // Create hardcoded character lists for each stage
+ val rookieCharacters = listOf(
+ APIBattleCharacter("AGUMON", "degimon_name_Dim012_003", "dim012_mon03", 0, 1, 1800, 1800, 2400.0f, 700.0f),
+ APIBattleCharacter("PULSEMON", "degimon_name_Dim000_003", "dim000_mon03", 0, 1, 1800, 1800, 2400.0f, 700.0f),
+ APIBattleCharacter("DORUMON", "degimon_name_dim137_mon03", "dim137_mon03", 0, 1, 3000, 3000, 5100.0f, 1050.0f)
+ )
+
+ val championCharacters = listOf(
+ APIBattleCharacter("GREYMON","degimon_name_Dim012_004","dim012_mon04",1,1,2000, 2000, 3000.0f,900.0f),
+ APIBattleCharacter("TYRANNOMON","degimon_name_Dim008_006","dim008_mon06",1,3,2000, 2000, 2400.0f,600.0f),
+ APIBattleCharacter("DORUGAMON","degimon_name_dim137_mon05","dim137_mon05",1,3,3500, 3500, 5200.0f,1200.0f)
+ )
+
+ val ultimateCharacters = listOf(
+ APIBattleCharacter("METALGREYMON (VIRUS)","degimon_name_Dim014_005","dim014_mon05",2,2,2640, 2640, 2450.0f,800.0f),
+ APIBattleCharacter("MAMEMON", "degimon_name_Dim000_005", "dim000_mon05", 2, 1, 3000, 3000, 4000.0f, 1000.0f),
+ APIBattleCharacter("DORUGREYMON","degimon_name_dim137_mon09","dim137_mon09",2,3,5000, 5000, 6400.0f,1400.0f)
+ )
+
+ val megaCharacters = listOf(
+ APIBattleCharacter("WARGREYMON","degimon_name_Dim012_014","dim012_mon14",3,1,3080, 3080, 3825.0f,800.0f),
+ APIBattleCharacter("SLAYERDRAMON","degimon_name_dim129_mon15","dim129_mon15",3,1,4800, 4800, 6300.0f,1950.0f),
+ APIBattleCharacter("BREAKDRAMON","degimon_name_dim129_mon17","dim129_mon17",3,2,6000, 6000, 4000.0f,1980.0f)
+ )
+
+ // Get the appropriate character list based on current stage
+ val characterList = when (currentStage.lowercase()) {
+ "rookie" -> rookieCharacters
+ "champion" -> championCharacters
+ "ultimate" -> ultimateCharacters
+ "mega" -> megaCharacters
+ else -> rookieCharacters
+ }
+
+ ExposedDropdownMenuBox(
+ expanded = expanded,
+ onExpandedChange = { expanded = !expanded }
+ ) {
+ OutlinedTextField(
+ value = selectedStage.ifEmpty { "Select Character" },
+ onValueChange = {},
+ readOnly = true,
+ trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
+ modifier = Modifier.menuAnchor()
+ )
+
+ ExposedDropdownMenu(
+ expanded = expanded,
+ onDismissRequest = { expanded = false }
+ ) {
+ characterList.forEach { character ->
+ DropdownMenuItem(
+ text = { Text(character.name) },
+ onClick = {
+ selectedStage = character.name
+ activeCharacter = character
+ expanded = false
+ println("Selected character: ${character.name}")
+ }
+ )
+ }
+ }
+ }
+ }
+
Scaffold (
topBar = {
TopBanner(
@@ -27,7 +286,156 @@ fun BattlesScreen() {
.padding(top = contentPadding.calculateTopPadding())
.fillMaxSize()
) {
- Text("Coming soon")
+ when (currentView) {
+ "main" -> {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ rookieButton()
+ championButton()
+ ultimateButton()
+ megaButton()
+ }
+ }
+
+
+ "rookie" -> {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Text("Rookie Battle View")
+
+ // Add character selection dropdown
+ characterDropdown("rookie")
+
+ // Display buttons for each opponent
+ opponentsList.forEach { opponent ->
+ Button(
+ onClick = {
+ activeCharacter = opponent
+ println("Selected character: ${opponent.name}")
+ // You can add battle logic here
+ },
+ modifier = Modifier.padding(vertical = 4.dp)
+ ) {
+ Text("Battle ${opponent.name}")
+ }
+ }
+
+ // Show selected character info
+ activeCharacter?.let { character ->
+ Text("Active Character: ${character.name}")
+ Text("HP: ${character.currentHp}/${character.baseHp}")
+ Text("BP: ${character.baseBp}")
+ Text("AP: ${character.baseAp}")
+ }
+
+ backButton()
+ }
+ }
+
+ "champion" -> {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Text("Champion Battle View")
+
+ // Add character selection dropdown
+ characterDropdown("champion")
+
+ // Display buttons for each opponent
+ opponentsList.forEach { opponent ->
+ Button(
+ onClick = {
+ activeCharacter = opponent
+ println("Selected character: ${opponent.name}")
+ },
+ modifier = Modifier.padding(vertical = 4.dp)
+ ) {
+ Text("Battle ${opponent.name}")
+ }
+ }
+
+ // Show selected character info
+ activeCharacter?.let { character ->
+ Text("Active Character: ${character.name}")
+ Text("HP: ${character.currentHp}/${character.baseHp}")
+ Text("BP: ${character.baseBp}")
+ Text("AP: ${character.baseAp}")
+ }
+
+ backButton()
+ }
+ }
+
+ "ultimate" -> {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Text("Ultimate Battle View")
+
+ // Add character selection dropdown
+ characterDropdown("ultimate")
+
+ // Display buttons for each opponent
+ opponentsList.forEach { opponent ->
+ Button(
+ onClick = {
+ activeCharacter = opponent
+ println("Selected character: ${opponent.name}")
+ },
+ modifier = Modifier.padding(vertical = 4.dp)
+ ) {
+ Text("Battle ${opponent.name}")
+ }
+ }
+
+ // Show selected character info
+ activeCharacter?.let { character ->
+ Text("Active Character: ${character.name}")
+ Text("HP: ${character.currentHp}/${character.baseHp}")
+ Text("BP: ${character.baseBp}")
+ Text("AP: ${character.baseAp}")
+ }
+
+ backButton()
+ }
+ }
+
+ "mega" -> {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Text("Mega Battle View")
+
+ // Add character selection dropdown
+ characterDropdown("mega")
+
+ // Display buttons for each opponent
+ opponentsList.forEach { opponent ->
+ Button(
+ onClick = {
+ activeCharacter = opponent
+ println("Selected character: ${opponent.name}")
+ },
+ modifier = Modifier.padding(vertical = 4.dp)
+ ) {
+ Text("Battle ${opponent.name}")
+ }
+ }
+
+ // Show selected character info
+ activeCharacter?.let { character ->
+ Text("Active Character: ${character.name}")
+ Text("HP: ${character.currentHp}/${character.baseHp}")
+ Text("BP: ${character.baseBp}")
+ Text("AP: ${character.baseAp}")
+ }
+
+ backButton()
+ }
+ }
+ }
}
}
}