Skip to content

Commit

Permalink
Merge pull request #590 from ThibaultLassiaz/fix-rocck-smash-safari-em
Browse files Browse the repository at this point in the history
Fix Rock smash mode in safari for Emerald
  • Loading branch information
ThibaultLassiaz authored Dec 21, 2024
2 parents 072344f + 7be9474 commit 9e5e30e
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 25 deletions.
63 changes: 44 additions & 19 deletions modules/data/symbols/patches/language/pokeemerald.yml
Original file line number Diff line number Diff line change
Expand Up @@ -384,18 +384,6 @@ EventScript_DoTrainerBattle:
I: 0x82710ab
J: 0x82424ee
S: 0x8275258
EventScript_RockSmash:
D: 0x829ef03
F: 0x8297028
I: 0x829146e
J: 0x825667c
S: 0x8295638
EventScript_SmashRock:
D: 0x829ef58
F: 0x829707d
I: 0x82914c3
J: 0x82566d1
S: 0x829568d
EventScript_EggHatch:
D: 0x82a0780
F: 0x829887c
Expand Down Expand Up @@ -611,12 +599,6 @@ LittlerootTown_ProfessorBirchsLab_EventScript_UpgradeToNationalDex:
I: 0x81f9a6d
J: 0x81f141b
S: 0x81fa666
SafariZone_EventScript_TimesUp:
D: 0x82b676d
F: 0x82ad154
I: 0x82a6033
J: 0x82623e9
S: 0x82aae5a
SouthernIsland_Interior_EventScript_Lati:
D: 0x824b6cd
F: 0x8247d7c
Expand Down Expand Up @@ -815,4 +797,47 @@ EventScript_RepelWoreOff:
S: 0x82aadeb
gSpecialVar_0x8004:
J: 0x2037280
#----------------#
#----------------#

#-----------------#
# Rock Smash #
#-----------------#
EventScript_RockSmash:
D: 0x829ef03
F: 0x8297028
I: 0x829146e
J: 0x825667c
S: 0x8295638
EventScript_SmashRock:
D: 0x829ef58
F: 0x829707d
I: 0x82914c3
J: 0x82566d1
S: 0x829568d
sSafariZoneStepCounter:
J: 0x2039d1a
gNumSafariBalls:
J: 0x2039d18
# 0xb
SafariZone_EventScript_TimesUp:
D: 0x82b676d
F: 0x82ad154
I: 0x82a6033
J: 0x82623e8
S: 0x82aae5a
# 0xb
Route121_SafariZoneEntrance_EventScript_ExitSafariZone:
D: 0x8232697
F: 0x822fb48
I: 0x822b9b9
J: 0x82129eb
S: 0x822de23

# We map it here to exit Safari otherwise the RepelScript is mapping at this address
MatchCall_PersonalizedText20:
F: 0x82ad142
MatchCall_Text_MrStone10:
D: 0x82b675b
#----------------#


2 changes: 2 additions & 0 deletions modules/data/symbols/patches/language/pokefirered.yml
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,8 @@ sTextPrinters:
J: 0x2020030
gNumSafariBalls:
J: 0x203990c
gSafariZoneStepCounter:
J: 0x203990e
#--------------------#

#----------------#
Expand Down
2 changes: 2 additions & 0 deletions modules/data/symbols/patches/language/pokeleafgreen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ sTextPrinters:
J: 0x2020030
gNumSafariBalls:
J: 0x203990c
gSafariZoneStepCounter:
J: 0x203990e
#--------------------#

