mirror of
https://github.com/nacabaro/vbhelper.git
synced 2026-06-05 22:02:54 +00:00
Updated client for attack battle loop.
This commit is contained in:
parent
a044d24f5f
commit
6c9d057917
@ -13,6 +13,20 @@ data class CharacterData(
|
||||
val laugeFileName: String
|
||||
)
|
||||
|
||||
data class CharacterDataResponse(
|
||||
val name: String,
|
||||
val type: String,
|
||||
val source_file: String,
|
||||
val collection: String,
|
||||
val unity_collection_id: String,
|
||||
val relative_path: String,
|
||||
val all_attributes: CharacterDataAttributes
|
||||
)
|
||||
|
||||
data class CharacterDataAttributes(
|
||||
val DataList: List<String>
|
||||
)
|
||||
|
||||
class AttackSpriteManager(private val context: Context) {
|
||||
private val gson = Gson()
|
||||
private val characterDataCache = mutableMapOf<String, CharacterData>()
|
||||
@ -21,9 +35,11 @@ class AttackSpriteManager(private val context: Context) {
|
||||
private val attackTexturesPath = "Battle_Sprites_Reference/extracted_assets/atk_textures"
|
||||
|
||||
fun getAttackSprite(characterId: String, isLarge: Boolean = false): Bitmap? {
|
||||
println("AttackSpriteManager: Getting attack sprite for characterId=$characterId, isLarge=$isLarge")
|
||||
try {
|
||||
// Get character data
|
||||
val characterData = getCharacterData(characterId) ?: return null
|
||||
println("AttackSpriteManager: Got character data: $characterData")
|
||||
|
||||
// Determine which attack file to use
|
||||
val attackFileName = if (isLarge) {
|
||||
@ -31,44 +47,99 @@ class AttackSpriteManager(private val context: Context) {
|
||||
} else {
|
||||
characterData.smalefilename
|
||||
}
|
||||
println("AttackSpriteManager: Attack filename = $attackFileName")
|
||||
|
||||
// Skip if no attack file
|
||||
if (attackFileName == "0") return null
|
||||
if (attackFileName == "0") {
|
||||
println("AttackSpriteManager: Skipping attack file (filename is '0')")
|
||||
return null
|
||||
}
|
||||
|
||||
// Load the attack sprite
|
||||
val attackFilePath = "$attackTexturesPath/$attackFileName.png"
|
||||
val attackFile = File(context.filesDir, attackFilePath)
|
||||
println("AttackSpriteManager: Attack file path = ${attackFile.absolutePath}")
|
||||
println("AttackSpriteManager: Attack file exists = ${attackFile.exists()}")
|
||||
|
||||
return if (attackFile.exists()) {
|
||||
BitmapFactory.decodeFile(attackFile.absolutePath)
|
||||
val bitmap = BitmapFactory.decodeFile(attackFile.absolutePath)
|
||||
println("AttackSpriteManager: Successfully loaded bitmap = ${bitmap != null}")
|
||||
bitmap
|
||||
} else {
|
||||
println("AttackSpriteManager: Attack file does not exist")
|
||||
null
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
println("AttackSpriteManager: Exception occurred: ${e.message}")
|
||||
e.printStackTrace()
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCharacterData(characterId: String): CharacterData? {
|
||||
println("AttackSpriteManager: Getting character data for characterId=$characterId")
|
||||
// Check cache first
|
||||
if (characterDataCache.containsKey(characterId)) {
|
||||
println("AttackSpriteManager: Found character data in cache")
|
||||
return characterDataCache[characterId]
|
||||
}
|
||||
|
||||
try {
|
||||
// Load character data from JSON file
|
||||
val characterDataFile = File(context.filesDir, "Battle_Sprites_Reference/extracted_digimon_stats/character_data/CharacterData.json")
|
||||
println("AttackSpriteManager: Character data file path = ${characterDataFile.absolutePath}")
|
||||
println("AttackSpriteManager: Character data file exists = ${characterDataFile.exists()}")
|
||||
|
||||
if (!characterDataFile.exists()) {
|
||||
return null
|
||||
println("AttackSpriteManager: Character data file does not exist, using default data")
|
||||
// For now, return a default character data
|
||||
val characterData = CharacterData(
|
||||
name = characterId,
|
||||
charaId = characterId,
|
||||
smalefilename = "atk_s_02", // Default small attack
|
||||
laugeFileName = "atk_l_04" // Default large attack
|
||||
)
|
||||
|
||||
characterDataCache[characterId] = characterData
|
||||
return characterData
|
||||
}
|
||||
|
||||
val jsonContent = characterDataFile.readText()
|
||||
// Parse the JSON and find the character with matching charaId
|
||||
// This is a simplified version - you'll need to parse the actual JSON structure
|
||||
println("AttackSpriteManager: JSON content length = ${jsonContent.length}")
|
||||
|
||||
// For now, return a default character data
|
||||
// Parse the JSON response
|
||||
val response = gson.fromJson(jsonContent, CharacterDataResponse::class.java)
|
||||
|
||||
// Search through the DataList for the matching characterId
|
||||
for (characterString in response.all_attributes.DataList) {
|
||||
// Extract charaId from the string format: "<UnknownObject<Character> id=0, charaId='dim000_mon03', ...>"
|
||||
val charaIdMatch = Regex("charaId='([^']+)'").find(characterString)
|
||||
if (charaIdMatch != null) {
|
||||
val foundCharaId = charaIdMatch.groupValues[1]
|
||||
if (foundCharaId == characterId) {
|
||||
// Extract smalefilename and laugeFileName
|
||||
val smallFileMatch = Regex("smalefilename='([^']+)'").find(characterString)
|
||||
val largeFileMatch = Regex("laugeFileName='([^']+)'").find(characterString)
|
||||
|
||||
val smallFileName = smallFileMatch?.groupValues?.get(1) ?: "0"
|
||||
val largeFileName = largeFileMatch?.groupValues?.get(1) ?: "0"
|
||||
|
||||
val characterData = CharacterData(
|
||||
name = characterId,
|
||||
charaId = characterId,
|
||||
smalefilename = smallFileName,
|
||||
laugeFileName = largeFileName
|
||||
)
|
||||
|
||||
characterDataCache[characterId] = characterData
|
||||
println("AttackSpriteManager: Found character data: $characterData")
|
||||
return characterData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If character not found, return default data
|
||||
println("AttackSpriteManager: Character not found in JSON, using default data")
|
||||
val characterData = CharacterData(
|
||||
name = characterId,
|
||||
charaId = characterId,
|
||||
@ -77,9 +148,11 @@ class AttackSpriteManager(private val context: Context) {
|
||||
)
|
||||
|
||||
characterDataCache[characterId] = characterData
|
||||
println("AttackSpriteManager: Created default character data: $characterData")
|
||||
return characterData
|
||||
|
||||
} catch (e: Exception) {
|
||||
println("AttackSpriteManager: Exception in getCharacterData: ${e.message}")
|
||||
e.printStackTrace()
|
||||
return null
|
||||
}
|
||||
|
||||
@ -9,16 +9,26 @@ class SpriteFileManager(private val context: Context) {
|
||||
|
||||
fun copySpriteFilesToInternalStorage() {
|
||||
try {
|
||||
// Create the base directory
|
||||
val baseDir = File(context.filesDir, "Battle_Sprites_Reference/extracted_assets")
|
||||
if (!baseDir.exists()) {
|
||||
baseDir.mkdirs()
|
||||
// Create the base directory for extracted_assets
|
||||
val extractedAssetsDir = File(context.filesDir, "Battle_Sprites_Reference/extracted_assets")
|
||||
if (!extractedAssetsDir.exists()) {
|
||||
extractedAssetsDir.mkdirs()
|
||||
}
|
||||
|
||||
// Copy files from assets to internal storage
|
||||
copyAssetDirectory("Battle_Sprites_Reference/extracted_assets", baseDir)
|
||||
// Create the base directory for extracted_digimon_stats
|
||||
val extractedStatsDir = File(context.filesDir, "Battle_Sprites_Reference/extracted_digimon_stats")
|
||||
if (!extractedStatsDir.exists()) {
|
||||
extractedStatsDir.mkdirs()
|
||||
}
|
||||
|
||||
println("Sprite files copied successfully to: ${baseDir.absolutePath}")
|
||||
// Copy extracted_assets files from assets to internal storage
|
||||
copyAssetDirectory("Battle_Sprites_Reference/extracted_assets", extractedAssetsDir)
|
||||
|
||||
// Copy extracted_digimon_stats files from assets to internal storage
|
||||
copyAssetDirectory("Battle_Sprites_Reference/extracted_digimon_stats", extractedStatsDir)
|
||||
|
||||
println("Sprite files copied successfully to: ${extractedAssetsDir.absolutePath}")
|
||||
println("Stats files copied successfully to: ${extractedStatsDir.absolutePath}")
|
||||
|
||||
} catch (e: Exception) {
|
||||
println("Error copying sprite files: ${e.message}")
|
||||
@ -74,7 +84,12 @@ class SpriteFileManager(private val context: Context) {
|
||||
}
|
||||
|
||||
fun checkSpriteFilesExist(): Boolean {
|
||||
val baseDir = File(context.filesDir, "Battle_Sprites_Reference/extracted_assets")
|
||||
return baseDir.exists() && baseDir.listFiles()?.isNotEmpty() == true
|
||||
val extractedAssetsDir = File(context.filesDir, "Battle_Sprites_Reference/extracted_assets")
|
||||
val extractedStatsDir = File(context.filesDir, "Battle_Sprites_Reference/extracted_digimon_stats")
|
||||
|
||||
val assetsExist = extractedAssetsDir.exists() && extractedAssetsDir.listFiles()?.isNotEmpty() == true
|
||||
val statsExist = extractedStatsDir.exists() && extractedStatsDir.listFiles()?.isNotEmpty() == true
|
||||
|
||||
return assetsExist && statsExist
|
||||
}
|
||||
}
|
||||
@ -24,11 +24,13 @@ fun AttackSpriteImage(
|
||||
val context = LocalContext.current
|
||||
|
||||
LaunchedEffect(characterId, isLarge) {
|
||||
println("AttackSpriteImage: Loading attack sprite for characterId=$characterId, isLarge=$isLarge")
|
||||
coroutineScope.launch {
|
||||
val attackSpriteManager = AttackSpriteManager(context)
|
||||
val loadedBitmap = withContext(Dispatchers.IO) {
|
||||
attackSpriteManager.getAttackSprite(characterId, isLarge)
|
||||
}
|
||||
println("AttackSpriteImage: Loaded bitmap = ${loadedBitmap != null}")
|
||||
bitmap = loadedBitmap
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,6 +196,7 @@ fun BattleScreen(
|
||||
playerName: String = "Player",
|
||||
opponentName: String = "Opponent",
|
||||
activeCharacter: APIBattleCharacter? = null,
|
||||
opponentCharacter: APIBattleCharacter? = null,
|
||||
onBattleComplete: (String?) -> Unit = {},
|
||||
onExitBattle: () -> Unit = {}
|
||||
) {
|
||||
@ -232,31 +233,52 @@ fun BattleScreen(
|
||||
}
|
||||
}
|
||||
|
||||
// Opponent AI - automatically attack back after player attack
|
||||
LaunchedEffect(battleSystem.currentView) {
|
||||
if (battleSystem.currentView == 1 && !battleSystem.isAttacking) {
|
||||
// Wait a bit before opponent attacks
|
||||
delay(1000)
|
||||
if (battleSystem.currentView == 1 && !battleSystem.isBattleOver()) {
|
||||
println("Opponent attacking back!")
|
||||
battleSystem.startOpponentAttack()
|
||||
// Apply damage to player
|
||||
battleSystem.applyDamage(true, 15f) // Player takes damage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(Color.Black)
|
||||
) {
|
||||
println("Current battle view: ${battleSystem.currentView}")
|
||||
when (battleSystem.currentView) {
|
||||
0 -> PlayerBattleView(
|
||||
battleSystem = battleSystem,
|
||||
stage = stage,
|
||||
playerName = playerName,
|
||||
attackAnimationProgress = animationProgress,
|
||||
onAttackClick = {
|
||||
battleSystem.startPlayerAttack()
|
||||
// Apply damage after animation
|
||||
battleSystem.applyDamage(false, 20f) // Opponent takes damage
|
||||
},
|
||||
activeCharacter = activeCharacter
|
||||
)
|
||||
1 -> OpponentBattleView(
|
||||
battleSystem = battleSystem,
|
||||
stage = stage,
|
||||
opponentName = opponentName,
|
||||
attackAnimationProgress = animationProgress,
|
||||
activeCharacter = activeCharacter
|
||||
)
|
||||
0 -> {
|
||||
println("Showing PlayerBattleView")
|
||||
PlayerBattleView(
|
||||
battleSystem = battleSystem,
|
||||
stage = stage,
|
||||
playerName = playerName,
|
||||
attackAnimationProgress = animationProgress,
|
||||
onAttackClick = {
|
||||
battleSystem.startPlayerAttack()
|
||||
// Apply damage after animation
|
||||
battleSystem.applyDamage(false, 20f) // Opponent takes damage
|
||||
},
|
||||
activeCharacter = activeCharacter
|
||||
)
|
||||
}
|
||||
1 -> {
|
||||
println("Showing OpponentBattleView")
|
||||
OpponentBattleView(
|
||||
battleSystem = battleSystem,
|
||||
stage = stage,
|
||||
opponentName = opponentName,
|
||||
attackAnimationProgress = animationProgress,
|
||||
activeCharacter = opponentCharacter
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Exit button
|
||||
@ -330,7 +352,7 @@ fun PlayerBattleView(
|
||||
) {
|
||||
SpriteImage(
|
||||
spriteName = "00", // The sprite number (00, 01, 02, etc.)
|
||||
atlasName = when (stage) {
|
||||
atlasName = activeCharacter?.charaId ?: when (stage) {
|
||||
"rookie" -> "dim000_mon01"
|
||||
"champion" -> "dim012_mon04"
|
||||
"ultimate" -> "dim137_mon09"
|
||||
@ -401,8 +423,12 @@ fun PlayerBattleView(
|
||||
)
|
||||
|
||||
// Attack button
|
||||
println("PlayerBattleView: Attack button enabled = ${battleSystem.isAttackButtonEnabled}")
|
||||
Button(
|
||||
onClick = onAttackClick,
|
||||
onClick = {
|
||||
println("Attack button clicked!")
|
||||
onAttackClick()
|
||||
},
|
||||
enabled = battleSystem.isAttackButtonEnabled,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
@ -475,7 +501,7 @@ fun OpponentBattleView(
|
||||
) {
|
||||
SpriteImage(
|
||||
spriteName = "00", // The sprite number (00, 01, 02, etc.)
|
||||
atlasName = when (stage) {
|
||||
atlasName = activeCharacter?.charaId ?: when (stage) {
|
||||
"rookie" -> "dim000_mon01"
|
||||
"champion" -> "dim012_mon04"
|
||||
"ultimate" -> "dim137_mon09"
|
||||
@ -537,6 +563,7 @@ fun BattlesScreen() {
|
||||
var opponentsList by remember { mutableStateOf(ArrayList<APIBattleCharacter>()) }
|
||||
|
||||
var activeCharacter by remember { mutableStateOf<APIBattleCharacter?>(null) }
|
||||
var selectedOpponent by remember { mutableStateOf<APIBattleCharacter?>(null) }
|
||||
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
var selectedStage by remember { mutableStateOf("") }
|
||||
@ -835,6 +862,7 @@ fun BattlesScreen() {
|
||||
Button(
|
||||
onClick = {
|
||||
activeCharacter?.let {
|
||||
selectedOpponent = opponent
|
||||
RetrofitHelper().getPVPWinner(context, 0, 2, it.name, 0, 0, opponent.name, 0) { apiResult ->
|
||||
currentView = "battle-main"
|
||||
}
|
||||
@ -872,6 +900,7 @@ fun BattlesScreen() {
|
||||
Button(
|
||||
onClick = {
|
||||
activeCharacter?.let {
|
||||
selectedOpponent = opponent
|
||||
RetrofitHelper().getPVPWinner(context, 0, 2, it.name, 1, 0, opponent.name, 1) { apiResult ->
|
||||
currentView = "battle-main"
|
||||
}
|
||||
@ -909,6 +938,7 @@ fun BattlesScreen() {
|
||||
Button(
|
||||
onClick = {
|
||||
activeCharacter?.let {
|
||||
selectedOpponent = opponent
|
||||
RetrofitHelper().getPVPWinner(context, 0, 2, it.name, 2, 0, opponent.name, 2) { apiResult ->
|
||||
currentView = "battle-main"
|
||||
}
|
||||
@ -946,6 +976,7 @@ fun BattlesScreen() {
|
||||
Button(
|
||||
onClick = {
|
||||
activeCharacter?.let {
|
||||
selectedOpponent = opponent
|
||||
RetrofitHelper().getPVPWinner(context, 0, 2, it.name, 3, 0, opponent.name, 3) { apiResult ->
|
||||
currentView = "battle-main"
|
||||
}
|
||||
@ -970,35 +1001,47 @@ fun BattlesScreen() {
|
||||
}
|
||||
|
||||
"battle-main" -> {
|
||||
var battleSystem by remember { mutableStateOf(ArenaBattleSystem()) }
|
||||
var currentStage by remember { mutableStateOf("rookie") }
|
||||
|
||||
// Initialize battle with character stats
|
||||
LaunchedEffect(activeCharacter) {
|
||||
activeCharacter?.let { character ->
|
||||
battleSystem.initializeBattle(
|
||||
playerHP = character.currentHp.toFloat(),
|
||||
opponentHP = character.currentHp.toFloat(),
|
||||
playerMaxHP = character.baseHp.toFloat(),
|
||||
opponentMaxHP = character.baseHp.toFloat()
|
||||
)
|
||||
}
|
||||
val battleSystem = remember { ArenaBattleSystem() }
|
||||
|
||||
// Determine the current stage based on the character's stage
|
||||
val currentStage = when (activeCharacter?.stage) {
|
||||
0 -> "rookie"
|
||||
1 -> "champion"
|
||||
2 -> "ultimate"
|
||||
3 -> "mega"
|
||||
else -> "rookie"
|
||||
}
|
||||
|
||||
BattleScreen(
|
||||
battleSystem = battleSystem,
|
||||
stage = currentStage,
|
||||
playerName = activeCharacter?.name ?: "Player",
|
||||
opponentName = "Opponent",
|
||||
activeCharacter = activeCharacter,
|
||||
onBattleComplete = { winner ->
|
||||
// Handle battle completion
|
||||
currentView = "battle-results"
|
||||
},
|
||||
onExitBattle = {
|
||||
currentView = "main"
|
||||
}
|
||||
)
|
||||
|
||||
// Initialize battle with character stats
|
||||
LaunchedEffect(activeCharacter, selectedOpponent) {
|
||||
activeCharacter?.let { playerCharacter ->
|
||||
selectedOpponent?.let { opponentCharacter ->
|
||||
println("Initializing battle with player: ${playerCharacter.name}, opponent: ${opponentCharacter.name}")
|
||||
battleSystem.initializeBattle(
|
||||
playerHP = playerCharacter.currentHp.toFloat(),
|
||||
opponentHP = opponentCharacter.currentHp.toFloat(),
|
||||
playerMaxHP = playerCharacter.baseHp.toFloat(),
|
||||
opponentMaxHP = opponentCharacter.baseHp.toFloat()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BattleScreen(
|
||||
battleSystem = battleSystem,
|
||||
stage = currentStage,
|
||||
playerName = activeCharacter?.name ?: "Player",
|
||||
opponentName = selectedOpponent?.name ?: "Opponent",
|
||||
activeCharacter = activeCharacter,
|
||||
opponentCharacter = selectedOpponent,
|
||||
onBattleComplete = { winner ->
|
||||
println("Battle complete! Winner: $winner")
|
||||
currentView = "battle-results"
|
||||
},
|
||||
onExitBattle = {
|
||||
currentView = "main"
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
"battle-results" -> {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user