Skip to content

Commit

Permalink
Pokemon Emerald: Use some new state functions, improve rule reuse (Ar…
Browse files Browse the repository at this point in the history
…chipelagoMW#3383)

* Pokemon Emerald: Use some new state functions, improve rule reuse

* Pokemon Emerald: Remove a couple more extra lambdas

* Pokemon Emerald: Swap some rules to use exclusive groups/lists

* Pokemon Emerald: Linting

We're not gonna keep both me and the linter happy here, but this at least gets things more consistent

* Pokemon Emerald: Update _exclusive to _unique
  • Loading branch information
Zunawe authored Sep 8, 2024
1 parent b8c2e14 commit 5348f69
Showing 1 changed file with 80 additions and 79 deletions.
159 changes: 80 additions & 79 deletions worlds/pokemon_emerald/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
hm_rules: Dict[str, Callable[[CollectionState], bool]] = {}
for hm, badges in world.hm_requirements.items():
if isinstance(badges, list):
hm_rules[hm] = lambda state, hm=hm, badges=badges: state.has(hm, world.player) \
and state.has_all(badges, world.player)
hm_rules[hm] = lambda state, hm=hm, badges=badges: \
state.has(hm, world.player) and state.has_all(badges, world.player)
else:
hm_rules[hm] = lambda state, hm=hm, badges=badges: state.has(hm, world.player) \
and state.has_group("Badges", world.player, badges)
hm_rules[hm] = lambda state, hm=hm, badges=badges: \
state.has(hm, world.player) and state.has_group_unique("Badges", world.player, badges)

def has_acro_bike(state: CollectionState):
return state.has("Acro Bike", world.player)

def has_mach_bike(state: CollectionState):
return state.has("Mach Bike", world.player)

def defeated_n_gym_leaders(state: CollectionState, n: int) -> bool:
return sum([state.has(event, world.player) for event in [
return state.has_from_list_unique([
"EVENT_DEFEAT_ROXANNE",
"EVENT_DEFEAT_BRAWLY",
"EVENT_DEFEAT_WATTSON",
Expand All @@ -41,7 +41,7 @@ def defeated_n_gym_leaders(state: CollectionState, n: int) -> bool:
"EVENT_DEFEAT_WINONA",
"EVENT_DEFEAT_TATE_AND_LIZA",
"EVENT_DEFEAT_JUAN",
]]) >= n
], world.player, n)

huntable_legendary_events = [
f"EVENT_ENCOUNTER_{key}"
Expand All @@ -61,8 +61,9 @@ def defeated_n_gym_leaders(state: CollectionState, n: int) -> bool:
}.items()
if name in world.options.allowed_legendary_hunt_encounters.value
]

def encountered_n_legendaries(state: CollectionState, n: int) -> bool:
return sum(int(state.has(event, world.player)) for event in huntable_legendary_events) >= n
return state.has_from_list_unique(huntable_legendary_events, world.player, n)

def get_entrance(entrance: str):
return world.multiworld.get_entrance(entrance, world.player)
Expand Down Expand Up @@ -235,11 +236,11 @@ def get_location(location: str):
if world.options.norman_requirement == NormanRequirement.option_badges:
set_rule(
get_entrance("MAP_PETALBURG_CITY_GYM:2/MAP_PETALBURG_CITY_GYM:3"),
lambda state: state.has_group("Badges", world.player, world.options.norman_count.value)
lambda state: state.has_group_unique("Badges", world.player, world.options.norman_count.value)
)
set_rule(
get_entrance("MAP_PETALBURG_CITY_GYM:5/MAP_PETALBURG_CITY_GYM:6"),
lambda state: state.has_group("Badges", world.player, world.options.norman_count.value)
lambda state: state.has_group_unique("Badges", world.player, world.options.norman_count.value)
)
else:
set_rule(
Expand Down Expand Up @@ -299,15 +300,15 @@ def get_location(location: str):
)
set_rule(
get_entrance("REGION_ROUTE116/EAST -> REGION_TERRA_CAVE_ENTRANCE/MAIN"),
lambda state: state.has("EVENT_DEFEAT_CHAMPION", world.player) and \
state.has("TERRA_CAVE_ROUTE_116_1", world.player) and \
state.has("EVENT_DEFEAT_SHELLY", world.player)
lambda state: state.has("EVENT_DEFEAT_CHAMPION", world.player)
and state.has("TERRA_CAVE_ROUTE_116_1", world.player)
and state.has("EVENT_DEFEAT_SHELLY", world.player)
)
set_rule(
get_entrance("REGION_ROUTE116/WEST -> REGION_TERRA_CAVE_ENTRANCE/MAIN"),
lambda state: state.has("EVENT_DEFEAT_CHAMPION", world.player) and \
state.has("TERRA_CAVE_ROUTE_116_2", world.player) and \
state.has("EVENT_DEFEAT_SHELLY", world.player)
lambda state: state.has("EVENT_DEFEAT_CHAMPION", world.player)
and state.has("TERRA_CAVE_ROUTE_116_2", world.player)
and state.has("EVENT_DEFEAT_SHELLY", world.player)
)

