Skip to content

Commit

Permalink
Merge pull request #117 from Mowlawner/auto-battle-refactor-again
Browse files Browse the repository at this point in the history
Auto battle
  • Loading branch information
40Cakes authored Dec 16, 2023
2 parents 0978c55 + 1fcc354 commit b4bac6e
Show file tree
Hide file tree
Showing 10 changed files with 2,219 additions and 4 deletions.
1,159 changes: 1,159 additions & 0 deletions modules/battle.py

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion modules/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
from modules import exceptions
from modules.modes import available_bot_modes
from modules.runtime import get_base_path
from modules.config.schemas_v1 import CatchBlock, Cheats, Discord, Keys, Logging, OBS, ProfileMetadata
from modules.config.schemas_v1 import Battle, CatchBlock, Cheats, Discord, Keys, Logging, OBS, ProfileMetadata

# Defines which class attributes of the Config class are meant to hold required configuration data.
CONFIG_ATTRS = {
"battle",
"catch_block",
"cheats",
"discord",
Expand All @@ -33,6 +34,7 @@ def __init__(self, config_dir: str | Path | None = None, is_profile: bool = Fals
:param is_profile: Whether profile files are expected in this directory.
:param strict: Whether to allow files to be missing.
"""
self.battle: Battle = Battle()
self.config_dir = get_base_path() / "profiles" if not config_dir else Path(config_dir)
self.catch_block: CatchBlock = CatchBlock()
self.cheats: Cheats = Cheats()
Expand Down
60 changes: 60 additions & 0 deletions modules/config/schemas_v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,65 @@
from pydantic.types import Annotated, ClassVar, NonNegativeInt, PositiveInt


class Battle(BaseConfig):
"""Schema for the catch_block configuration."""

filename: ClassVar = "battle.yml"
pickup: bool = False
pickup_threshold: Annotated[int, Field(gt=0, lt=7)] = 1
pickup_check_frequency: Annotated[int, Field(gt=0)] = 5
battle: bool = False
battle_method: Literal["strongest"] = "strongest"
faint_action: Literal["stop", "flee", "rotate"] = "flee"
new_move: Literal["stop", "cancel", "learn_best"] = "stop"
stop_evolution: bool = True
replace_lead_battler: bool = False
switch_strategy: Literal["first_available"] = "first_available"
banned_moves: list[str] = [
"None",
# 2-turn
"Bounce",
"Dig",
"Dive",
"Fly",
"Sky Attack",
"Razor Wind",
"Doom Desire",
"Solar Beam",
# Inconsistent
"Fake Out",
"False Swipe",
"Nature Power",
"Present",
"Destiny Bond",
"Wrap",
"Snore",
"Spit Up",
"Bide",
"Bind",
"Counter",
"Future Sight",
"Mirror Coat",
"Grudge",
"Snatch",
"Spite",
"Curse",
"Endeavor",
"Revenge",
"Assist",
"Focus Punch",
"Eruption",
"Flail",
# Ends battle
"Roar",
"Whirlwind",
"Selfdestruct",
"Perish Song",
"Explosion",
"Memento",
]


class CatchBlock(BaseConfig):
"""Schema for the catch_block configuration."""

Expand All @@ -24,6 +83,7 @@ class Cheats(BaseConfig):
filename: ClassVar = "cheats.yml"
fast_check_starters: bool = False
random_soft_reset_rng: bool = False
faster_pickup: bool = False


class Discord(BaseConfig):
Expand Down
23 changes: 21 additions & 2 deletions modules/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
import sys
from threading import Thread

from modules.battle import BattleHandler, check_lead_can_battle, RotatePokemon
from modules.console import console
from modules.context import context
from modules.memory import get_game_state, GameState
from modules.menuing import MenuWrapper, CheckForPickup, should_check_for_pickup
from modules.pokemon import opponent_changed, get_opponent
from modules.temp import temp_run_from_battle


# Contains a queue of tasks that should be run the next time a frame completes.
Expand All @@ -22,6 +23,10 @@ def main_loop() -> None:
"""
from modules.encounter import encounter_pokemon # prevents instantiating TotalStats class before profile selected

encounter_counter = 0
pickup_checked = False
lead_rotated = False

try:
mode = None

Expand All @@ -48,14 +53,28 @@ def main_loop() -> None:
and context.bot_mode not in ["Starters", "Static Soft Resets"]
):
if opponent_changed():
pickup_checked = False
lead_rotated = False
encounter_pokemon(get_opponent())
encounter_counter += 1
if context.bot_mode != "Manual":
temp_run_from_battle()
mode = BattleHandler()

if context.bot_mode == "Manual":
if mode:
mode = None

elif (
not mode and config.battle.pickup and should_check_for_pickup(encounter_counter) and not pickup_checked
):
mode = MenuWrapper(CheckForPickup(encounter_counter))
pickup_checked = True
encounter_counter = 0

elif not mode and config.battle.replace_lead_battler and not check_lead_can_battle() and not lead_rotated:
mode = MenuWrapper(RotatePokemon())
lead_rotated = True

elif not mode:
match context.bot_mode:
case "Spin":
Expand Down
4 changes: 4 additions & 0 deletions modules/memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ class GameState(IntEnum):
CHANGE_MAP = auto()
TITLE_SCREEN = auto()
MAIN_MENU = auto()
GARBAGE_COLLECTION = auto()
EVOLUTION = auto()
UNKNOWN = auto()


Expand Down Expand Up @@ -170,6 +172,8 @@ def get_game_state() -> GameState:
result = GameState.TITLE_SCREEN
case "CB2_MAINMENU":
result = GameState.MAIN_MENU
case "CB2_EVOLUTIONSCENEUPDATE":
result = GameState.EVOLUTION
case _:
result = GameState.UNKNOWN

Expand Down
Loading

0 comments on commit b4bac6e

Please sign in to comment.