Рефакторинг, платный боевой пропуск и задания вызова
This commit is contained in:
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@ -4,7 +4,7 @@
|
|||||||
<component name="FrameworkDetectionExcludesConfiguration">
|
<component name="FrameworkDetectionExcludesConfiguration">
|
||||||
<file type="web" url="file://$PROJECT_DIR$" />
|
<file type="web" url="file://$PROJECT_DIR$" />
|
||||||
</component>
|
</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" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
2
.idea/vcs.xml
generated
2
.idea/vcs.xml
generated
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
<mapping directory="" vcs="Git" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
@ -4,10 +4,10 @@ import androidx.compose.foundation.layout.Column
|
|||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.OutlinedTextField
|
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.darkColorScheme
|
import androidx.compose.material3.darkColorScheme
|
||||||
@ -17,18 +17,27 @@ import androidx.compose.runtime.mutableStateOf
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
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.unit.dp
|
||||||
import androidx.compose.ui.window.Window
|
import androidx.compose.ui.window.Window
|
||||||
import androidx.compose.ui.window.application
|
import androidx.compose.ui.window.application
|
||||||
|
import utils.DecimalField
|
||||||
import utils.SliderCard
|
import utils.SliderCard
|
||||||
|
import utils.SwitchCard
|
||||||
import utils.VSpace
|
import utils.VSpace
|
||||||
import utils.parseInt
|
|
||||||
import kotlin.math.ceil
|
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 BATTLE_PASS_MAX_LEVEL = 115
|
||||||
const val DAILY_TASKS_XP = 450
|
const val DAILY_TASKS_XP = 450
|
||||||
const val WEEKLY_REWARD_XP = 2250
|
const val WEEKLY_REWARD_XP = 2250
|
||||||
const val WEEKLY_TASKS_XP = 1550
|
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
|
@Composable
|
||||||
@Preview
|
@Preview
|
||||||
@ -46,18 +55,24 @@ fun App() {
|
|||||||
var daysLeft by remember { mutableStateOf(0) }
|
var daysLeft by remember { mutableStateOf(0) }
|
||||||
val weeksLeft = ceil(daysLeft.toFloat() / 7).toInt()
|
val weeksLeft = ceil(daysLeft.toFloat() / 7).toInt()
|
||||||
var currentLevel by remember { mutableStateOf(0) }
|
var currentLevel by remember { mutableStateOf(0) }
|
||||||
|
var paidBattlePass by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
var dailyTasksDays by remember { mutableStateOf(0) }
|
var dailyTasksDays by remember { mutableStateOf(0) }
|
||||||
var weeklyRewardWeeks by remember { mutableStateOf(0) }
|
var weeklyRewardWeeks by remember { mutableStateOf(0) }
|
||||||
var weeklyTasksWeeks by remember { mutableStateOf(0) }
|
var weeklyTasksWeeks by remember { mutableStateOf(0) }
|
||||||
|
var challengeTasksNumber by remember { mutableStateOf(0) }
|
||||||
|
|
||||||
val xp = (
|
val xp = (
|
||||||
DAILY_TASKS_XP * dailyTasksDays
|
DAILY_TASKS_XP * dailyTasksDays
|
||||||
+ WEEKLY_REWARD_XP * weeklyRewardWeeks
|
+ WEEKLY_REWARD_XP * weeklyRewardWeeks
|
||||||
+ WEEKLY_TASKS_XP * weeklyTasksWeeks
|
+ WEEKLY_TASKS_XP * weeklyTasksWeeks
|
||||||
|
+ challengeTasksNumber / 3 * CHALLENGE_TASKS_XP
|
||||||
)
|
)
|
||||||
|
|
||||||
Column {
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.width(384.dp),
|
||||||
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = "Исходные значения",
|
text = "Исходные значения",
|
||||||
style = MaterialTheme.typography.headlineSmall,
|
style = MaterialTheme.typography.headlineSmall,
|
||||||
@ -65,32 +80,50 @@ fun App() {
|
|||||||
|
|
||||||
VSpace(16)
|
VSpace(16)
|
||||||
|
|
||||||
OutlinedTextField(
|
DecimalField(
|
||||||
value = daysLeft.toString(),
|
value = daysLeft,
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
daysLeft = parseInt(it)
|
daysLeft = it
|
||||||
},
|
|
||||||
label = {
|
|
||||||
Text("Дней до завершения события")
|
|
||||||
},
|
},
|
||||||
|
label = "Дней до завершения события",
|
||||||
)
|
)
|
||||||
|
|
||||||
VSpace(8)
|
VSpace(8)
|
||||||
|
|
||||||
OutlinedTextField(
|
DecimalField(
|
||||||
value = currentLevel.toString(),
|
value = currentLevel,
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
currentLevel = parseInt(it)
|
currentLevel = it
|
||||||
},
|
},
|
||||||
label = {
|
label = "Текущий уровень",
|
||||||
Text("Текущий уровень")
|
)
|
||||||
|
|
||||||
|
VSpace(16)
|
||||||
|
|
||||||
|
SwitchCard(
|
||||||
|
checked = paidBattlePass,
|
||||||
|
onCheckedChange = {
|
||||||
|
paidBattlePass = it
|
||||||
},
|
},
|
||||||
|
label = "Платный боевой пропуск",
|
||||||
|
description = "Вычисления будут выполняться из расчета, что боевой пропуск уже приобретен",
|
||||||
)
|
)
|
||||||
|
|
||||||
VSpace(32)
|
VSpace(32)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Text(
|
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,
|
style = MaterialTheme.typography.displaySmall,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -143,6 +176,20 @@ fun App() {
|
|||||||
},
|
},
|
||||||
valueRange = 0..weeksLeft,
|
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()
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,21 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.OutlinedCard
|
import androidx.compose.material3.OutlinedCard
|
||||||
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.Slider
|
import androidx.compose.material3.Slider
|
||||||
|
import androidx.compose.material3.Switch
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
@ -21,9 +28,66 @@ fun VSpace(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun parseInt(
|
@Composable
|
||||||
value: String,
|
fun DecimalField(
|
||||||
) = value.toIntOrNull() ?: 0
|
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
|
@Composable
|
||||||
fun SliderCard(
|
fun SliderCard(
|
||||||
|
Reference in New Issue
Block a user