# Rusturf Tunnel
Expand Down Expand Up @@ -347,19 +348,19 @@ def get_location(location: str):
)
set_rule(
get_entrance("REGION_ROUTE115/NORTH_BELOW_SLOPE -> REGION_ROUTE115/NORTH_ABOVE_SLOPE"),
lambda state: has_mach_bike(state)
has_mach_bike
)
set_rule(
get_entrance("REGION_ROUTE115/NORTH_BELOW_SLOPE -> REGION_TERRA_CAVE_ENTRANCE/MAIN"),
lambda state: state.has("EVENT_DEFEAT_CHAMPION", world.player) and \
state.has("TERRA_CAVE_ROUTE_115_1", world.player) and \
state.has("EVENT_DEFEAT_SHELLY", world.player)
lambda state: state.has("EVENT_DEFEAT_CHAMPION", world.player)
and state.has("TERRA_CAVE_ROUTE_115_1", world.player)
and state.has("EVENT_DEFEAT_SHELLY", world.player)
)
set_rule(
get_entrance("REGION_ROUTE115/NORTH_ABOVE_SLOPE -> REGION_TERRA_CAVE_ENTRANCE/MAIN"),
lambda state: state.has("EVENT_DEFEAT_CHAMPION", world.player) and \
state.has("TERRA_CAVE_ROUTE_115_2", world.player) and \
state.has("EVENT_DEFEAT_SHELLY", world.player)
lambda state: state.has("EVENT_DEFEAT_CHAMPION", world.player)
and state.has("TERRA_CAVE_ROUTE_115_2", world.player)
and state.has("EVENT_DEFEAT_SHELLY", world.player)
)

