Pokemon Emerald: Use some new state functions, improve rule reuse (#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
This commit is contained in:
Bryce Wilson 2024-09-08 05:19:37 -07:00 committed by GitHub
parent b8c2e14e8b
commit 5348f693fe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 80 additions and 79 deletions

View File

@ -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",
@ -41,7 +41,7 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
"EVENT_DEFEAT_WINONA",
"EVENT_DEFEAT_TATE_AND_LIZA",
"EVENT_DEFEAT_JUAN",
]]) >= n
], world.player, n)
huntable_legendary_events = [
f"EVENT_ENCOUNTER_{key}"
@ -61,8 +61,9 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
}.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)
@ -235,11 +236,11 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
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(
@ -299,15 +300,15 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
)
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
@ -347,19 +348,19 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
)
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:
@ -375,7 +376,7 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
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(
@ -386,17 +387,17 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
# 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"),
@ -439,7 +440,7 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
)
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
@ -643,15 +644,15 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
)
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
@ -699,11 +700,11 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
# 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"),
@ -719,11 +720,11 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
# 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"),
@ -812,15 +813,15 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
)
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
@ -830,11 +831,11 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
)
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"),
@ -850,7 +851,7 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
)
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(
@ -927,11 +928,11 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
)
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"),
@ -1115,17 +1116,17 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
# 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
@ -1257,17 +1258,17 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
)
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
@ -1374,17 +1375,17 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
# 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
@ -1505,7 +1506,7 @@ def set_rules(world: "PokemonEmeraldWorld") -> None:
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(