#----------------#
Expand Down
3 changes: 2 additions & 1 deletion modules/modes/_asserts.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ def assert_player_has_poke_balls() -> None:
or if safari ball threshold is reached.
"""
if is_safari_map():
if context.rom.is_frlg and get_safari_balls_left() <= 15:
# TODO : Remove rom check when RSE safari auto catch is implemented
if context.rom.is_frlg and get_safari_balls_left() < 15:
raise BotModeError("You have less than 15 balls left, switching to manual mode...")
else:
if get_item_bag().number_of_balls_except_master_ball == 0:
Expand Down
21 changes: 16 additions & 5 deletions modules/modes/rock_smash.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
from modules.encounter import handle_encounter, EncounterInfo
from modules.gui.multi_select_window import Selection, ask_for_choice
from modules.items import get_item_bag, get_item_by_name
from modules.map_data import MapRSE
from modules.map_data import MapRSE, is_safari_map
from modules.safari_strategy import get_safari_balls_left
from modules.map_path import calculate_path
from modules.memory import get_event_flag, get_event_var, read_symbol, unpack_uint16
from modules.player import TileTransitionState, get_player, get_player_avatar, AvatarFlags, get_player_location
Expand Down Expand Up @@ -50,16 +51,23 @@ def name() -> str:

@staticmethod
def is_selectable() -> bool:
if not context.rom.is_rse:
if context.rom.is_frlg:
return False

return get_player_avatar().map_group_and_number in (
player_map = get_player_avatar().map_group_and_number

if context.rom.is_rs:
return player_map == MapRSE.GRANITE_CAVE_B2F

allowed_maps = {
MapRSE.GRANITE_CAVE_B2F,
MapRSE.ROUTE121_SAFARI_ZONE_ENTRANCE,
MapRSE.SAFARI_ZONE_SOUTH,
MapRSE.SAFARI_ZONE_NORTHEAST,
MapRSE.SAFARI_ZONE_SOUTHEAST,
)
}

return player_map in allowed_maps

def __init__(self):
super().__init__()
Expand Down Expand Up @@ -133,7 +141,10 @@ def run(self) -> Generator:
check_in_saved_game=True,
)

assert_player_has_poke_balls()
# TODO: Remove and use the assert_player_has_poke_balls when RSE safari auto catch is implemented
# Shuckle catch rate is 35%. So 10 balls should be enough to catch it
if is_safari_map() and get_safari_balls_left() < 10:
raise BotModeError("Cannot rock smash with less than 10 safari balls")

if get_player_avatar().map_group_and_number == MapRSE.GRANITE_CAVE_B2F and get_item_bag().number_of_repels > 0:
mode = ask_for_choice(
Expand Down
80 changes: 80 additions & 0 deletions modules/modes/safari_debug.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
from typing import Generator

from modules.context import context
from modules.player import get_player_avatar
from modules.battle_state import BattleOutcome
from modules.map_data import MapFRLG, is_safari_map
from modules.player import TileTransitionState, get_player, get_player_avatar
from modules.tasks import task_is_active
from modules.memory import get_game_state, GameState
from modules.modes.util.walking import wait_for_player_avatar_to_be_controllable
from ._interface import BotMode
from ._asserts import assert_player_has_poke_balls
from .util import spin, navigate_to, ensure_facing_direction, wait_for_script_to_start_and_finish, fish
from modules.console import console


class SafariMode(BotMode):
@staticmethod
def name() -> str:
return "Safari"

@staticmethod
def is_selectable() -> bool:
return is_safari_map()

def on_battle_ended(self, outcome: "BattleOutcome") -> None:
if not outcome == BattleOutcome.Lost:
assert_player_has_poke_balls()

def run(self) -> Generator:
yield from self.enter_safari_zone()

while True:
match get_player_avatar().map_group_and_number:
case MapFRLG.FUCHSIA_CITY_SAFARI_ZONE_ENTRANCE:
yield from self.enter_safari_zone()
case MapFRLG.SAFARI_ZONE_CENTER:

def is_at_entrance_door():
return (
get_player_avatar().map_group_and_number == MapFRLG.SAFARI_ZONE_CENTER
and get_player_avatar().local_coordinates in (26, 30)
)

if is_at_entrance_door():
yield from wait_for_player_avatar_to_be_standing_still()
# yield from navigate_to(MapFRLG.SAFARI_ZONE_CENTER, (32, 19))
# while True:
# yield from fish()
yield from navigate_to(MapFRLG.SAFARI_ZONE_CENTER, (43, 16))
case MapFRLG.SAFARI_ZONE_EAST:
yield from navigate_to(MapFRLG.SAFARI_ZONE_EAST, (8, 9))
case MapFRLG.SAFARI_ZONE_NORTH:
yield from navigate_to(MapFRLG.SAFARI_ZONE_NORTH, (35, 30))
yield from spin()

def enter_safari_zone(self):
if get_player().money < 500:
raise BotModeError("You do not have enough cash to re-enter the Safari Zone.")
yield from navigate_to(MapFRLG.FUCHSIA_CITY_SAFARI_ZONE_ENTRANCE, (4, 4))
yield from ensure_facing_direction("Up")
context.emulator.hold_button("Up")
for _ in range(10):
yield
context.emulator.release_button("Up")
yield
yield from wait_for_script_to_start_and_finish(
"FuchsiaCity_SafariZone_Entrance_EventScript_AskEnterSafariZone", "A"
)
yield from wait_for_script_to_start_and_finish(
"FuchsiaCity_SafariZone_Entrance_EventScript_TryEnterSafariZone", "A"
)
while (
get_player_avatar().local_coordinates != (26, 30)
or task_is_active("Task_RunMapPreviewScreenForest")
or get_game_state() == GameState.CHANGE_MAP
):
console.print("here")
yield
yield from wait_for_player_avatar_to_be_controllable()

0 comments on commit 9e5e30e

Please sign in to comment.