if world.options.extra_boulders:
Expand All @@ -375,7 +376,7 @@ def get_location(location: str):
if world.options.extra_bumpy_slope:
set_rule(
get_entrance("REGION_ROUTE115/SOUTH_BELOW_LEDGE -> REGION_ROUTE115/SOUTH_ABOVE_LEDGE"),
lambda state: has_acro_bike(state)
has_acro_bike
)
else:
set_rule(
Expand All @@ -386,17 +387,17 @@ def get_location(location: str):
# Route 105
set_rule(
get_entrance("REGION_UNDERWATER_ROUTE105/MARINE_CAVE_ENTRANCE_1 -> REGION_UNDERWATER_MARINE_CAVE/MAIN"),
lambda state: hm_rules["HM08 Dive"](state) and \
state.has("EVENT_DEFEAT_CHAMPION", world.player) and \
state.has("MARINE_CAVE_ROUTE_105_1", world.player) and \
state.has("EVENT_DEFEAT_SHELLY", world.player)
lambda state: hm_rules["HM08 Dive"](state)
and state.has("EVENT_DEFEAT_CHAMPION", world.player)
and state.has("MARINE_CAVE_ROUTE_105_1", world.player)
and state.has("EVENT_DEFEAT_SHELLY", world.player)
)
set_rule(
get_entrance("REGION_UNDERWATER_ROUTE105/MARINE_CAVE_ENTRANCE_2 -> REGION_UNDERWATER_MARINE_CAVE/MAIN"),
lambda state: hm_rules["HM08 Dive"](state) and \
state.has("EVENT_DEFEAT_CHAMPION", world.player) and \
state.has("MARINE_CAVE_ROUTE_105_2", world.player) and \
state.has("EVENT_DEFEAT_SHELLY", world.player)
lambda state: hm_rules["HM08 Dive"](state)
and state.has("EVENT_DEFEAT_CHAMPION", world.player)
and state.has("MARINE_CAVE_ROUTE_105_2", world.player)
and state.has("EVENT_DEFEAT_SHELLY", world.player)
)
set_rule(
get_entrance("MAP_ROUTE105:0/MAP_ISLAND_CAVE:0"),
Expand Down Expand Up @@ -439,7 +440,7 @@ def get_location(location: str):
)
set_rule(
get_entrance("REGION_GRANITE_CAVE_B1F/LOWER -> REGION_GRANITE_CAVE_B1F/UPPER"),
lambda state: has_mach_bike(state)
has_mach_bike
)

# Route 107
Expand Down Expand Up @@ -643,15 +644,15 @@ def get_location(location: str):
)
set_rule(
get_entrance("REGION_ROUTE114/ABOVE_WATERFALL -> REGION_TERRA_CAVE_ENTRANCE/MAIN"),
lambda state: state.has("EVENT_DEFEAT_CHAMPION", world.player) and \
state.has("TERRA_CAVE_ROUTE_114_1", world.player) and \
state.has("EVENT_DEFEAT_SHELLY", world.player)
lambda state: state.has("EVENT_DEFEAT_CHAMPION", world.player)
and state.has("TERRA_CAVE_ROUTE_114_1", world.player)
and state.has("EVENT_DEFEAT_SHELLY", world.player)
)
set_rule(
get_entrance("REGION_ROUTE114/MAIN -> REGION_TERRA_CAVE_ENTRANCE/MAIN"),
lambda state: state.has("EVENT_DEFEAT_CHAMPION", world.player) and \
state.has("TERRA_CAVE_ROUTE_114_2", world.player) and \
state.has("EVENT_DEFEAT_SHELLY", world.player)
lambda state: state.has("EVENT_DEFEAT_CHAMPION", world.player)
and state.has("TERRA_CAVE_ROUTE_114_2", world.player)
and state.has("EVENT_DEFEAT_SHELLY", world.player)
)

