Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Sweet Scent method #163

Closed
wants to merge 12 commits into from
5 changes: 5 additions & 0 deletions modules/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ def main_loop() -> None:
from modules.modes.soft_resets import ModeStaticSoftResets

mode = ModeStaticSoftResets()

case "Sweet Scent":
from modules.modes.sweet_scent import ModeSweetScent

mode = ModeSweetScent()

case "Tower Duo":
from modules.modes.tower_duo import ModeTowerDuo
Expand Down
2 changes: 0 additions & 2 deletions modules/memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,6 @@ def get_game_state() -> GameState:
return state_cache.game_state.value

match get_game_state_symbol():
case "CB2_SETUPOVERWORLDFORQLPLAYBACKWITHWARPEXIT" | "CB2_SETUPOVERWORLDFORQLPLAYBACK" | "CB2_LOADMAPFORQLPLAYBACK" | "CB2_ENTERFIELDFROMQUESTLOG":
return GameState.QUEST_LOG
case "CB2_OVERWORLD":
result = GameState.OVERWORLD
case "BATTLEMAINCB2":
Expand Down
41 changes: 38 additions & 3 deletions modules/menu_parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from modules.tasks import get_task, task_is_active


class CursorOptionEFRLG(IntEnum):
class CursorOptionE(IntEnum):
SUMMARY = 0
SWITCH = 1
CANCEL_1 = 2
Expand Down Expand Up @@ -43,6 +43,39 @@ class CursorOptionEFRLG(IntEnum):
SWEET_SCENT = 32


class CursorOptionFRLG(IntEnum):
SUMMARY = 0
SWITCH = 1
CANCEL_1 = 2
ITEM = 3
GIVE_ITEM = 4
TAKE_ITEM = 5
MAIL = 6
TAKE_MAIL = 7
READ = 8
CANCEL_2 = 9
SHIFT = 10
SEND_OUT = 11
ENTER = 12
NO_ENTRY = 13
STORE = 14
REGISTER = 15
TRADE_1 = 16
TRADE_2 = 17
FLASH = 18
CUT = 19
FLY = 20
STRENGTH = 21
SURF = 22
ROCK_SMASH = 23
WATERFALL = 24
TELEPORT = 25
DIG = 26
MILK_DRINK = 27
SOFTBOILED = 28
SWEET_SCENT = 29


class CursorOptionRS(IntEnum):
SUMMARY = 0
SWITCH = 1
Expand Down Expand Up @@ -312,7 +345,9 @@ def switch_requested() -> bool:

def get_cursor_options(idx: int) -> str:
match context.rom.game_title:
case "POKEMON FIRE" | "POKEMON LEAF" | "POKEMON EMER":
return CursorOptionEFRLG(idx).name
case "POKEMON EMER":
return CursorOptionE(idx).name
case "POKEMON FIRE" | "POKEMON LEAF":
return CursorOptionFRLG(idx).name
case _:
return CursorOptionRS(idx).name
9 changes: 4 additions & 5 deletions modules/menuing.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,8 @@ def __init__(self, idx: int, mode: str):
def get_primary_option(self):
if self.mode in ["take_item", "give_item"]:
self.primary_option = "ITEM"
if self.mode == "switch":
self.primary_option = "SWITCH"
if self.mode == "summary":
self.primary_option = "SUMMARY"
else:
self.primary_option = self.mode.upper()

def get_next_func(self):
match self.current_step:
Expand Down Expand Up @@ -299,7 +297,8 @@ def select_mon(self):
if self.game in ["POKEMON EMER", "POKEMON FIRE", "POKEMON LEAF"]:
while task_is_active("TASK_HANDLECHOOSEMONINPUT"):
context.emulator.press_button("A")
yield
# yield
context.emulator.run_single_frame()
Copy link
Owner

Choose a reason for hiding this comment

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

Any reason you're running the frame instead of yielding?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It randomly breaks when yielding. Works about 50% with yield, 100% with single frame

else:
while not task_is_active("SUB_8089D94"):
context.emulator.press_button("A")
Expand Down
1 change: 1 addition & 0 deletions modules/modes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"Fishing",
"Bunny Hop",
"Static Soft Resets",
"Sweet Scent",
"Tower Duo",
"Ancient Legendaries",
]
13 changes: 7 additions & 6 deletions modules/modes/starters.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,15 +335,16 @@ def step(self):
self.update_state(ModeStarterStates.TITLE)

