Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ class BattleScreenLocations @Inject constructor(
fun imageRegion(skill: Skill.Servant) =
Region(22, 28, 30, 30) + locate(skill)

fun cooldownTextRegion(skill: Skill.Servant) =
Region(8, 108, 96, 48) + locate(skill)

val servantDetailsInfoClick = Location(-660, 110).xFromCenter()

val servantDetailsFaceCardRegion = when (gameServer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import io.github.fate_grand_automata.scripts.models.SkillSpamTarget
import io.github.fate_grand_automata.scripts.models.SpamConfigPerTeamSlot
import io.github.fate_grand_automata.scripts.models.battle.BattleState
import io.github.fate_grand_automata.scripts.models.skills
import io.github.lib_automata.Pattern
import io.github.lib_automata.dagger.ScriptScope
import javax.inject.Inject
import kotlin.time.Duration.Companion.seconds
Expand All @@ -22,6 +23,8 @@ class SkillSpam @Inject constructor(
) : IFgoAutomataApi by api {
companion object {
val skillSpamDelay = 0.25.seconds
val skillReadyRecheckDelay = 0.1.seconds
val cooldownRegex = Regex("""\d+""")
}
Comment on lines 26 to 29
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 61c7ebf — the hardcoded skillReadySimilarity = 0.9 constant was removed and the calls were reverted to the in operator (Region.contains), which passes similarity = null and defers to platformImpl.prefs.minSimilarity. This is consistent with how the rest of the codebase handles image matching.


fun spamSkills() {
Expand All @@ -42,7 +45,7 @@ class SkillSpam @Inject constructor(
// Some delay for skill icon to be loaded
skillSpamDelay.wait()

if (skillImage in locations.battle.imageRegion(skill)) {
if (isReadyForSpam(skill, skillImage)) {
val target = skillSpamConfig.determineTarget(servantSlot)

caster.castServantSkill(skill, target)
Expand All @@ -68,4 +71,36 @@ class SkillSpam @Inject constructor(
SkillSpamTarget.Left -> ServantTarget.Left
SkillSpamTarget.Right -> ServantTarget.Right
}
}

private fun isReadyForSpam(skill: io.github.fate_grand_automata.scripts.models.Skill.Servant, skillImage: Pattern): Boolean {
val isReady = useSameSnapIn {
skillImage in locations.battle.imageRegion(skill) && !hasCooldownText(skill)
}

if (!isReady) {
return false
}

skillReadyRecheckDelay.wait()

return useSameSnapIn {
skillImage in locations.battle.imageRegion(skill) && !hasCooldownText(skill)
}
}

private fun hasCooldownText(skill: io.github.fate_grand_automata.scripts.models.Skill.Servant): Boolean {
val text = locations.battle.cooldownTextRegion(skill)
.detectText(outlinedText = true)
.replace('O', '0')
.replace('o', '0')
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 8926ddc — extracted the predicate into a local checkReady() function.

.replace('I', '1')
.replace('l', '1')

val cooldown = cooldownRegex
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 8926ddc — added import io.github.fate_grand_automata.scripts.models.Skill and replaced the fully-qualified names with Skill.Servant, consistent with Caster.kt.

.find(text)
?.value
?.toIntOrNull()

return cooldown != null && cooldown > 0
}
}
Loading