# Meteor Falls
Expand Down Expand Up @@ -699,11 +700,11 @@ def get_location(location: str):
# Jagged Pass
set_rule(
get_entrance("REGION_JAGGED_PASS/BOTTOM -> REGION_JAGGED_PASS/MIDDLE"),
lambda state: has_acro_bike(state)
has_acro_bike
)
set_rule(
get_entrance("REGION_JAGGED_PASS/MIDDLE -> REGION_JAGGED_PASS/TOP"),
lambda state: has_acro_bike(state)
has_acro_bike
)
set_rule(
get_entrance("MAP_JAGGED_PASS:4/MAP_MAGMA_HIDEOUT_1F:0"),
Expand All @@ -719,11 +720,11 @@ def get_location(location: str):
# Mirage Tower
set_rule(
get_entrance("REGION_MIRAGE_TOWER_2F/TOP -> REGION_MIRAGE_TOWER_2F/BOTTOM"),
lambda state: has_mach_bike(state)
has_mach_bike
)
set_rule(
get_entrance("REGION_MIRAGE_TOWER_2F/BOTTOM -> REGION_MIRAGE_TOWER_2F/TOP"),
lambda state: has_mach_bike(state)
has_mach_bike
)
set_rule(
get_entrance("REGION_MIRAGE_TOWER_3F/TOP -> REGION_MIRAGE_TOWER_3F/BOTTOM"),
Expand Down Expand Up @@ -812,15 +813,15 @@ def get_location(location: str):
)
set_rule(
get_entrance("REGION_ROUTE118/EAST -> REGION_TERRA_CAVE_ENTRANCE/MAIN"),
lambda state: state.has("EVENT_DEFEAT_CHAMPION", world.player) and \
state.has("TERRA_CAVE_ROUTE_118_1", world.player) and \
state.has("EVENT_DEFEAT_SHELLY", world.player)
lambda state: state.has("EVENT_DEFEAT_CHAMPION", world.player)
and state.has("TERRA_CAVE_ROUTE_118_1", world.player)
and state.has("EVENT_DEFEAT_SHELLY", world.player)
)
set_rule(
get_entrance("REGION_ROUTE118/WEST -> REGION_TERRA_CAVE_ENTRANCE/MAIN"),
lambda state: state.has("EVENT_DEFEAT_CHAMPION", world.player) and \
state.has("TERRA_CAVE_ROUTE_118_2", world.player) and \
state.has("EVENT_DEFEAT_SHELLY", world.player)
lambda state: state.has("EVENT_DEFEAT_CHAMPION", world.player)
and state.has("TERRA_CAVE_ROUTE_118_2", world.player)
and state.has("EVENT_DEFEAT_SHELLY", world.player)
)

# Route 119
Expand All @@ -830,11 +831,11 @@ def get_location(location: str):
)
set_rule(
get_entrance("REGION_ROUTE119/LOWER -> REGION_ROUTE119/LOWER_ACROSS_RAILS"),
lambda state: has_acro_bike(state)
has_acro_bike
)
set_rule(
get_entrance("REGION_ROUTE119/LOWER_ACROSS_RAILS -> REGION_ROUTE119/LOWER"),
lambda state: has_acro_bike(state)
has_acro_bike
)
set_rule(
get_entrance("REGION_ROUTE119/UPPER -> REGION_ROUTE119/MIDDLE_RIVER"),
Expand All @@ -850,7 +851,7 @@ def get_location(location: str):
)
set_rule(
get_entrance("REGION_ROUTE119/ABOVE_WATERFALL -> REGION_ROUTE119/ABOVE_WATERFALL_ACROSS_RAILS"),
lambda state: has_acro_bike(state)
has_acro_bike
)
if "Route 119 Aqua Grunts" not in world.options.remove_roadblocks.value:
set_rule(
Expand Down Expand Up @@ -927,11 +928,11 @@ def get_location(location: str):
)
set_rule(
get_entrance("REGION_SAFARI_ZONE_SOUTH/MAIN -> REGION_SAFARI_ZONE_NORTH/MAIN"),
lambda state: has_acro_bike(state)
has_acro_bike
)
set_rule(
get_entrance("REGION_SAFARI_ZONE_SOUTHWEST/MAIN -> REGION_SAFARI_ZONE_NORTHWEST/MAIN"),
lambda state: has_mach_bike(state)
has_mach_bike
)
set_rule(
get_entrance("REGION_SAFARI_ZONE_SOUTHWEST/MAIN -> REGION_SAFARI_ZONE_SOUTHWEST/POND"),
Expand Down Expand Up @@ -1115,17 +1116,17 @@ def get_location(location: str):
# Route 125
set_rule(
get_entrance("REGION_UNDERWATER_ROUTE125/MARINE_CAVE_ENTRANCE_1 -> REGION_UNDERWATER_MARINE_CAVE/MAIN"),
lambda state: hm_rules["HM08 Dive"](state) and \
state.has("EVENT_DEFEAT_CHAMPION", world.player) and \
state.has("MARINE_CAVE_ROUTE_125_1", world.player) and \
state.has("EVENT_DEFEAT_SHELLY", world.player)
lambda state: hm_rules["HM08 Dive"](state)
and state.has("EVENT_DEFEAT_CHAMPION", world.player)
and state.has("MARINE_CAVE_ROUTE_125_1", world.player)
and state.has("EVENT_DEFEAT_SHELLY", world.player)
)
set_rule(
get_entrance("REGION_UNDERWATER_ROUTE125/MARINE_CAVE_ENTRANCE_2 -> REGION_UNDERWATER_MARINE_CAVE/MAIN"),
lambda state: hm_rules["HM08 Dive"](state) and \
state.has("EVENT_DEFEAT_CHAMPION", world.player) and \
state.has("MARINE_CAVE_ROUTE_125_2", world.player) and \
state.has("EVENT_DEFEAT_SHELLY", world.player)
lambda state: hm_rules["HM08 Dive"](state)
and state.has("EVENT_DEFEAT_CHAMPION", world.player)
and state.has("MARINE_CAVE_ROUTE_125_2", world.player)
and state.has("EVENT_DEFEAT_SHELLY", world.player)
)

# Shoal Cave
Expand Down Expand Up @@ -1257,17 +1258,17 @@ def get_location(location: str):
)
set_rule(
get_entrance("REGION_UNDERWATER_ROUTE127/MARINE_CAVE_ENTRANCE_1 -> REGION_UNDERWATER_MARINE_CAVE/MAIN"),
lambda state: hm_rules["HM08 Dive"](state) and \
state.has("EVENT_DEFEAT_CHAMPION", world.player) and \
state.has("MARINE_CAVE_ROUTE_127_1", world.player) and \
state.has("EVENT_DEFEAT_SHELLY", world.player)
lambda state: hm_rules["HM08 Dive"](state)
and state.has("EVENT_DEFEAT_CHAMPION", world.player)
and state.has("MARINE_CAVE_ROUTE_127_1", world.player)
and state.has("EVENT_DEFEAT_SHELLY", world.player)
)
set_rule(
get_entrance("REGION_UNDERWATER_ROUTE127/MARINE_CAVE_ENTRANCE_2 -> REGION_UNDERWATER_MARINE_CAVE/MAIN"),
lambda state: hm_rules["HM08 Dive"](state) and \
state.has("EVENT_DEFEAT_CHAMPION", world.player) and \
state.has("MARINE_CAVE_ROUTE_127_2", world.player) and \
state.has("EVENT_DEFEAT_SHELLY", world.player)
lambda state: hm_rules["HM08 Dive"](state)
and state.has("EVENT_DEFEAT_CHAMPION", world.player)
and state.has("MARINE_CAVE_ROUTE_127_2", world.player)
and state.has("EVENT_DEFEAT_SHELLY", world.player)
)

