Рефакторинг, платный боевой пропуск и задания вызова

This commit is contained in:
2025-05-19 17:48:07 +03:00
parent 9f1b7f3513
commit 4e00239a70
4 changed files with 131 additions and 20 deletions

2
.idea/misc.xml generated
View File

@ -4,7 +4,7 @@
<component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_23" project-jdk-name="24" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

2
.idea/vcs.xml generated
View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@ -4,10 +4,10 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.darkColorScheme
@ -17,18 +17,27 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import utils.DecimalField
import utils.SliderCard
import utils.SwitchCard
import utils.VSpace
import utils.parseInt
import kotlin.math.ceil
const val BATTLE_PASS_WEEKS = 13
const val BATTLE_PASS_DAYS = BATTLE_PASS_WEEKS * 7
const val BATTLE_PASS_MAX_LEVEL = 115
const val DAILY_TASKS_XP = 450
const val WEEKLY_REWARD_XP = 2250
const val WEEKLY_TASKS_XP = 1550
const val CHALLENGE_TASKS_XP = 1000
const val CHALLENGE_TASKS_FREE_NUMBER = 20
const val CHALLENGE_TASKS_PAID_NUMBER = 36
@Composable
@Preview
@ -46,18 +55,24 @@ fun App() {
var daysLeft by remember { mutableStateOf(0) }
val weeksLeft = ceil(daysLeft.toFloat() / 7).toInt()
var currentLevel by remember { mutableStateOf(0) }
var paidBattlePass by remember { mutableStateOf(false) }
var dailyTasksDays by remember { mutableStateOf(0) }
var weeklyRewardWeeks by remember { mutableStateOf(0) }
var weeklyTasksWeeks by remember { mutableStateOf(0) }
var challengeTasksNumber by remember { mutableStateOf(0) }
val xp = (
DAILY_TASKS_XP * dailyTasksDays
+ WEEKLY_REWARD_XP * weeklyRewardWeeks
+ WEEKLY_TASKS_XP * weeklyTasksWeeks
+ challengeTasksNumber / 3 * CHALLENGE_TASKS_XP
)
Column {
Column(
modifier = Modifier
.width(384.dp),
) {
Text(
text = "Исходные значения",
style = MaterialTheme.typography.headlineSmall,
@ -65,32 +80,50 @@ fun App() {
VSpace(16)
OutlinedTextField(
value = daysLeft.toString(),
DecimalField(
value = daysLeft,
onValueChange = {
daysLeft = parseInt(it)
},
label = {
Text("Дней до завершения события")
daysLeft = it
},
label = "Дней до завершения события",
)
VSpace(8)
OutlinedTextField(
value = currentLevel.toString(),
DecimalField(
value = currentLevel,
onValueChange = {
currentLevel = parseInt(it)
currentLevel = it
},
label = {
Text("Текущий уровень")
label = "Текущий уровень",
)
VSpace(16)
SwitchCard(
checked = paidBattlePass,
onCheckedChange = {
paidBattlePass = it
},
label = "Платный боевой пропуск",
description = "Вычисления будут выполняться из расчета, что боевой пропуск уже приобретен",
)
VSpace(32)
Text(
text = "${currentLevel + xp.toFloat() / 1000}/$BATTLE_PASS_MAX_LEVEL",
text = buildAnnotatedString {
append((currentLevel + xp.toFloat() / 1000).toString())
withStyle(
style = SpanStyle(
fontSize = MaterialTheme.typography.bodyLarge.fontSize,
),
) {
append("/$BATTLE_PASS_MAX_LEVEL")
}
},
style = MaterialTheme.typography.displaySmall,
)
}
@ -143,6 +176,20 @@ fun App() {
},
valueRange = 0..weeksLeft,
)
// TODO: место для заданий недели
SliderCard(
name = "Задания вызова",
value = challengeTasksNumber,
onValueChange = {
challengeTasksNumber = it
},
valueRange = 0..when (paidBattlePass) {
true -> ceil(CHALLENGE_TASKS_PAID_NUMBER.toFloat() / BATTLE_PASS_DAYS * daysLeft).toInt()
false -> ceil(CHALLENGE_TASKS_FREE_NUMBER.toFloat() / BATTLE_PASS_DAYS * daysLeft).toInt()
},
)
}
}
}

View File

@ -1,14 +1,21 @@
package utils
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Slider
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@ -21,9 +28,66 @@ fun VSpace(
)
}
fun parseInt(
value: String,
) = value.toIntOrNull() ?: 0
@Composable
fun DecimalField(
value: Int,
onValueChange: (Int) -> Unit,
label: String,
) {
OutlinedTextField(
value = value.toString(),
onValueChange = {
onValueChange(it.toIntOrNull() ?: 0)
},
modifier = Modifier
.fillMaxWidth(),
label = {
Text(label)
},
)
}
@Composable
fun SwitchCard(
checked: Boolean,
onCheckedChange: (Boolean) -> Unit,
label: String,
description: String? = null,
) {
OutlinedCard {
Column(
modifier = Modifier
.padding(
horizontal = 16.dp,
vertical = 12.dp,
),
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
Row(
modifier = Modifier
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = label,
style = MaterialTheme.typography.titleLarge,
)
Spacer(Modifier.width(16.dp))
Switch(
checked = checked,
onCheckedChange = onCheckedChange,
)
}
description?.let {
Text(
text = it,
style = MaterialTheme.typography.bodyMedium,
)
}
}
}
}
@Composable
fun SliderCard(