Skip to content

Commit

Permalink
Auto Servant Level (#1748)
Browse files Browse the repository at this point in the history
Co-authored-by: arthur <[email protected]>
Co-authored-by: reconman <[email protected]>
  • Loading branch information
3 people authored Jan 14, 2024
1 parent 997d624 commit 84be9f9
Show file tree
Hide file tree
Showing 52 changed files with 877 additions and 15 deletions.
File renamed without changes
Binary file added app/src/main/assets/En/execute.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/En/ok.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/En/servant_auto_select.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/En/servant_max_level.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/Jp/execute.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/Jp/ok.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/Jp/servant_auto_select.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/Tw/close.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/Tw/ok.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/Tw/servant_auto_select.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ interface ScriptEntryPoint {
fun supportImageMaker(): SupportImageMaker
fun ceBomb(): AutoCEBomb

fun servantLevel(): AutoServantLevel

fun autoDetect(): AutoDetect
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ class ScriptLauncherResponseHandler @Inject constructor(
is ScriptLauncherResponse.Battle -> {
ScriptModeEnum.Battle
}

is ScriptLauncherResponse.ServantEnhancement -> {
ScriptModeEnum.ServantLevel
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import io.github.fate_grand_automata.scripts.entrypoints.AutoCEBomb
import io.github.fate_grand_automata.scripts.entrypoints.AutoFriendGacha
import io.github.fate_grand_automata.scripts.entrypoints.AutoGiftBox
import io.github.fate_grand_automata.scripts.entrypoints.AutoLottery
import io.github.fate_grand_automata.scripts.entrypoints.AutoServantLevel
import io.github.fate_grand_automata.scripts.entrypoints.SupportImageMaker
import io.github.fate_grand_automata.scripts.enums.GameServer
import io.github.fate_grand_automata.scripts.enums.ScriptModeEnum
Expand Down Expand Up @@ -200,6 +201,39 @@ class ScriptManager @Inject constructor(

showBattleExit(service, e)
}
is AutoServantLevel.ExitException -> {
val msg = when (val reason = e.reason) {
AutoServantLevel.ExitReason.NoServantSelected ->
context.getString(R.string.servant_enhancement_none_selected)

is AutoServantLevel.ExitReason.Unexpected -> {
e.let {
"${context.getString(R.string.unexpected_error)}: ${reason.exception.message}"
}
}

AutoServantLevel.ExitReason.MaxLevelAchieved ->
context.getString(R.string.servant_enhancement_max_level)

AutoServantLevel.ExitReason.NoEmbersOrQPLeft ->
context.getString(R.string.servant_enhancement_no_embers_or_qp_left)

AutoServantLevel.ExitReason.Abort ->
context.getString(R.string.servant_enhancement_aborted)

AutoServantLevel.ExitReason.RedirectAscension ->
context.getString(R.string.servant_enhancement_redirect_ascension_success)
AutoServantLevel.ExitReason.RedirectGrail ->
context.getString(R.string.servant_enhancement_redirect_grail_success)

AutoServantLevel.ExitReason.UnableToPerformAscension ->
context.getString(R.string.servant_enhancement_perform_ascension_failed)

AutoServantLevel.ExitReason.NotImplementedForServer ->
context.getString(R.string.servant_enhancement_not_implemented)
}
messageBox.show(scriptExitedString, msg)
}

is ScriptAbortException -> {
// user aborted. do nothing
Expand Down Expand Up @@ -243,6 +277,7 @@ class ScriptManager @Inject constructor(
ScriptModeEnum.PresentBox -> entryPoint.giftBox()
ScriptModeEnum.SupportImageMaker -> entryPoint.supportImageMaker()
ScriptModeEnum.CEBomb -> entryPoint.ceBomb()
ScriptModeEnum.ServantLevel -> entryPoint.servantLevel()
}

enum class PauseAction {
Expand Down Expand Up @@ -388,7 +423,8 @@ class ScriptManager @Inject constructor(
continuation.resume(it)
dialog?.dismiss()
},
prefs = preferences
prefs = preferences,
prefsCore = prefsCore
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import com.google.gson.Gson
import dagger.hilt.android.lifecycle.HiltViewModel
import io.github.fate_grand_automata.R
import io.github.fate_grand_automata.prefs.core.BattleConfigCore
import io.github.fate_grand_automata.prefs.core.PrefsCore
import io.github.fate_grand_automata.scripts.prefs.IBattleConfig
import io.github.fate_grand_automata.scripts.prefs.IPreferences
import io.github.fate_grand_automata.ui.skill_maker.SkillMakerModel
Expand All @@ -23,7 +22,6 @@ import javax.inject.Inject
class BattleConfigScreenViewModel @Inject constructor(
val prefs: IPreferences,
val battleConfig: IBattleConfig,
val prefsCore: PrefsCore,
val battleConfigCore: BattleConfigCore
) : ViewModel() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import io.github.fate_grand_automata.R
import io.github.fate_grand_automata.prefs.core.PrefsCore
import io.github.fate_grand_automata.scripts.enums.ScriptModeEnum
import io.github.fate_grand_automata.scripts.prefs.IPreferences
import io.github.fate_grand_automata.ui.FgaScreen
Expand All @@ -20,7 +21,8 @@ import io.github.fate_grand_automata.ui.FgaScreen
fun ScriptLauncher(
scriptMode: ScriptModeEnum,
onResponse: (ScriptLauncherResponse) -> Unit,
prefs: IPreferences
prefs: IPreferences,
prefsCore: PrefsCore
) {
FgaScreen {
Column(
Expand All @@ -37,6 +39,7 @@ fun ScriptLauncher(
ScriptModeEnum.Lottery -> lotteryLauncher(prefs, modifier)
ScriptModeEnum.PresentBox -> giftBoxLauncher(prefs, modifier)
ScriptModeEnum.CEBomb -> ceBombLauncher(prefs, modifier)
ScriptModeEnum.ServantLevel -> servantLevelLauncher(prefsCore.servantEnhancement, modifier)
}

Divider()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.github.fate_grand_automata.ui.launcher

sealed class ScriptLauncherResponse {
object Cancel : ScriptLauncherResponse()
data object Cancel : ScriptLauncherResponse()
data class FP(val limit: Int?) : ScriptLauncherResponse()
data class Lottery(
val giftBox: GiftBox?
Expand All @@ -13,8 +13,10 @@ sealed class ScriptLauncherResponse {
) : ScriptLauncherResponse()

data class CEBomb(val targetRarity: Int) : ScriptLauncherResponse()
object SupportImageMaker : ScriptLauncherResponse()
object Battle : ScriptLauncherResponse()
data object SupportImageMaker : ScriptLauncherResponse()
data object Battle : ScriptLauncherResponse()

data object ServantEnhancement : ScriptLauncherResponse()
}

class ScriptLauncherResponseBuilder(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
package io.github.fate_grand_automata.ui.launcher

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
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.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Checkbox
import androidx.compose.material3.Divider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import io.github.fate_grand_automata.R
import io.github.fate_grand_automata.prefs.core.ServantEnhancementPrefsCore
import io.github.fate_grand_automata.ui.VerticalDivider
import io.github.fate_grand_automata.ui.prefs.remember


@Composable
fun servantLevelLauncher(
servantEnhancementPrefsCore: ServantEnhancementPrefsCore,
modifier: Modifier = Modifier
): ScriptLauncherResponseBuilder {
var shouldRedirectAscension by servantEnhancementPrefsCore.shouldRedirectAscension.remember()

var shouldPerformAscension by servantEnhancementPrefsCore.shouldPerformAscension.remember()

var shouldRedirectGrail by servantEnhancementPrefsCore.shouldRedirectGrail.remember()

LazyColumn(
modifier = modifier
.padding(horizontal = 16.dp)
.padding(top = 5.dp)
) {
stickyHeader {
Column(
modifier = Modifier
.fillMaxWidth()
.background(
color = MaterialTheme.colorScheme.background
)
) {
Text(
text = stringResource(id = R.string.servant_enhancement),
style = MaterialTheme.typography.headlineSmall
)
Divider()
}
}
item {
Text(
text = stringResource(R.string.note),
style = MaterialTheme.typography.bodyLarge,
fontWeight = FontWeight.Bold
)
}
item {
Text(
text = stringResource(id = R.string.servert_enhancement_warning_notice),
style = MaterialTheme.typography.bodyMedium,
textAlign = TextAlign.Justify
)
}
item {
Divider()
}

item {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
){
RowTextCheckBox(
modifier = Modifier.weight(1f),
text = stringResource(R.string.servant_enhancement_redirect_ascension_question),
status = shouldRedirectAscension,
onStatusChange = {
shouldRedirectAscension = it
}
)
VerticalDivider()

Column(
modifier = Modifier
.weight(1f),
verticalArrangement = Arrangement.Center,

) {
RowTextCheckBox(
text = stringResource(R.string.servant_enhancement_perform_ascension_question),
status = shouldPerformAscension,
onStatusChange = {
shouldPerformAscension = it
}
)
Text(
stringResource(R.string.servant_enhancement_perform_ascension_warning),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.secondary
)
}
}
}
item {
Divider(
modifier = Modifier.padding(vertical = 5.dp)
)
}
item {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
){
RowTextCheckBox(
modifier = Modifier
.weight(1f),
text = stringResource(R.string.servant_enhancement_redirect_grail),
status = shouldRedirectGrail,
onStatusChange = {
shouldRedirectGrail = it
}
)
VerticalDivider()
Spacer(modifier = Modifier.weight(1f))
}
}
}


return ScriptLauncherResponseBuilder(
canBuild = { true },
build = {
ScriptLauncherResponse.ServantEnhancement
}
)
}

@Composable
private fun RowTextCheckBox(
modifier: Modifier = Modifier,
status: Boolean,
text: String,
onStatusChange: (Boolean) -> Unit,
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
modifier = modifier
.clickable { onStatusChange(!status) }
) {
Text(
text,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.secondary,
textAlign = TextAlign.Justify,
modifier = Modifier.weight(1f)
)

Checkbox(
checked = status,
onCheckedChange = { onStatusChange(it) }
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class ImageLoader @Inject constructor(
Images.Support -> "support.png"
Images.ServantCheckSupport -> "servant_check_support.png"
Images.BattleMenu -> "battle_menu.png"
Images.CEEnhance -> "ce_enhance.png"
Images.EmptyEnhance -> "empty_enhance.png"
Images.CEGloomLv1 -> "gloom_0.png"
Images.CEStarvationLv1 -> "starvation_0.png"
Images.CEAwakeningLv1 -> "awakening_0.png"
Expand All @@ -114,6 +114,16 @@ class ImageLoader @Inject constructor(
Images.SkillUse -> "skill_use.png"
Images.RankUp -> "rank_up.png"
Images.Close -> "close.png"
Images.ServantAutoSelect -> "servant_auto_select.png"
Images.ServantAutoSelectOff -> "servant_auto_select_off.png"
Images.ServantMaxLevel -> "servant_max_level.png"
Images.ServantGrailRedirectFromMenu -> "servant_palingenesis_redirect_from_menu.png"
Images.ServantAscensionRedirectFromMenu -> "servant_ascension_redirect_from_menu.png"
Images.ServantGrailBanner -> "servant_palingenesis_banner.png"
Images.ServantAscensionBanner -> "servant_ascension_banner.png"
Images.ServantAscensionReturnToLevel -> "servant_ascension_return_to_level.png"
Images.Ok -> "ok.png"
Images.Execute -> "execute.png"
}

override operator fun get(img: Images, gameServer: GameServer?): Pattern = synchronized(regionCachedPatterns) {
Expand Down
16 changes: 16 additions & 0 deletions app/src/main/res/values/localized.xml
Original file line number Diff line number Diff line change
Expand Up @@ -398,4 +398,20 @@ After pressing on the button, switch the app filter from \"Not optimized\" to \"
<string name="p_screenshot_bond">"Screenshot Bond"</string>
<string name="p_screenshot_bond_summary">"Experimental screenshot of bond level up regardless of level to 'bond' folder\nNote: Auto-click on another results screen might cause occasional missed screenshots, potentially skipping the bond level-up."</string>
<string name="bond_level_up">Bond Level up!</string>

<string name="servant_enhancement">Servant Enhancement</string>
<string name="servant_enhancement_no_embers_or_qp_left">Insufficient Embers or QP</string>
<string name="servert_enhancement_warning_notice">This script will use the auto-select feature to select the embers.</string>
<string name="servant_enhancement_redirect_ascension_question">Redirect to Ascension upon reaching the level cap</string>
<string name="servant_enhancement_perform_ascension_question">Perform Ascension</string>
<string name="servant_enhancement_perform_ascension_warning">Ascension of duplicate Servants is not supported.</string>
<string name="servant_enhancement_redirect_grail">Redirect to Palingenesis upon reaching the level cap</string>
<string name="servant_enhancement_redirect_ascension_success">Redirected to Ascension</string>
<string name="servant_enhancement_redirect_grail_success">Redirected to Palingenesis</string>
<string name="servant_enhancement_perform_ascension_failed">Unable to perform Ascension</string>
<string name="servant_enhancement_max_level">Max Level Achieved</string>
<string name="servant_enhancement_none_selected">No Servant Selected. Please select a Servant before proceeding.</string>
<string name="servant_enhancement_aborted">Enhancement was aborted</string>
<string name="servant_enhancement_not_implemented">Servant Enhancement is not supported on your FGO server yet."</string>
<string name="note">"Note:"</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,10 @@ interface AutomataApi {
fun Region.isBlack(): Boolean

fun Region.detectText(outlinedText: Boolean = false): String

fun Map<Pattern, Region>.exists(
timeout: Duration = Duration.ZERO,
similarity: Double? = null,
requireAll: Boolean = false
): Boolean
}
Loading

0 comments on commit 84be9f9

Please sign in to comment.