mirror of
https://github.com/nacabaro/vbhelper.git
synced 2026-07-30 00:31:54 +00:00
Compare commits
No commits in common. "main" and "v0.6.4-pre" have entirely different histories.
main
...
v0.6.4-pre
@ -2,6 +2,7 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.android.application)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
alias(libs.plugins.kotlin.compose)
|
||||
alias(libs.plugins.vksp)
|
||||
alias(libs.plugins.vprotobuf)
|
||||
@ -9,14 +10,14 @@ plugins {
|
||||
|
||||
android {
|
||||
namespace = "com.github.nacabaro.vbhelper"
|
||||
compileSdk = 37
|
||||
compileSdk = 36
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.github.nacabaro.vbhelper"
|
||||
minSdk = 28
|
||||
targetSdk = 37
|
||||
targetSdk = 36
|
||||
versionCode = 1
|
||||
versionName = "Alpha 0.6.5"
|
||||
versionName = "Alpha 0.6.4"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
@ -55,6 +56,9 @@ protobuf {
|
||||
artifact = "com.google.protobuf:protoc:4.27.0"
|
||||
}
|
||||
|
||||
// Generates the java Protobuf-lite code for the Protobufs in this project. See
|
||||
// https://github.com/google/protobuf-gradle-plugin#customizing-protobuf-compilation
|
||||
// for more information.
|
||||
generateProtoTasks {
|
||||
all().forEach { task ->
|
||||
task.builtins {
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
|
||||
tools:ignore="ScopedStorage" />
|
||||
|
||||
@ -35,6 +34,7 @@
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/Theme.VBHelper">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
@ -51,10 +51,8 @@
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="http" />
|
||||
<data android:host="localhost" android:port="8080" />
|
||||
<data android:host="127.0.0.1" android:port="8080" />
|
||||
<data android:pathPrefix="/authenticate" />
|
||||
<data android:scheme="http" android:host="localhost" android:port="8080" android:pathPrefix="/authenticate" />
|
||||
<data android:scheme="http" android:host="127.0.0.1" android:port="8080" android:pathPrefix="/authenticate" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
|
||||
@ -49,8 +49,7 @@ class MainActivity : ComponentActivity() {
|
||||
application.container.dataStoreSecretsRepository.secretsFlow,
|
||||
this,
|
||||
this::registerActivityLifecycleListener,
|
||||
this::unregisterActivityLifecycleListener,
|
||||
application.container.db,
|
||||
this::unregisterActivityLifecycleListener
|
||||
)
|
||||
val settingsScreenController = SettingsScreenControllerImpl(this)
|
||||
val itemsScreenController = ItemsScreenControllerImpl(this)
|
||||
|
||||
@ -2,13 +2,11 @@ package com.github.nacabaro.vbhelper.daos
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import androidx.room.RewriteQueriesToDropUnusedColumns
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
|
||||
@Dao
|
||||
@RewriteQueriesToDropUnusedColumns
|
||||
interface AdventureDao {
|
||||
@Query("""
|
||||
INSERT INTO Adventure (characterId, originalDuration, finishesAdventure)
|
||||
|
||||
@ -2,13 +2,11 @@ package com.github.nacabaro.vbhelper.daos
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import androidx.room.RewriteQueriesToDropUnusedColumns
|
||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
@RewriteQueriesToDropUnusedColumns
|
||||
interface CardFusionsDao {
|
||||
@Query("""
|
||||
INSERT INTO
|
||||
|
||||
@ -5,7 +5,6 @@ import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Upsert
|
||||
import androidx.room.RewriteQueriesToDropUnusedColumns
|
||||
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
|
||||
@ -17,7 +16,6 @@ import com.github.nacabaro.vbhelper.dtos.CharacterDtos
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
@RewriteQueriesToDropUnusedColumns
|
||||
interface UserCharacterDao {
|
||||
@Insert
|
||||
fun insertCharacterData(characterData: UserCharacter): Long
|
||||
|
||||
@ -40,8 +40,7 @@ import com.github.nacabaro.vbhelper.domain.device_data.CharacterTransferPolicy
|
||||
import com.github.nacabaro.vbhelper.domain.items.Items
|
||||
|
||||
@Database(
|
||||
version = 3,
|
||||
exportSchema = false,
|
||||
version = 2,
|
||||
entities = [
|
||||
Card::class,
|
||||
CardProgress::class,
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package com.github.nacabaro.vbhelper.domain.card
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@ -13,8 +12,7 @@ import androidx.room.PrimaryKey
|
||||
childColumns = ["cardId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
],
|
||||
indices = [Index(value = ["cardId"])]
|
||||
]
|
||||
)
|
||||
data class Background (
|
||||
@PrimaryKey(autoGenerate = true) val id: Long,
|
||||
@ -22,28 +20,4 @@ data class Background (
|
||||
val background: ByteArray,
|
||||
val backgroundWidth: Int,
|
||||
val backgroundHeight: Int
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as Background
|
||||
|
||||
if (id != other.id) return false
|
||||
if (cardId != other.cardId) return false
|
||||
if (!background.contentEquals(other.background)) return false
|
||||
if (backgroundWidth != other.backgroundWidth) return false
|
||||
if (backgroundHeight != other.backgroundHeight) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = id.hashCode()
|
||||
result = 31 * result + cardId.hashCode()
|
||||
result = 31 * result + background.contentHashCode()
|
||||
result = 31 * result + backgroundWidth
|
||||
result = 31 * result + backgroundHeight
|
||||
return result
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -14,34 +14,4 @@ data class Card(
|
||||
val name: String,
|
||||
val stageCount: Int,
|
||||
val isBEm: Boolean
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as Card
|
||||
|
||||
if (id != other.id) return false
|
||||
if (cardId != other.cardId) return false
|
||||
if (!logo.contentEquals(other.logo)) return false
|
||||
if (logoWidth != other.logoWidth) return false
|
||||
if (logoHeight != other.logoHeight) return false
|
||||
if (name != other.name) return false
|
||||
if (stageCount != other.stageCount) return false
|
||||
if (isBEm != other.isBEm) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = id.hashCode()
|
||||
result = 31 * result + cardId
|
||||
result = 31 * result + logo.contentHashCode()
|
||||
result = 31 * result + logoWidth
|
||||
result = 31 * result + logoHeight
|
||||
result = 31 * result + name.hashCode()
|
||||
result = 31 * result + stageCount
|
||||
result = 31 * result + isBEm.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package com.github.nacabaro.vbhelper.domain.card
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@ -19,10 +18,6 @@ import androidx.room.PrimaryKey
|
||||
childColumns = ["cardId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
],
|
||||
indices = [
|
||||
Index(value = ["characterId"]),
|
||||
Index(value = ["cardId"])
|
||||
]
|
||||
)
|
||||
data class CardAdventure(
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package com.github.nacabaro.vbhelper.domain.card
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
@ -21,10 +20,6 @@ import com.github.nacabaro.vbhelper.domain.characters.Sprite
|
||||
childColumns = ["spriteId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
],
|
||||
indices = [
|
||||
Index(value = ["cardId"]),
|
||||
Index(value = ["spriteId"])
|
||||
]
|
||||
)
|
||||
|
||||
@ -46,42 +41,4 @@ data class CardCharacter (
|
||||
val nameSprite: ByteArray,
|
||||
val nameWidth: Int,
|
||||
val nameHeight: Int
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as CardCharacter
|
||||
|
||||
if (id != other.id) return false
|
||||
if (cardId != other.cardId) return false
|
||||
if (spriteId != other.spriteId) return false
|
||||
if (charaIndex != other.charaIndex) return false
|
||||
if (stage != other.stage) return false
|
||||
if (attribute != other.attribute) return false
|
||||
if (baseHp != other.baseHp) return false
|
||||
if (baseBp != other.baseBp) return false
|
||||
if (baseAp != other.baseAp) return false
|
||||
if (!nameSprite.contentEquals(other.nameSprite)) return false
|
||||
if (nameWidth != other.nameWidth) return false
|
||||
if (nameHeight != other.nameHeight) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = id.hashCode()
|
||||
result = 31 * result + cardId.hashCode()
|
||||
result = 31 * result + spriteId.hashCode()
|
||||
result = 31 * result + charaIndex
|
||||
result = 31 * result + stage
|
||||
result = 31 * result + attribute.hashCode()
|
||||
result = 31 * result + baseHp
|
||||
result = 31 * result + baseBp
|
||||
result = 31 * result + baseAp
|
||||
result = 31 * result + nameSprite.contentHashCode()
|
||||
result = 31 * result + nameWidth
|
||||
result = 31 * result + nameHeight
|
||||
return result
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -1,7 +1,6 @@
|
||||
package com.github.nacabaro.vbhelper.domain.card
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
@ -20,10 +19,6 @@ import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
childColumns = ["toCharaId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
],
|
||||
indices = [
|
||||
Index(value = ["fromCharaId"]),
|
||||
Index(value = ["toCharaId"])
|
||||
]
|
||||
)
|
||||
data class CardFusions(
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package com.github.nacabaro.vbhelper.domain.card
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@ -19,10 +18,6 @@ import androidx.room.PrimaryKey
|
||||
childColumns = ["toCharaId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
],
|
||||
indices = [
|
||||
Index(value = ["charaId"]),
|
||||
Index(value = ["toCharaId"])
|
||||
]
|
||||
)
|
||||
data class PossibleTransformations (
|
||||
|
||||
@ -20,48 +20,4 @@ data class Sprite(
|
||||
val spriteDodge: ByteArray,
|
||||
val width: Int,
|
||||
val height: Int
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as Sprite
|
||||
|
||||
if (id != other.id) return false
|
||||
if (!spriteIdle1.contentEquals(other.spriteIdle1)) return false
|
||||
if (!spriteIdle2.contentEquals(other.spriteIdle2)) return false
|
||||
if (!spriteWalk1.contentEquals(other.spriteWalk1)) return false
|
||||
if (!spriteWalk2.contentEquals(other.spriteWalk2)) return false
|
||||
if (!spriteRun1.contentEquals(other.spriteRun1)) return false
|
||||
if (!spriteRun2.contentEquals(other.spriteRun2)) return false
|
||||
if (!spriteTrain1.contentEquals(other.spriteTrain1)) return false
|
||||
if (!spriteTrain2.contentEquals(other.spriteTrain2)) return false
|
||||
if (!spriteHappy.contentEquals(other.spriteHappy)) return false
|
||||
if (!spriteSleep.contentEquals(other.spriteSleep)) return false
|
||||
if (!spriteAttack.contentEquals(other.spriteAttack)) return false
|
||||
if (!spriteDodge.contentEquals(other.spriteDodge)) return false
|
||||
if (width != other.width) return false
|
||||
if (height != other.height) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = id
|
||||
result = 31 * result + spriteIdle1.contentHashCode()
|
||||
result = 31 * result + spriteIdle2.contentHashCode()
|
||||
result = 31 * result + spriteWalk1.contentHashCode()
|
||||
result = 31 * result + spriteWalk2.contentHashCode()
|
||||
result = 31 * result + spriteRun1.contentHashCode()
|
||||
result = 31 * result + spriteRun2.contentHashCode()
|
||||
result = 31 * result + spriteTrain1.contentHashCode()
|
||||
result = 31 * result + spriteTrain2.contentHashCode()
|
||||
result = 31 * result + spriteHappy.contentHashCode()
|
||||
result = 31 * result + spriteSleep.contentHashCode()
|
||||
result = 31 * result + spriteAttack.contentHashCode()
|
||||
result = 31 * result + spriteDodge.contentHashCode()
|
||||
result = 31 * result + width
|
||||
result = 31 * result + height
|
||||
return result
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package com.github.nacabaro.vbhelper.domain.device_data
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
import com.github.cfogrady.vbnfc.vb.SpecialMission
|
||||
@ -14,8 +13,7 @@ import com.github.cfogrady.vbnfc.vb.SpecialMission
|
||||
childColumns = ["characterId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
],
|
||||
indices = [Index(value = ["characterId"])]
|
||||
]
|
||||
)
|
||||
data class SpecialMissions (
|
||||
@PrimaryKey(autoGenerate = true) var id: Long = 0,
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package com.github.nacabaro.vbhelper.domain.device_data
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
import com.github.nacabaro.vbhelper.domain.card.CardCharacter
|
||||
@ -20,10 +19,6 @@ import com.github.nacabaro.vbhelper.domain.card.CardCharacter
|
||||
childColumns = ["stageId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
],
|
||||
indices = [
|
||||
Index(value = ["monId"]),
|
||||
Index(value = ["stageId"])
|
||||
]
|
||||
)
|
||||
data class TransformationHistory (
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package com.github.nacabaro.vbhelper.domain.device_data
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
import com.github.cfogrady.vbnfc.data.NfcCharacter
|
||||
@ -16,8 +15,7 @@ import com.github.nacabaro.vbhelper.domain.card.CardCharacter
|
||||
childColumns = ["charId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
],
|
||||
indices = [Index(value = ["charId"])]
|
||||
]
|
||||
)
|
||||
/**
|
||||
* UserCharacter represents and instance of a character. The charId should map to a Character
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package com.github.nacabaro.vbhelper.domain.device_data
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@ -13,8 +12,7 @@ import androidx.room.PrimaryKey
|
||||
childColumns = ["charId"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
],
|
||||
indices = [Index(value = ["charId"])]
|
||||
]
|
||||
)
|
||||
data class VitalsHistory (
|
||||
@PrimaryKey(autoGenerate = true) val id: Long = 0,
|
||||
|
||||
@ -9,35 +9,7 @@ object CardDtos {
|
||||
val logoHeight: Int,
|
||||
val totalCharacters: Int,
|
||||
val obtainedCharacters: Int,
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as CardProgress
|
||||
|
||||
if (cardId != other.cardId) return false
|
||||
if (cardName != other.cardName) return false
|
||||
if (!cardLogo.contentEquals(other.cardLogo)) return false
|
||||
if (logoWidth != other.logoWidth) return false
|
||||
if (logoHeight != other.logoHeight) return false
|
||||
if (totalCharacters != other.totalCharacters) return false
|
||||
if (obtainedCharacters != other.obtainedCharacters) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = cardId.hashCode()
|
||||
result = 31 * result + cardName.hashCode()
|
||||
result = 31 * result + cardLogo.contentHashCode()
|
||||
result = 31 * result + logoWidth
|
||||
result = 31 * result + logoHeight
|
||||
result = 31 * result + totalCharacters
|
||||
result = 31 * result + obtainedCharacters
|
||||
return result
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
data class CardAdventureWithSprites (
|
||||
val characterName: ByteArray,
|
||||
@ -51,67 +23,11 @@ object CardDtos {
|
||||
val characterDp: Int,
|
||||
val characterHp: Int,
|
||||
val steps: Int,
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as CardAdventureWithSprites
|
||||
|
||||
if (!characterName.contentEquals(other.characterName)) return false
|
||||
if (characterNameWidth != other.characterNameWidth) return false
|
||||
if (characterNameHeight != other.characterNameHeight) return false
|
||||
if (!characterIdleSprite.contentEquals(other.characterIdleSprite)) return false
|
||||
if (characterIdleSpriteWidth != other.characterIdleSpriteWidth) return false
|
||||
if (characterIdleSpriteHeight != other.characterIdleSpriteHeight) return false
|
||||
if (characterAp != other.characterAp) return false
|
||||
if (characterBp != other.characterBp) return false
|
||||
if (characterDp != other.characterDp) return false
|
||||
if (characterHp != other.characterHp) return false
|
||||
if (steps != other.steps) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = characterName.contentHashCode()
|
||||
result = 31 * result + characterNameWidth
|
||||
result = 31 * result + characterNameHeight
|
||||
result = 31 * result + characterIdleSprite.contentHashCode()
|
||||
result = 31 * result + characterIdleSpriteWidth
|
||||
result = 31 * result + characterIdleSpriteHeight
|
||||
result = 31 * result + characterAp
|
||||
result = 31 * result + (characterBp ?: 0)
|
||||
result = 31 * result + characterDp
|
||||
result = 31 * result + characterHp
|
||||
result = 31 * result + steps
|
||||
return result
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
data class CardIcon (
|
||||
val cardIcon: ByteArray,
|
||||
val cardIconWidth: Int,
|
||||
val cardIconHeight: Int
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as CardIcon
|
||||
|
||||
if (!cardIcon.contentEquals(other.cardIcon)) return false
|
||||
if (cardIconWidth != other.cardIconWidth) return false
|
||||
if (cardIconHeight != other.cardIconHeight) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = cardIcon.contentHashCode()
|
||||
result = 31 * result + cardIconWidth
|
||||
result = 31 * result + cardIconHeight
|
||||
return result
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -33,75 +33,7 @@ object CharacterDtos {
|
||||
val isBemCard: Boolean,
|
||||
val isInAdventure: Boolean,
|
||||
val active: Boolean
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as CharacterWithSprites
|
||||
|
||||
if (id != other.id) return false
|
||||
if (charId != other.charId) return false
|
||||
if (stage != other.stage) return false
|
||||
if (attribute != other.attribute) return false
|
||||
if (ageInDays != other.ageInDays) return false
|
||||
if (mood != other.mood) return false
|
||||
if (vitalPoints != other.vitalPoints) return false
|
||||
if (transformationCountdown != other.transformationCountdown) return false
|
||||
if (injuryStatus != other.injuryStatus) return false
|
||||
if (trophies != other.trophies) return false
|
||||
if (currentPhaseBattlesWon != other.currentPhaseBattlesWon) return false
|
||||
if (currentPhaseBattlesLost != other.currentPhaseBattlesLost) return false
|
||||
if (totalBattlesWon != other.totalBattlesWon) return false
|
||||
if (totalBattlesLost != other.totalBattlesLost) return false
|
||||
if (activityLevel != other.activityLevel) return false
|
||||
if (heartRateCurrent != other.heartRateCurrent) return false
|
||||
if (characterType != other.characterType) return false
|
||||
if (!spriteIdle.contentEquals(other.spriteIdle)) return false
|
||||
if (!spriteIdle2.contentEquals(other.spriteIdle2)) return false
|
||||
if (spriteWidth != other.spriteWidth) return false
|
||||
if (spriteHeight != other.spriteHeight) return false
|
||||
if (!nameSprite.contentEquals(other.nameSprite)) return false
|
||||
if (nameSpriteWidth != other.nameSpriteWidth) return false
|
||||
if (nameSpriteHeight != other.nameSpriteHeight) return false
|
||||
if (isBemCard != other.isBemCard) return false
|
||||
if (isInAdventure != other.isInAdventure) return false
|
||||
if (active != other.active) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = id.hashCode()
|
||||
result = 31 * result + charId.hashCode()
|
||||
result = 31 * result + stage
|
||||
result = 31 * result + attribute.hashCode()
|
||||
result = 31 * result + ageInDays
|
||||
result = 31 * result + mood
|
||||
result = 31 * result + vitalPoints
|
||||
result = 31 * result + transformationCountdown
|
||||
result = 31 * result + injuryStatus.hashCode()
|
||||
result = 31 * result + trophies
|
||||
result = 31 * result + currentPhaseBattlesWon
|
||||
result = 31 * result + currentPhaseBattlesLost
|
||||
result = 31 * result + totalBattlesWon
|
||||
result = 31 * result + totalBattlesLost
|
||||
result = 31 * result + activityLevel
|
||||
result = 31 * result + heartRateCurrent
|
||||
result = 31 * result + characterType.hashCode()
|
||||
result = 31 * result + spriteIdle.contentHashCode()
|
||||
result = 31 * result + spriteIdle2.contentHashCode()
|
||||
result = 31 * result + spriteWidth
|
||||
result = 31 * result + spriteHeight
|
||||
result = 31 * result + nameSprite.contentHashCode()
|
||||
result = 31 * result + nameSpriteWidth
|
||||
result = 31 * result + nameSpriteHeight
|
||||
result = 31 * result + isBemCard.hashCode()
|
||||
result = 31 * result + isInAdventure.hashCode()
|
||||
result = 31 * result + active.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
data class CardCharacterInfo(
|
||||
val cardId: Long,
|
||||
@ -118,33 +50,7 @@ object CharacterDtos {
|
||||
val spriteHeight: Int,
|
||||
val monIndex: Int,
|
||||
val transformationDate: Long
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as TransformationHistory
|
||||
|
||||
if (id != other.id) return false
|
||||
if (!spriteIdle.contentEquals(other.spriteIdle)) return false
|
||||
if (spriteWidth != other.spriteWidth) return false
|
||||
if (spriteHeight != other.spriteHeight) return false
|
||||
if (monIndex != other.monIndex) return false
|
||||
if (transformationDate != other.transformationDate) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = id.hashCode()
|
||||
result = 31 * result + spriteIdle.contentHashCode()
|
||||
result = 31 * result + spriteWidth
|
||||
result = 31 * result + spriteHeight
|
||||
result = 31 * result + monIndex
|
||||
result = 31 * result + transformationDate.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
data class TransformationHistoryExport(
|
||||
val stageId: Long,
|
||||
@ -167,76 +73,14 @@ object CharacterDtos {
|
||||
val baseAp: Int,
|
||||
val stage: Int,
|
||||
val attribute: NfcCharacter.Attribute,
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as CardCharaProgress
|
||||
|
||||
if (id != other.id) return false
|
||||
if (!spriteIdle.contentEquals(other.spriteIdle)) return false
|
||||
if (spriteWidth != other.spriteWidth) return false
|
||||
if (spriteHeight != other.spriteHeight) return false
|
||||
if (!nameSprite.contentEquals(other.nameSprite)) return false
|
||||
if (nameSpriteWidth != other.nameSpriteWidth) return false
|
||||
if (nameSpriteHeight != other.nameSpriteHeight) return false
|
||||
if (discoveredOn != other.discoveredOn) return false
|
||||
if (baseHp != other.baseHp) return false
|
||||
if (baseBp != other.baseBp) return false
|
||||
if (baseAp != other.baseAp) return false
|
||||
if (stage != other.stage) return false
|
||||
if (attribute != other.attribute) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = id.hashCode()
|
||||
result = 31 * result + spriteIdle.contentHashCode()
|
||||
result = 31 * result + spriteWidth
|
||||
result = 31 * result + spriteHeight
|
||||
result = 31 * result + nameSprite.contentHashCode()
|
||||
result = 31 * result + nameSpriteWidth
|
||||
result = 31 * result + nameSpriteHeight
|
||||
result = 31 * result + (discoveredOn?.hashCode() ?: 0)
|
||||
result = 31 * result + baseHp
|
||||
result = 31 * result + baseBp
|
||||
result = 31 * result + baseAp
|
||||
result = 31 * result + stage
|
||||
result = 31 * result + attribute.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
data class CardProgress(
|
||||
val id: Long,
|
||||
val spriteIdle: ByteArray,
|
||||
val spriteWidth: Int,
|
||||
val spriteHeight: Int,
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as CardProgress
|
||||
|
||||
if (id != other.id) return false
|
||||
if (!spriteIdle.contentEquals(other.spriteIdle)) return false
|
||||
if (spriteWidth != other.spriteWidth) return false
|
||||
if (spriteHeight != other.spriteHeight) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = id.hashCode()
|
||||
result = 31 * result + spriteIdle.contentHashCode()
|
||||
result = 31 * result + spriteWidth
|
||||
result = 31 * result + spriteHeight
|
||||
return result
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
data class AdventureCharacterWithSprites(
|
||||
var id: Long = 0,
|
||||
@ -262,67 +106,7 @@ object CharacterDtos {
|
||||
val isBemCard: Boolean,
|
||||
val finishesAdventure: Long,
|
||||
val originalTimeInMinutes: Long
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as AdventureCharacterWithSprites
|
||||
|
||||
if (id != other.id) return false
|
||||
if (charId != other.charId) return false
|
||||
if (stage != other.stage) return false
|
||||
if (attribute != other.attribute) return false
|
||||
if (ageInDays != other.ageInDays) return false
|
||||
if (mood != other.mood) return false
|
||||
if (vitalPoints != other.vitalPoints) return false
|
||||
if (transformationCountdown != other.transformationCountdown) return false
|
||||
if (injuryStatus != other.injuryStatus) return false
|
||||
if (trophies != other.trophies) return false
|
||||
if (currentPhaseBattlesWon != other.currentPhaseBattlesWon) return false
|
||||
if (currentPhaseBattlesLost != other.currentPhaseBattlesLost) return false
|
||||
if (totalBattlesWon != other.totalBattlesWon) return false
|
||||
if (totalBattlesLost != other.totalBattlesLost) return false
|
||||
if (activityLevel != other.activityLevel) return false
|
||||
if (heartRateCurrent != other.heartRateCurrent) return false
|
||||
if (characterType != other.characterType) return false
|
||||
if (!spriteIdle.contentEquals(other.spriteIdle)) return false
|
||||
if (spriteWidth != other.spriteWidth) return false
|
||||
if (spriteHeight != other.spriteHeight) return false
|
||||
if (isBemCard != other.isBemCard) return false
|
||||
if (finishesAdventure != other.finishesAdventure) return false
|
||||
if (originalTimeInMinutes != other.originalTimeInMinutes) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = id.hashCode()
|
||||
result = 31 * result + charId.hashCode()
|
||||
result = 31 * result + stage
|
||||
result = 31 * result + attribute.hashCode()
|
||||
result = 31 * result + ageInDays
|
||||
result = 31 * result + mood
|
||||
result = 31 * result + vitalPoints
|
||||
result = 31 * result + transformationCountdown
|
||||
result = 31 * result + injuryStatus.hashCode()
|
||||
result = 31 * result + trophies
|
||||
result = 31 * result + currentPhaseBattlesWon
|
||||
result = 31 * result + currentPhaseBattlesLost
|
||||
result = 31 * result + totalBattlesWon
|
||||
result = 31 * result + totalBattlesLost
|
||||
result = 31 * result + activityLevel
|
||||
result = 31 * result + heartRateCurrent
|
||||
result = 31 * result + characterType.hashCode()
|
||||
result = 31 * result + spriteIdle.contentHashCode()
|
||||
result = 31 * result + spriteWidth
|
||||
result = 31 * result + spriteHeight
|
||||
result = 31 * result + isBemCard.hashCode()
|
||||
result = 31 * result + finishesAdventure.hashCode()
|
||||
result = 31 * result + originalTimeInMinutes.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
data class EvolutionRequirementsWithSpritesAndObtained(
|
||||
val charaId: Long,
|
||||
@ -337,45 +121,7 @@ object CharacterDtos {
|
||||
val requiredWinRate: Int,
|
||||
val changeTimerHours: Int,
|
||||
val requiredAdventureLevelCompleted: Int
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as EvolutionRequirementsWithSpritesAndObtained
|
||||
|
||||
if (charaId != other.charaId) return false
|
||||
if (fromCharaId != other.fromCharaId) return false
|
||||
if (!spriteIdle.contentEquals(other.spriteIdle)) return false
|
||||
if (spriteWidth != other.spriteWidth) return false
|
||||
if (spriteHeight != other.spriteHeight) return false
|
||||
if (discoveredOn != other.discoveredOn) return false
|
||||
if (requiredTrophies != other.requiredTrophies) return false
|
||||
if (requiredVitals != other.requiredVitals) return false
|
||||
if (requiredBattles != other.requiredBattles) return false
|
||||
if (requiredWinRate != other.requiredWinRate) return false
|
||||
if (changeTimerHours != other.changeTimerHours) return false
|
||||
if (requiredAdventureLevelCompleted != other.requiredAdventureLevelCompleted) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = charaId.hashCode()
|
||||
result = 31 * result + fromCharaId.hashCode()
|
||||
result = 31 * result + spriteIdle.contentHashCode()
|
||||
result = 31 * result + spriteWidth
|
||||
result = 31 * result + spriteHeight
|
||||
result = 31 * result + (discoveredOn?.hashCode() ?: 0)
|
||||
result = 31 * result + requiredTrophies
|
||||
result = 31 * result + requiredVitals
|
||||
result = 31 * result + requiredBattles
|
||||
result = 31 * result + requiredWinRate
|
||||
result = 31 * result + changeTimerHours
|
||||
result = 31 * result + requiredAdventureLevelCompleted
|
||||
return result
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
data class FusionsWithSpritesAndObtained(
|
||||
val charaId: Long,
|
||||
@ -385,33 +131,5 @@ object CharacterDtos {
|
||||
val spriteHeight: Int,
|
||||
val discoveredOn: Long?,
|
||||
val fusionAttribute: NfcCharacter.Attribute
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as FusionsWithSpritesAndObtained
|
||||
|
||||
if (charaId != other.charaId) return false
|
||||
if (fromCharaId != other.fromCharaId) return false
|
||||
if (!spriteIdle.contentEquals(other.spriteIdle)) return false
|
||||
if (spriteWidth != other.spriteWidth) return false
|
||||
if (spriteHeight != other.spriteHeight) return false
|
||||
if (discoveredOn != other.discoveredOn) return false
|
||||
if (fusionAttribute != other.fusionAttribute) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = charaId.hashCode()
|
||||
result = 31 * result + fromCharaId.hashCode()
|
||||
result = 31 * result + spriteIdle.contentHashCode()
|
||||
result = 31 * result + spriteWidth
|
||||
result = 31 * result + spriteHeight
|
||||
result = 31 * result + (discoveredOn?.hashCode() ?: 0)
|
||||
result = 31 * result + fusionAttribute.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,15 +1,10 @@
|
||||
package com.github.nacabaro.vbhelper.screens
|
||||
|
||||
/**
|
||||
* This is me, nacabaro.
|
||||
* File related to battles.
|
||||
* TODO: Refactor this, 2400+ lines feels like a lot.
|
||||
*/
|
||||
|
||||
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.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.size
|
||||
@ -33,6 +28,10 @@ import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
//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.runtime.LaunchedEffect
|
||||
@ -52,6 +51,8 @@ import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.media.MediaPlayer
|
||||
import android.os.Environment
|
||||
//import androidx.compose.animation.core.animateFloatAsState
|
||||
//import androidx.compose.animation.core.tween
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
@ -71,8 +72,13 @@ import com.github.nacabaro.vbhelper.battle.AnimatedSpriteImage
|
||||
import com.github.nacabaro.vbhelper.battle.HitEffectOverlay
|
||||
import com.github.nacabaro.vbhelper.battle.BattleAuthContainer
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
//import kotlin.math.sin
|
||||
//import kotlin.math.PI
|
||||
//import androidx.compose.animation.core.animateDpAsState
|
||||
//import androidx.compose.animation.core.animateIntAsState
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.graphics.Shadow
|
||||
@ -80,20 +86,24 @@ import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import android.graphics.BitmapFactory
|
||||
//import android.os.Environment
|
||||
import java.io.File
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.foundation.layout.width
|
||||
import com.github.nacabaro.vbhelper.di.VBHelper
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
//import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import androidx.compose.material3.AlertDialog
|
||||
|
||||
/*@Composable
|
||||
@Composable
|
||||
fun isLandscapeMode(): Boolean {
|
||||
val configuration = LocalConfiguration.current
|
||||
return configuration.screenWidthDp > configuration.screenHeightDp
|
||||
}*/
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun getLandscapeModifier(): Modifier {
|
||||
@ -1725,7 +1735,7 @@ fun BattlesScreen() {
|
||||
val currentCharacter = activeUserCharacter
|
||||
if (currentCharacter != null && canBattle && playerBattleType != null) {
|
||||
try {
|
||||
RetrofitHelper().getOpponents(context, playerBattleType) { opponents ->
|
||||
RetrofitHelper().getOpponents(context, playerBattleType!!) { opponents ->
|
||||
try {
|
||||
// Create a new list to trigger UI recomposition
|
||||
opponentsList = ArrayList(opponents.opponentsList)
|
||||
@ -2124,8 +2134,8 @@ fun BattlesScreen() {
|
||||
|
||||
// Create APIBattleCharacter from database character
|
||||
val playerCharacter = APIBattleCharacter(
|
||||
name = "Player Character", // We could get this from the database if needed
|
||||
namekey = "player_digimon", // Name key for the character (functional lookup key, not shown)
|
||||
name = "Player Digimon", // We could get this from the database if needed
|
||||
namekey = "player_digimon", // Name key for the character
|
||||
charaId = formattedCardId, // Use the formatted card ID for sprite loading
|
||||
stage = characterData.stage,
|
||||
attribute = characterData.attribute.ordinal, // Convert enum to int
|
||||
@ -2232,10 +2242,10 @@ fun BattlesScreen() {
|
||||
) {
|
||||
// Show active character info
|
||||
activeUserCharacter?.let { character ->
|
||||
Text("Active character:")
|
||||
Text("Active Digimon:")
|
||||
Text("Stage: ${character.stage}")
|
||||
activeCardId?.let { cardId ->
|
||||
Text("Character ID: $cardId", fontSize = 14.sp, color = Color.Blue, fontWeight = FontWeight.Bold)
|
||||
Text("Digimon ID: $cardId", fontSize = 14.sp, color = Color.Blue, fontWeight = FontWeight.Bold)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
@ -2336,7 +2346,7 @@ fun BattlesScreen() {
|
||||
textAlign = TextAlign.Center)
|
||||
}
|
||||
} else {
|
||||
Text("Your character must be at least Stage 2 to battle",
|
||||
Text("Your Digimon must be at least Stage 2 to battle",
|
||||
fontSize = 16.sp,
|
||||
color = Color.Red,
|
||||
textAlign = TextAlign.Center)
|
||||
@ -2405,7 +2415,7 @@ fun BattlesScreen() {
|
||||
|
||||
// Also check winner field if it's not empty
|
||||
val playerWonFromWinner = activeCardId?.let { cardId ->
|
||||
val winner = apiResult.winner
|
||||
val winner = apiResult.winner ?: ""
|
||||
if (winner.isNotEmpty()) {
|
||||
if (winner.contains("|")) {
|
||||
// Pipe-separated format: first part is the winner
|
||||
@ -2432,7 +2442,7 @@ fun BattlesScreen() {
|
||||
println("BATTLESCREEN: Battle result (first call) - winner: '${apiResult.winner}', playerHP: ${apiResult.playerHP}, opponentHP: ${apiResult.opponentHP}, playerWonFromHP: $playerWonFromHP, playerWonFromWinner: $playerWonFromWinner, final playerWon: $playerWon")
|
||||
|
||||
// Store winner name for display (will be updated in cleanup call if available)
|
||||
winnerName = apiResult.winner
|
||||
winnerName = apiResult.winner ?: if (playerWon) "You" else "Opponent"
|
||||
isWinnerLoaded = true
|
||||
|
||||
// Then send the cleanup call - this will have the actual winner name
|
||||
@ -2455,7 +2465,7 @@ fun BattlesScreen() {
|
||||
// Primary method: Check HP values (opponentHP <= 0 means opponent lost = player won)
|
||||
// Secondary method: Check winner name (if winner doesn't match opponent, player won)
|
||||
val opponentName = selectedOpponent?.name ?: ""
|
||||
val winner = cleanupResult.winner
|
||||
val winner = cleanupResult.winner ?: ""
|
||||
|
||||
// Primary: HP-based determination (most reliable)
|
||||
// If opponentHP <= 0, opponent is dead = player won
|
||||
|
||||
@ -45,12 +45,11 @@ class HomeScreenControllerImpl(
|
||||
.clearSpecialMission(missionId)
|
||||
|
||||
if (missionStatus.status == SpecialMission.Status.COMPLETED) {
|
||||
val allItems = database.itemDao().getAllItems().first()
|
||||
if (allItems.isEmpty()) {
|
||||
onCleared(null, null)
|
||||
return@launch
|
||||
}
|
||||
val randomItem = allItems.random()
|
||||
val randomItem = database
|
||||
.itemDao()
|
||||
.getAllItems()
|
||||
.first()
|
||||
.random()
|
||||
|
||||
val randomItemAmount = (Random.nextFloat() * 5).roundToInt()
|
||||
|
||||
|
||||
@ -142,7 +142,7 @@ fun VBDiMHomeScreen(
|
||||
ItemDisplay(
|
||||
icon = R.drawable.baseline_swords_24,
|
||||
textValue = when {
|
||||
activeMon.currentPhaseBattlesWon + activeMon.currentPhaseBattlesLost == 0 -> "0.00 %"
|
||||
activeMon.totalBattlesLost == 0 -> "0.00 %"
|
||||
else -> {
|
||||
val battleWinPercentage =
|
||||
activeMon.currentPhaseBattlesWon.toFloat() / (activeMon.currentPhaseBattlesWon + activeMon.currentPhaseBattlesLost).toFloat()
|
||||
@ -150,7 +150,7 @@ fun VBDiMHomeScreen(
|
||||
Locale.getDefault(),
|
||||
"%.2f",
|
||||
battleWinPercentage * 100
|
||||
) + " %"
|
||||
) + " %" // Specify locale
|
||||
}
|
||||
},
|
||||
definition = stringResource(R.string.home_vbdim_current_phase_win),
|
||||
@ -193,9 +193,9 @@ fun VBDiMHomeScreen(
|
||||
onClickMission = { missionId ->
|
||||
selectedSpecialMissionId = missionId
|
||||
},
|
||||
onClickCollect = { missionId ->
|
||||
onClickCollect = {
|
||||
homeScreenController
|
||||
.clearSpecialMission(missionId, onClickCollect)
|
||||
.clearSpecialMission(selectedSpecialMissionId, onClickCollect)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@ -4,9 +4,9 @@ import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.PrimaryTabRow
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Tab
|
||||
import androidx.compose.material3.TabRow
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
@ -34,7 +34,7 @@ fun ItemsScreen(
|
||||
topBar = {
|
||||
Column {
|
||||
TopBanner(text = stringResource(R.string.items_title))
|
||||
PrimaryTabRow(
|
||||
TabRow(
|
||||
selectedTabIndex = selectedTabItem,
|
||||
modifier = Modifier
|
||||
) {
|
||||
|
||||
@ -43,7 +43,7 @@ fun ChooseConnectOption(
|
||||
.padding(contentPadding)
|
||||
) {
|
||||
Text(
|
||||
text = "VB, VH, VBBE",
|
||||
text = "Bandai Toys = Vital Bracelet, Vital Hero, BE Bracelet",
|
||||
fontSize = 14.sp,
|
||||
modifier = Modifier.padding(bottom = 24.dp)
|
||||
)
|
||||
|
||||
@ -44,8 +44,14 @@ fun ScanScreen(
|
||||
|
||||
val context = LocalContext.current
|
||||
|
||||
LaunchedEffect(characterId) {
|
||||
LaunchedEffect(storageRepository) {
|
||||
withContext(Dispatchers.IO) {
|
||||
/*
|
||||
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)
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@ package com.github.nacabaro.vbhelper.screens.scanScreen
|
||||
import android.content.Intent
|
||||
import android.nfc.NfcAdapter
|
||||
import android.nfc.Tag
|
||||
import android.nfc.tech.IsoDep
|
||||
import android.nfc.tech.NfcA
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
@ -16,16 +15,12 @@ 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.database.AppDatabase
|
||||
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.VitalWearCharacterExporter
|
||||
import com.github.nacabaro.vbhelper.source.VitalWearCharacterImporter
|
||||
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.transfer.hce.VitalWearHceReaderClient
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
@ -37,10 +32,8 @@ class ScanScreenControllerImpl(
|
||||
private val componentActivity: ComponentActivity,
|
||||
private val registerActivityLifecycleListener: (String, ActivityLifecycleListener)->Unit,
|
||||
private val unregisterActivityLifecycleListener: (String)->Unit,
|
||||
private val database: AppDatabase,
|
||||
): ScanScreenController {
|
||||
private var lastScannedCharacter: NfcCharacter? = null
|
||||
private var pendingExportCharacterId: Long? = null
|
||||
private val nfcAdapter: NfcAdapter
|
||||
|
||||
init {
|
||||
@ -53,9 +46,7 @@ class ScanScreenControllerImpl(
|
||||
}
|
||||
|
||||
override fun onClickRead(secrets: Secrets, onComplete: ()->Unit, onMultipleCards: (List<Card>) -> Unit) {
|
||||
handleTag(
|
||||
secrets,
|
||||
handlerFunc = { tagCommunicator ->
|
||||
handleTag(secrets) { tagCommunicator ->
|
||||
try {
|
||||
val character = tagCommunicator.receiveCharacter()
|
||||
val resultMessage = characterFromNfc(character) { cards, nfcCharacter ->
|
||||
@ -72,27 +63,7 @@ class ScanScreenControllerImpl(
|
||||
onComplete.invoke()
|
||||
componentActivity.getString(R.string.scan_error_generic)
|
||||
}
|
||||
},
|
||||
hceHandler = { isoDep ->
|
||||
try {
|
||||
val client = VitalWearHceReaderClient(isoDep)
|
||||
val character = client.receiveCharacterFromWatch()
|
||||
val importer = VitalWearCharacterImporter(database)
|
||||
val result = importer.importCharacter(character)
|
||||
Log.i("NFC_READ", "VitalWear HCE import: ${result.message}")
|
||||
componentActivity.runOnUiThread {
|
||||
Toast.makeText(componentActivity, result.message, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("NFC_READ", "Error reading character from VitalWear HCE", e)
|
||||
componentActivity.runOnUiThread {
|
||||
Toast.makeText(componentActivity, componentActivity.getString(R.string.scan_error_generic) + ": " + (e.message ?: e.javaClass.simpleName), Toast.LENGTH_LONG).show()
|
||||
}
|
||||
} finally {
|
||||
onComplete()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun cancelRead() {
|
||||
@ -112,45 +83,29 @@ class ScanScreenControllerImpl(
|
||||
unregisterActivityLifecycleListener.invoke(key)
|
||||
}
|
||||
|
||||
private fun handleTag(
|
||||
secrets: Secrets,
|
||||
handlerFunc: (TagCommunicator) -> String,
|
||||
hceHandler: ((IsoDep) -> Unit)? = null,
|
||||
) {
|
||||
// EXTRACTED DIRECTLY FROM EXAMPLE APP
|
||||
private fun handleTag(secrets: Secrets, handlerFunc: (TagCommunicator)->String) {
|
||||
if (!nfcAdapter.isEnabled) {
|
||||
showWirelessSettings()
|
||||
} else {
|
||||
val options = Bundle()
|
||||
// Work around for some broken Nfc firmware implementations that poll the card too fast
|
||||
options.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 250)
|
||||
nfcAdapter.enableReaderMode(
|
||||
componentActivity,
|
||||
buildOnReadTag(secrets, handlerFunc, hceHandler),
|
||||
NfcAdapter.FLAG_READER_NFC_A or NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK,
|
||||
nfcAdapter.enableReaderMode(componentActivity, buildOnReadTag(secrets, handlerFunc), NfcAdapter.FLAG_READER_NFC_A or NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK,
|
||||
options
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildOnReadTag(
|
||||
secrets: Secrets,
|
||||
handlerFunc: (TagCommunicator) -> String,
|
||||
hceHandler: ((IsoDep) -> Unit)? = null,
|
||||
): (Tag) -> Unit {
|
||||
// EXTRACTED DIRECTLY FROM EXAMPLE APP
|
||||
private fun buildOnReadTag(secrets: Secrets, handlerFunc: (TagCommunicator)->String): (Tag)->Unit {
|
||||
return { tag->
|
||||
val isoDep = IsoDep.get(tag)
|
||||
if (isoDep != null && hceHandler != null) {
|
||||
// VitalWear watch via HCE / ISO-DEP
|
||||
isoDep.connect()
|
||||
isoDep.use { hceHandler(isoDep) }
|
||||
} else {
|
||||
// Physical Vital Bracelet via raw NFC-A
|
||||
val nfcData = NfcA.get(tag)
|
||||
if (nfcData == null) {
|
||||
componentActivity.runOnUiThread {
|
||||
Toast.makeText(componentActivity, componentActivity.getString(R.string.scan_tag_not_vb), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
} else {
|
||||
}
|
||||
nfcData.connect()
|
||||
nfcData.use {
|
||||
val tagCommunicator = TagCommunicator.getInstance(nfcData, secrets.getCryptographicTransformerMap())
|
||||
@ -161,8 +116,6 @@ class ScanScreenControllerImpl(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSecrets() {
|
||||
componentActivity.lifecycleScope.launch(Dispatchers.IO) {
|
||||
@ -179,16 +132,16 @@ class ScanScreenControllerImpl(
|
||||
nfcCharacter: NfcCharacter,
|
||||
onComplete: () -> Unit
|
||||
) {
|
||||
handleTag(
|
||||
secrets,
|
||||
handlerFunc = { tagCommunicator ->
|
||||
handleTag(secrets) { tagCommunicator ->
|
||||
try {
|
||||
if (nfcCharacter is VBNfcCharacter) {
|
||||
Log.d("SendCharacter", "VBNfcCharacter")
|
||||
tagCommunicator.sendCharacter(nfcCharacter)
|
||||
val castNfcCharacter: VBNfcCharacter = nfcCharacter
|
||||
tagCommunicator.sendCharacter(castNfcCharacter)
|
||||
} else if (nfcCharacter is BENfcCharacter) {
|
||||
Log.d("SendCharacter", "BENfcCharacter")
|
||||
tagCommunicator.sendCharacter(nfcCharacter)
|
||||
val castNfcCharacter: BENfcCharacter = nfcCharacter
|
||||
tagCommunicator.sendCharacter(castNfcCharacter)
|
||||
}
|
||||
onComplete.invoke()
|
||||
componentActivity.getString(R.string.scan_sent_character_success)
|
||||
@ -196,12 +149,7 @@ class ScanScreenControllerImpl(
|
||||
Log.e("TAG", e.stackTraceToString())
|
||||
componentActivity.getString(R.string.scan_error_generic)
|
||||
}
|
||||
},
|
||||
hceHandler = { _ ->
|
||||
// Character was already sent in onClickCheckCard's HCE handler.
|
||||
onComplete()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onClickCheckCard(
|
||||
@ -209,42 +157,11 @@ class ScanScreenControllerImpl(
|
||||
nfcCharacter: NfcCharacter,
|
||||
onComplete: () -> Unit
|
||||
) {
|
||||
handleTag(
|
||||
secrets,
|
||||
handlerFunc = { tagCommunicator ->
|
||||
handleTag(secrets) { tagCommunicator ->
|
||||
tagCommunicator.prepareDIMForCharacter(nfcCharacter.dimId)
|
||||
onComplete.invoke()
|
||||
componentActivity.getString(R.string.scan_sent_dim_success)
|
||||
},
|
||||
hceHandler = { isoDep ->
|
||||
// VitalWear watch: send the character proto directly via HCE.
|
||||
val characterId = pendingExportCharacterId
|
||||
if (characterId == null) {
|
||||
Log.e("NFC_WRITE", "No pending character to send to VitalWear")
|
||||
componentActivity.runOnUiThread {
|
||||
Toast.makeText(componentActivity, componentActivity.getString(R.string.scan_error_generic), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
onComplete()
|
||||
return@handleTag
|
||||
}
|
||||
try {
|
||||
val proto = VitalWearCharacterExporter(componentActivity, database).buildCharacterProto(characterId)
|
||||
val client = VitalWearHceReaderClient(isoDep)
|
||||
client.sendCharacterToWatch(proto)
|
||||
Log.i("NFC_WRITE", "Character sent to VitalWear (id=$characterId), deletion deferred to WritingScreen")
|
||||
componentActivity.runOnUiThread {
|
||||
Toast.makeText(componentActivity, componentActivity.getString(R.string.scan_sent_character_success), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("NFC_WRITE", "Error sending character to VitalWear HCE", e)
|
||||
componentActivity.runOnUiThread {
|
||||
Toast.makeText(componentActivity, componentActivity.getString(R.string.scan_error_generic) + ": " + (e.message ?: e.javaClass.simpleName), Toast.LENGTH_LONG).show()
|
||||
}
|
||||
} finally {
|
||||
onComplete()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// EXTRACTED DIRECTLY FROM EXAMPLE APP
|
||||
@ -264,8 +181,10 @@ class ScanScreenControllerImpl(
|
||||
}
|
||||
|
||||
override suspend fun characterToNfc(characterId: Long): NfcCharacter {
|
||||
pendingExportCharacterId = characterId
|
||||
val nfcGenerator = ToNfcConverter(componentActivity = componentActivity)
|
||||
val nfcGenerator = ToNfcConverter(
|
||||
componentActivity = componentActivity
|
||||
)
|
||||
|
||||
val character = nfcGenerator.characterToNfc(characterId)
|
||||
Log.d("CharacterType", character.toString())
|
||||
return character
|
||||
|
||||
@ -104,7 +104,7 @@ fun TransferAnimationScreen(
|
||||
) {
|
||||
Image(
|
||||
bitmap = preview.imageBitmap,
|
||||
contentDescription = "Transferred character sprite",
|
||||
contentDescription = "Transferred Digimon sprite",
|
||||
modifier = Modifier
|
||||
.size(preview.dpWidth, preview.dpHeight)
|
||||
.padding(8.dp),
|
||||
|
||||
@ -136,7 +136,7 @@ class SettingsScreenControllerImpl(
|
||||
secrets = secretsImporter.importSecrets(it)
|
||||
} catch (e: Exception) {
|
||||
context.runOnUiThread {
|
||||
Toast.makeText(context, "Secrets import failed. Please only select the official app APK.", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(context, "Secrets import failed. Please only select the official Vital Arena App 2.1.0 APK.", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
return@launch
|
||||
}
|
||||
|
||||
@ -15,13 +15,14 @@ class VitalWearCharacterExporter(
|
||||
private val context: Context,
|
||||
private val database: AppDatabase
|
||||
) {
|
||||
fun buildCharacterProto(characterId: Long): Character = runBlocking {
|
||||
fun buildShareIntent(characterId: Long): Intent {
|
||||
return runBlocking {
|
||||
val characterWithSprites = database.userCharacterDao().getCharacterWithSprites(characterId)
|
||||
val userCharacter = database.userCharacterDao().getCharacter(characterId)
|
||||
val card = database.cardDao().getCardByCharacterIdSync(characterId)
|
||||
?: error("Card not found for character $characterId")
|
||||
val cardProgress = database.cardProgressDao().getCardProgressSync(card.id) ?: 0
|
||||
Character.newBuilder()
|
||||
val proto = Character.newBuilder()
|
||||
.setCardId(card.cardId)
|
||||
.setCardName(card.name)
|
||||
.setCharacterStats(
|
||||
@ -60,11 +61,6 @@ class VitalWearCharacterExporter(
|
||||
}
|
||||
)
|
||||
.build()
|
||||
}
|
||||
|
||||
fun buildShareIntent(characterId: Long): Intent {
|
||||
return runBlocking {
|
||||
val proto = buildCharacterProto(characterId)
|
||||
|
||||
val exportDir = File(context.cacheDir, "exports").apply { mkdirs() }
|
||||
val exportFile = File(exportDir, "vbhelper_character_$characterId.vitalwear")
|
||||
|
||||
@ -13,27 +13,7 @@ data class BitmapData (
|
||||
val bitmap: ByteArray,
|
||||
val width: Int,
|
||||
val height: Int
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as BitmapData
|
||||
|
||||
if (!bitmap.contentEquals(other.bitmap)) return false
|
||||
if (width != other.width) return false
|
||||
if (height != other.height) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = bitmap.contentHashCode()
|
||||
result = 31 * result + width
|
||||
result = 31 * result + height
|
||||
return result
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
data class ImageBitmapData(
|
||||
val imageBitmap: ImageBitmap,
|
||||
|
||||
@ -0,0 +1 @@
|
||||
|
||||
@ -17,21 +17,21 @@
|
||||
<string name="nav_adventure">アドベンチャー</string>
|
||||
<string name="nav_credits">クレジット</string>
|
||||
<string name="adventure_title">アドベンチャー</string>
|
||||
<string name="adventure_empty_state">No Data</string>
|
||||
<string name="adventure_empty_state">何もありません。</string>
|
||||
<string name="home_title">VB Helper</string>
|
||||
<string name="scan_secrets_not_imported">" APKの読み込みがされていません。設定から読み込をして下さい。 "</string>
|
||||
<string name="scan_title">デバイスをスキャン</string>
|
||||
<string name="scan_sent_dim_success">DIMの転送に成功しました。</string>
|
||||
<string name="scan_nfc_must_be_enabled">NFC機能を有効にして下さい。</string>
|
||||
<string name="settings_title">設定</string>
|
||||
<string name="scan_missing_secrets">公式アプリのAPKを読み込みして下さい。</string>
|
||||
<string name="scan_missing_secrets">必要なデータが不足しています。設定を開き、Vital ArenaのAPKを読み込んでください。</string>
|
||||
<string name="scan_sent_character_success">転送が成功しました。</string>
|
||||
<string name="scan_error_generic">エラー</string>
|
||||
<string name="settings_about_desc">このアプリについて</string>
|
||||
<string name="settings_export_data_title">データベースのエクスポート</string>
|
||||
<string name="settings_export_data_desc">データベースの書き出しをします。</string>
|
||||
<string name="settings_import_data_title">データベースのインポート</string>
|
||||
<string name="settings_import_data_desc">データベースの読み込みをします。</string>
|
||||
<string name="settings_export_data_title">データベースの書き出し</string>
|
||||
<string name="settings_export_data_desc">" データベースを書き出します。"</string>
|
||||
<string name="settings_import_data_title">データベースの読み込み</string>
|
||||
<string name="settings_import_data_desc">" データベースを読み込みます。"</string>
|
||||
<string name="credits_title">クレジット</string>
|
||||
<string name="battles_coming_soon">Coming soon</string>
|
||||
<string name="cards_my_cards_title">カードリスト</string>
|
||||
@ -42,7 +42,7 @@
|
||||
<string name="scan_vb_to_app">デバイスからアプリへ</string>
|
||||
<string name="scan_app_to_vb">アプリからデバイスへ</string>
|
||||
<string name="read_character_title">キャラクターを読み込みます。</string>
|
||||
<string name="read_character_prepare_device">デバイスを準備してください。</string>
|
||||
<string name="read_character_prepare_device">バイタルブレスを準備してください。</string>
|
||||
<string name="read_character_go_to_connect">準備が出来たら転送を押してください。</string>
|
||||
<string name="read_character_confirm">転送</string>
|
||||
<string name="card_adventure_missions_title">アドベンチャーミッション</string>
|
||||
@ -54,32 +54,31 @@
|
||||
<string name="storage_delete_character">削除</string>
|
||||
<string name="storage_close">閉じる</string>
|
||||
<string name="storage_character_image_description">キャラクター画像</string>
|
||||
<string name="storage_send_to_watch">デバイスへ転送</string>
|
||||
<string name="storage_send_to_vitalwear">VitalWearへ転送</string>
|
||||
<string name="storage_send_to_watch">転送</string>
|
||||
<string name="storage_set_active">選択</string>
|
||||
<string name="storage_send_on_adventure">アドベンチャーへ出発</string>
|
||||
<string name="scan_no_nfc_on_device">NFC機能が見つかりません。</string>
|
||||
<string name="scan_tag_not_vb">検出されたタグはバイタルブレスでは使用出来ません。</string>
|
||||
<string name="settings_section_nfc">NFC通信</string>
|
||||
<string name="settings_section_dim_bem">DiM / BEm管理</string>
|
||||
<string name="settings_section_nfc">NFC</string>
|
||||
<string name="settings_section_dim_bem">DiM / BEm</string>
|
||||
<string name="settings_section_data">データ管理</string>
|
||||
<string name="settings_import_apk_title">アプリのインポート</string>
|
||||
<string name="settings_import_apk_desc">公式アプリのAPKファイルを読み込みします。</string>
|
||||
<string name="settings_import_card_title">カードのインポート</string>
|
||||
<string name="settings_import_apk_title">アプリの読み込み</string>
|
||||
<string name="settings_import_apk_desc">" Vital Arena 2.1.0のAPKファイルを読み込みします。"</string>
|
||||
<string name="settings_import_card_title">カードの読み込み</string>
|
||||
<string name="settings_section_about">概要 / クレジット</string>
|
||||
<string name="dex_chara_fusions_button">ジョグレス</string>
|
||||
<string name="dex_chara_close_button">閉じる</string>
|
||||
<string name="settings_import_card_desc">Dim / BEm のデータファイルを読み込みします。</string>
|
||||
<string name="settings_import_card_desc">" Dim / BEm カードファイルを読み込みます。"</string>
|
||||
<string name="settings_credits_title">クレジット</string>
|
||||
<string name="settings_credits_desc">開発者について</string>
|
||||
<string name="settings_about_title">概要</string>
|
||||
<string name="beta_warning_message_main">このアプリは現在開発中です。\n今後のアップデートにより、保存されているデータ全ての削除が必要になる場合があります。\nその為、大切なデータの保存には使用しないようお願い致します。\nご不便をおかけして申し訳ございません。</string>
|
||||
<string name="beta_warning_message_main">" このアプリは現在アルファ版です。今後のアップデートにより保存されているデータの全てが削除される可能性がある為、大切なデータの保存はしないようにお願い致します。ご不便をおかけして申し訳ございません。 "</string>
|
||||
<string name="beta_warning_message_compatibility">" このアプリはオリジナルのVBおよびVHで動作するようになりました。 "</string>
|
||||
<string name="beta_warning_message_thanks">ご理解とご協力に感謝致します。\n開発チーム一同</string>
|
||||
<string name="beta_warning_message_thanks">" ご理解とご協力に感謝いたします。\n 開発チーム一同"</string>
|
||||
<string name="home_vbdim_vitals">バイタル</string>
|
||||
<string name="home_adventure_mission_finished">" 1人のキャラクターがアドベンチャーミッションを完了しました。 "</string>
|
||||
<string name="scan_secrets_not_initialized">" 初期化が出来ませんでした。もう一度試して下さい。 "</string>
|
||||
<string name="home_special_mission_delete_main">現在の進捗状況が失われます。本当にこのミッションを削除しますか?</string>
|
||||
<string name="home_special_mission_delete_main">現在の進捗状況が失われますが、本当にこのスペシャルミッションを削除しますか?</string>
|
||||
<string name="home_special_mission_delete_dismiss">閉じる</string>
|
||||
<string name="home_special_mission_delete_remove">削除</string>
|
||||
<string name="item_dialog_use">アイテム使用</string>
|
||||
@ -91,26 +90,25 @@
|
||||
<string name="obtained_item_you_also_got_credits">%1$d クレジットを獲得しました。</string>
|
||||
<string name="obtained_item_dismiss">閉じる</string>
|
||||
<string name="nav_dex">図鑑</string>
|
||||
<string name="credits_RedEyez_description">献身的なデバッグ作業を行って頂きました。</string>
|
||||
<string name="action_place_near_reader">デバイスを近づけて下さい。</string>
|
||||
<string name="action_place_near_reader">バイタルブレス本体を近くに置いて下さい。</string>
|
||||
<string name="action_cancel">キャンセル</string>
|
||||
<string name="card_view_discovered_characters">解放済みキャラクター</string>
|
||||
<string name="dex_chara_icon_description">キャラクターアイコン</string>
|
||||
<string name="dex_chara_name_icon_description">名前</string>
|
||||
<string name="credits_section_reverse_engineering">プログラム解析</string>
|
||||
<string name="credits_section_reverse_engineering">リバースエンジニアリング</string>
|
||||
<string name="credits_section_app_development">アプリケーション開発</string>
|
||||
<string name="credits_cyanic_description">ファームウェアの解析を行い、開発をサポートしてくれました。</string>
|
||||
<string name="credits_cfogrady_description">vb-lib-nfc開発および本アプリの開発に協力して頂きました。</string>
|
||||
<string name="credits_nacabaro_description">本アプリの開発をしました。</string>
|
||||
<string name="credits_lightheel_description">本アプリのサーバー含む対戦機能を開発して頂きました。現在も開発を継続して頂いています。</string>
|
||||
<string name="credits_shvstrz_description">本アプリのアイコンデザインをして頂きました。</string>
|
||||
<string name="credits_cyanic_description">" ファームウェアの解析を行い、開発をサポートしてくれました。"</string>
|
||||
<string name="credits_cfogrady_description">" vb-lib-nfc開発およびアプリの開発に協力して頂きました。"</string>
|
||||
<string name="credits_nacabaro_description">" アプリの開発をしました。"</string>
|
||||
<string name="credits_lightheel_description">" アプリのサーバー含む対戦機能を開発して頂きました。現在も開発を継続して頂いています。"</string>
|
||||
<string name="credits_shvstrz_description">" アプリのアイコンデザインをして頂きました。"</string>
|
||||
<string name="write_card_title">カード情報書き込み中</string>
|
||||
<string name="write_card_icon_description">カードアイコン</string>
|
||||
<string name="write_card_device_ready">デバイスの準備をして下さい。</string>
|
||||
<string name="write_card_required_card">%1$s カードが必要です。</string>
|
||||
<string name="write_card_confirm">転送</string>
|
||||
<string name="write_character_success">カードの読み込みが完了しました。</string>
|
||||
<string name="write_character_wait_ready">デバイスの準備をしてから確認を押して下さい。</string>
|
||||
<string name="write_character_success">" カードの読み込みが完了しました。"</string>
|
||||
<string name="write_character_wait_ready">" デバイスの準備をしてから確認を押して下さい。"</string>
|
||||
<string name="write_character_confirm">確認</string>
|
||||
<string name="home_vbdim_trophies">トロフィー</string>
|
||||
<string name="items_purchase_success">購入しました。</string>
|
||||
@ -121,10 +119,10 @@
|
||||
<string name="dex_chara_stats">HP: %1$d, BP: %2$d, AP: %3$d</string>
|
||||
<string name="dex_chara_stage_attribute_unknown">Stg: -, Atr: -</string>
|
||||
<string name="dex_chara_stats_unknown">HP: -, BP: -, AP: -</string>
|
||||
<string name="dex_chara_requirements">\n Tr: %1$d; Bt: %2$d; Vr: %3$d; Wr: %4$d%%; Ct: %5$dh</string>
|
||||
<string name="dex_chara_requirements">" Tr: %1$d; Bt: %2$d; Vr: %3$d; Wr: %4$d%%; Ct: %5$dh "</string>
|
||||
<string name="dex_chara_adventure_level">AdvLvl %1$d</string>
|
||||
<string name="storage_my_characters_title">キャラクターリスト</string>
|
||||
<string name="storage_nothing_to_see_here">No Data</string>
|
||||
<string name="storage_nothing_to_see_here">表示するデータはありません。</string>
|
||||
<string name="storage_in_adventure_toast">このキャラクターは冒険中です。</string>
|
||||
<string name="home_vbdim_next_timer">次のタイマー</string>
|
||||
<string name="home_vbdim_total_battle_win">総勝率 %</string>
|
||||
@ -145,17 +143,4 @@
|
||||
<string name="special_mission_steps_progress">歩数 %1$d 歩</string>
|
||||
<string name="special_mission_battles_progress">バトル %1$d 回</string>
|
||||
<string name="special_mission_wins_progress">勝利 %1$d 回</string>
|
||||
<string name="settings_companion_import_card_image_title">カードのインポート</string>
|
||||
<string name="companion_validation_connect_vb">デバイスに接続</string>
|
||||
<string name="companion_card_import_success">カードのインポートに成功しました。</string>
|
||||
<string name="companion_firmware_no_watch">デバイスが見つかりません。</string>
|
||||
<string name="companion_validation_insert_card">デバイスへカードを差し込んで下さい。</string>
|
||||
<string name="companion_validation_success">データチェックが完了しました。</string>
|
||||
<string name="companion_loading_select_firmware">ファームウェアファイルを選択</string>
|
||||
<string name="companion_firmware_sent_success">ファームウェアの送信が完了しました。</string>
|
||||
<string name="companion_logs_receive_failed">ログの受信に失敗しました。</string>
|
||||
<string name="companion_logs_failed_request">ログの要求に失敗しました。</string>
|
||||
<string name="companion_logs_warning">注意:ログの転送には時間がかかる場合があります。</string>
|
||||
<string name="settings_companion_send_watch_logs_title">ログの送信</string>
|
||||
<string name="companion_transfer_disabled_message">現在、転送は無効になっています。</string>
|
||||
</resources>
|
||||
@ -43,13 +43,13 @@
|
||||
Os segredos ainda não foram importados. Vá em Configurações e importe o APK.
|
||||
</string>
|
||||
|
||||
<string name="scan_title">Escanear um VB</string>
|
||||
<string name="scan_vb_to_app">VB para o app</string>
|
||||
<string name="scan_app_to_vb">App para o VB</string>
|
||||
<string name="scan_title">Escanear um Vital Bracelet</string>
|
||||
<string name="scan_vb_to_app">Vital Bracelet para o app</string>
|
||||
<string name="scan_app_to_vb">App para o Vital Bracelet</string>
|
||||
|
||||
<string name="scan_no_nfc_on_device">O dispositivo não possui NFC!</string>
|
||||
<string name="scan_tag_not_vb">A tag detectada não é do VB.</string>
|
||||
<string name="scan_missing_secrets">" Segredos ausentes. Vá em Configurações e importe o APK do app oficial. "</string>
|
||||
<string name="scan_tag_not_vb">A tag detectada não é do Vital Bracelet.</string>
|
||||
<string name="scan_missing_secrets">" Segredos ausentes. Vá em Configurações e importe o APK do Vital Arena. "</string>
|
||||
<string name="scan_sent_character_success">Personagem enviado com sucesso!</string>
|
||||
<string name="scan_error_generic">Ops!</string>
|
||||
<string name="scan_sent_dim_success">DIM enviado com sucesso!</string>
|
||||
@ -64,7 +64,7 @@
|
||||
|
||||
<string name="settings_import_apk_title">Importar APK</string>
|
||||
<string name="settings_import_apk_desc">
|
||||
Importar segredos do APK do app oficial
|
||||
Importar segredos do APK do Vital Arena 2.1.0
|
||||
</string>
|
||||
|
||||
<string name="settings_import_card_title">Importar card</string>
|
||||
@ -106,7 +106,7 @@
|
||||
Responsável pelo design do ícone do aplicativo em SVG.
|
||||
</string>
|
||||
|
||||
<string name="action_place_near_reader">Aproxime o seu VB do leitor...</string>
|
||||
<string name="action_place_near_reader">Aproxime o seu Vital Bracelet do leitor...</string>
|
||||
<string name="action_cancel">Cancelar</string>
|
||||
|
||||
<string name="read_character_title">Ler personagem</string>
|
||||
|
||||
@ -43,13 +43,13 @@
|
||||
Secrets not yet imported. Go to Settings and Import APK.
|
||||
</string>
|
||||
|
||||
<string name="scan_title">Scan a VB</string>
|
||||
<string name="scan_title">Scan a Vital Bracelet</string>
|
||||
<string name="scan_vb_to_app">Watch to VBH</string>
|
||||
<string name="scan_app_to_vb">VBH to Watch</string>
|
||||
|
||||
<string name="scan_no_nfc_on_device">No NFC on device!</string>
|
||||
<string name="scan_tag_not_vb">Tag detected is not VB</string>
|
||||
<string name="scan_missing_secrets">" Missing Secrets. Go to settings and import the official app APK. "</string>
|
||||
<string name="scan_missing_secrets">" Missing Secrets. Go to settings and import Vital Arena APK. "</string>
|
||||
<string name="scan_sent_character_success">Sent character successfully!</string>
|
||||
<string name="scan_error_generic">Whoops</string>
|
||||
<string name="scan_sent_dim_success">Sent DIM successfully!</string>
|
||||
@ -65,7 +65,7 @@
|
||||
|
||||
<string name="settings_import_apk_title">Import APK</string>
|
||||
<string name="settings_import_apk_desc">
|
||||
Import Secrets From the official app APK
|
||||
Import Secrets From Vital Arena APK
|
||||
</string>
|
||||
|
||||
<string name="settings_import_card_title">Import card</string>
|
||||
@ -109,7 +109,7 @@
|
||||
<string name="credits_RedEyez_description">
|
||||
Devout Debugger.
|
||||
</string>
|
||||
<string name="action_place_near_reader">Place your VB near the reader...</string>
|
||||
<string name="action_place_near_reader">Place your Vital Bracelet near the reader...</string>
|
||||
<string name="action_cancel">Cancel</string>
|
||||
|
||||
<string name="read_character_title">Read character</string>
|
||||
@ -220,10 +220,10 @@
|
||||
<string name="home_special_mission_delete_remove">Remove</string>
|
||||
|
||||
<string name="settings_companion_import_card_image_title">Import Card Image</string>
|
||||
<string name="companion_validation_connect_vb">Connect VB</string>
|
||||
<string name="companion_validation_connect_vb">Connect Vital Bracelet</string>
|
||||
<string name="companion_card_import_success">Card imported successfully!</string>
|
||||
<string name="companion_firmware_no_watch">No watch found!</string>
|
||||
<string name="companion_validation_insert_card">Insert card into VB</string>
|
||||
<string name="companion_validation_insert_card">Insert card into Vital Bracelet</string>
|
||||
<string name="companion_validation_success">Validation successful!</string>
|
||||
<string name="companion_loading_select_firmware">Select firmware file</string>
|
||||
<string name="companion_firmware_sent_success">Firmware sent successfully!</string>
|
||||
|
||||
@ -21,6 +21,13 @@ kotlin.code.style=official
|
||||
# resources declared in the library itself and none from the library's dependencies,
|
||||
# thereby reducing the size of the R class for that library
|
||||
android.nonTransitiveRClass=true
|
||||
android.defaults.buildfeatures.resvalues=true
|
||||
android.sdk.defaultTargetSdkToCompileSdkIfUnset=false
|
||||
android.enableAppCompileTimeRClass=false
|
||||
android.usesSdkInManifest.disallowed=false
|
||||
android.uniquePackageNames=false
|
||||
android.dependency.useConstraints=true
|
||||
android.r8.strictFullModeForKeepRules=false
|
||||
android.r8.optimizedResourceShrinking=false
|
||||
android.builtInKotlin=false
|
||||
android.newDsl=false
|
||||
@ -1,19 +1,19 @@
|
||||
[versions]
|
||||
agp = "9.2.1"
|
||||
datastore = "1.2.1"
|
||||
datastorePreferences = "1.2.1"
|
||||
kotlin = "2.4.0"
|
||||
coreKtx = "1.19.0"
|
||||
datastore = "1.2.0"
|
||||
datastorePreferences = "1.2.0"
|
||||
kotlin = "2.3.0"
|
||||
coreKtx = "1.17.0"
|
||||
junit = "4.13.2"
|
||||
junitVersion = "1.3.0"
|
||||
espressoCore = "3.7.0"
|
||||
lifecycleRuntimeKtx = "2.11.0"
|
||||
activityCompose = "1.13.0"
|
||||
composeBom = "2026.06.00"
|
||||
material = "1.14.0"
|
||||
navigationCompose = "2.9.8"
|
||||
protobufGradlePlugin = "0.10.0"
|
||||
protobufJavalite = "4.35.1"
|
||||
lifecycleRuntimeKtx = "2.10.0"
|
||||
activityCompose = "1.12.2"
|
||||
composeBom = "2026.01.00"
|
||||
material = "1.13.0"
|
||||
navigationCompose = "2.9.6"
|
||||
protobufGradlePlugin = "0.9.6"
|
||||
protobufJavalite = "4.33.4"
|
||||
roomRuntime = "2.8.4"
|
||||
vbNfcReader = "0.2.0-SNAPSHOT"
|
||||
dimReader = "2.1.0"
|
||||
@ -21,10 +21,10 @@ playServicesWearable = "20.0.1"
|
||||
kotlinxCoroutinesPlayServices = "1.11.0"
|
||||
timber = "5.0.1"
|
||||
tinylog = "2.7.0"
|
||||
retrofit = "3.0.0"
|
||||
gson = "2.14.0"
|
||||
okhttp = "5.4.0"
|
||||
ksp = "2.3.9"
|
||||
retrofit = "2.9.0"
|
||||
gson = "2.10.1"
|
||||
okhttp = "4.11.0"
|
||||
ksp = "2.3.2"
|
||||
|
||||
[libraries]
|
||||
androidx-compose-material = { module = "androidx.compose.material:material" }
|
||||
@ -50,6 +50,7 @@ androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-man
|
||||
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
|
||||
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
|
||||
material = { module = "com.google.android.material:material", version.ref = "material" }
|
||||
protobuf-gradle-plugin = { module = "com.google.protobuf:protobuf-gradle-plugin", version.ref = "protobufGradlePlugin" }
|
||||
protobuf-javalite = { module = "com.google.protobuf:protobuf-javalite", version.ref = "protobufJavalite" }
|
||||
vb-nfc-reader = { module = "com.github.cfogrady:vb-nfc-reader", version.ref = "vbNfcReader" }
|
||||
dim-reader = { module = "com.github.cfogrady:vb-dim-reader", version.ref = "dimReader" }
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
||||
#Tue Dec 24 10:55:57 UTC 2024
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@ -17,7 +17,6 @@ dependencyResolutionManagement {
|
||||
mavenLocal()
|
||||
google()
|
||||
mavenCentral()
|
||||
maven { url = uri("https://jitpack.io") }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user