# Route 128
Expand Down Expand Up @@ -1374,17 +1375,17 @@ def get_location(location: str):
# Route 129
set_rule(
get_entrance("REGION_UNDERWATER_ROUTE129/MARINE_CAVE_ENTRANCE_1 -> REGION_UNDERWATER_MARINE_CAVE/MAIN"),
lambda state: hm_rules["HM08 Dive"](state) and \
state.has("EVENT_DEFEAT_CHAMPION", world.player) and \
state.has("MARINE_CAVE_ROUTE_129_1", world.player) and \
state.has("EVENT_DEFEAT_SHELLY", world.player)
lambda state: hm_rules["HM08 Dive"](state)
and state.has("EVENT_DEFEAT_CHAMPION", world.player)
and state.has("MARINE_CAVE_ROUTE_129_1", world.player)
and state.has("EVENT_DEFEAT_SHELLY", world.player)
)
set_rule(
get_entrance("REGION_UNDERWATER_ROUTE129/MARINE_CAVE_ENTRANCE_2 -> REGION_UNDERWATER_MARINE_CAVE/MAIN"),
lambda state: hm_rules["HM08 Dive"](state) and \
state.has("EVENT_DEFEAT_CHAMPION", world.player) and \
state.has("MARINE_CAVE_ROUTE_129_2", world.player) and \
state.has("EVENT_DEFEAT_SHELLY", world.player)
lambda state: hm_rules["HM08 Dive"](state)
and state.has("EVENT_DEFEAT_CHAMPION", world.player)
and state.has("MARINE_CAVE_ROUTE_129_2", world.player)
and state.has("EVENT_DEFEAT_SHELLY", world.player)
)

# Pacifidlog Town
Expand Down Expand Up @@ -1505,7 +1506,7 @@ def get_location(location: str):
if world.options.elite_four_requirement == EliteFourRequirement.option_badges:
set_rule(
get_entrance("REGION_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F/MAIN -> REGION_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F/BEHIND_BADGE_CHECKERS"),
lambda state: state.has_group("Badges", world.player, world.options.elite_four_count.value)
lambda state: state.has_group_unique("Badges", world.player, world.options.elite_four_count.value)
)
else:
set_rule(
Expand Down

0 comments on commit 5348f69

Please sign in to comment.