case ModeStarterStates.TITLE:
match get_game_state():
case GameState.TITLE_SCREEN:
match get_game_state(), read_symbol("gQuestLogState"):
case GameState.TITLE_SCREEN, _:
context.emulator.press_button(random.choice(["A", "Start", "Left", "Right", "Up"]))
case GameState.MAIN_MENU:
case GameState.MAIN_MENU, _:
context.emulator.press_button("A")
case GameState.QUEST_LOG:
context.emulator.press_button("B")
case GameState.OVERWORLD:
case GameState.OVERWORLD, bytearray(b"\x00"):
self.update_state(ModeStarterStates.OVERWORLD)
case GameState.OVERWORLD, _:
context.emulator.press_button("B")


case ModeStarterStates.OVERWORLD:
context.message = "Pathing to starter..."
Expand Down
110 changes: 110 additions & 0 deletions modules/modes/sweet_scent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import random
from enum import Enum, auto

from modules.context import context
from modules.encounter import encounter_pokemon
from modules.memory import (
read_symbol,
get_game_state,
GameState,
write_symbol,
unpack_uint32,
pack_uint32,
)
from modules.pokemon import get_opponent, opponent_changed
from modules.tasks import task_is_active
from modules.menuing import StartMenuNavigator, PokemonPartyMenuNavigator
from modules.pokemon import get_party


class ModeSweetScentStates(Enum):
RESET = auto()
SELECT_SCENT = auto()
OVERWORLD = auto()
BATTLE = auto()
OPPONENT_CRY_START = auto()
OPPONENT_CRY_END = auto()
LOG_OPPONENT = auto()


class ModeSweetScent:
def __init__(self) -> None:
self.navigator = None
self.state: ModeSweetScentStates = ModeSweetScentStates.RESET

def update_state(self, state: ModeSweetScentStates) -> None:
self.state: ModeSweetScentStates = state

def step(self):
while True:
match self.state:
case ModeSweetScentStates.RESET:
if task_is_active("Task_HandleChooseMonInput"):
self.update_state(ModeSweetScentStates.SELECT_SCENT)
elif not task_is_active("Task_RunPerStepCallback") or task_is_active("Task_ShowStartMenu"):
context.emulator.press_button("B")
yield
else:
self.update_state(ModeSweetScentStates.OVERWORLD)
continue

case ModeSweetScentStates.OVERWORLD:
if self.navigator is None:
self.navigator = StartMenuNavigator("POKEMON")
else:
yield from self.navigator.step()
match self.navigator.current_step:
case "exit":
self.navigator = None
self.update_state(ModeSweetScentStates.SELECT_SCENT)
continue
continue

case ModeSweetScentStates.SELECT_SCENT:
scent_poke = None
for num, poke in enumerate(get_party()):
if "Sweet Scent" in str(poke.moves):
scent_poke = num
break
if scent_poke is None:
raise Exception("No Pokemon with Sweet Scent in party")
context.set_manual_mode()
break
else:
if self.navigator is None:
self.navigator = PokemonPartyMenuNavigator(scent_poke, "SWEET_SCENT")
else:
yield from self.navigator.step()
match self.navigator.current_step:
case "exit":
self.navigator = None
self.update_state(ModeSweetScentStates.BATTLE)
continue
continue

case ModeSweetScentStates.BATTLE:
if get_game_state() != GameState.BATTLE:
context.emulator.press_button("A")
else:
self.update_state(ModeSweetScentStates.OPPONENT_CRY_START)
continue

case ModeSweetScentStates.OPPONENT_CRY_START:
if not task_is_active("Task_DuckBGMForPokemonCry"):
context.emulator.press_button("B")
else:
self.update_state(ModeSweetScentStates.OPPONENT_CRY_END)
continue

case ModeSweetScentStates.OPPONENT_CRY_END:
if task_is_active("Task_DuckBGMForPokemonCry"):
pass
else:
self.update_state(ModeSweetScentStates.LOG_OPPONENT)
continue

case ModeSweetScentStates.LOG_OPPONENT:
encounter_pokemon(get_opponent())
return

yield
Loading