Skip to content

Commit 3a09677

Browse files
authored
sm64ex: Fix generations (#2583)
1 parent d3b09bd commit 3a09677

File tree

2 files changed

+77
-46
lines changed

2 files changed

+77
-46
lines changed

worlds/sm64ex/Regions.py

+58-28
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import typing
2+
3+
from enum import Enum
4+
25
from BaseClasses import MultiWorld, Region, Entrance, Location
36
from .Locations import SM64Location, location_table, locBoB_table, locWhomp_table, locJRB_table, locCCM_table, \
47
locBBH_table, \
@@ -7,36 +10,63 @@
710
locPSS_table, locSA_table, locBitDW_table, locTotWC_table, locCotMC_table, \
811
locVCutM_table, locBitFS_table, locWMotR_table, locBitS_table, locSS_table
912

10-
# sm64paintings is dict of entrances, format LEVEL | AREA
11-
sm64_level_to_paintings = {
12-
91: "Bob-omb Battlefield",
13-
241: "Whomp's Fortress",
14-
121: "Jolly Roger Bay",
15-
51: "Cool, Cool Mountain",
16-
41: "Big Boo's Haunt",
17-
71: "Hazy Maze Cave",
18-
221: "Lethal Lava Land",
19-
81: "Shifting Sand Land",
20-
231: "Dire, Dire Docks",
21-
101: "Snowman's Land",
22-
111: "Wet-Dry World",
23-
361: "Tall, Tall Mountain",
24-
132: "Tiny-Huge Island (Tiny)",
25-
131: "Tiny-Huge Island (Huge)",
26-
141: "Tick Tock Clock",
27-
151: "Rainbow Ride"
13+
class SM64Levels(int, Enum):
14+
BOB_OMB_BATTLEFIELD = 91
15+
WHOMPS_FORTRESS = 241
16+
JOLLY_ROGER_BAY = 121
17+
COOL_COOL_MOUNTAIN = 51
18+
BIG_BOOS_HAUNT = 41
19+
HAZY_MAZE_CAVE = 71
20+
LETHAL_LAVA_LAND = 221
21+
SHIFTING_SAND_LAND = 81
22+
DIRE_DIRE_DOCKS = 231
23+
SNOWMANS_LAND = 101
24+
WET_DRY_WORLD = 111
25+
TALL_TALL_MOUNTAIN = 361
26+
TINY_HUGE_ISLAND_TINY = 132
27+
TINY_HUGE_ISLAND_HUGE = 131
28+
TICK_TOCK_CLOCK = 141
29+
RAINBOW_RIDE = 151
30+
THE_PRINCESS_SECRET_SLIDE = 271
31+
THE_SECRET_AQUARIUM = 201
32+
BOWSER_IN_THE_DARK_WORLD = 171
33+
TOWER_OF_THE_WING_CAP = 291
34+
CAVERN_OF_THE_METAL_CAP = 281
35+
VANISH_CAP_UNDER_THE_MOAT = 181
36+
BOWSER_IN_THE_FIRE_SEA = 191
37+
WING_MARIO_OVER_THE_RAINBOW = 311
38+
39+
# sm64paintings is a dict of entrances, format LEVEL | AREA
40+
sm64_level_to_paintings: typing.Dict[SM64Levels, str] = {
41+
SM64Levels.BOB_OMB_BATTLEFIELD: "Bob-omb Battlefield",
42+
SM64Levels.WHOMPS_FORTRESS: "Whomp's Fortress",
43+
SM64Levels.JOLLY_ROGER_BAY: "Jolly Roger Bay",
44+
SM64Levels.COOL_COOL_MOUNTAIN: "Cool, Cool Mountain",
45+
SM64Levels.BIG_BOOS_HAUNT: "Big Boo's Haunt",
46+
SM64Levels.HAZY_MAZE_CAVE: "Hazy Maze Cave",
47+
SM64Levels.LETHAL_LAVA_LAND: "Lethal Lava Land",
48+
SM64Levels.SHIFTING_SAND_LAND: "Shifting Sand Land",
49+
SM64Levels.DIRE_DIRE_DOCKS: "Dire, Dire Docks",
50+
SM64Levels.SNOWMANS_LAND: "Snowman's Land",
51+
SM64Levels.WET_DRY_WORLD: "Wet-Dry World",
52+
SM64Levels.TALL_TALL_MOUNTAIN: "Tall, Tall Mountain",
53+
SM64Levels.TINY_HUGE_ISLAND_TINY: "Tiny-Huge Island (Tiny)",
54+
SM64Levels.TINY_HUGE_ISLAND_HUGE: "Tiny-Huge Island (Huge)",
55+
SM64Levels.TICK_TOCK_CLOCK: "Tick Tock Clock",
56+
SM64Levels.RAINBOW_RIDE: "Rainbow Ride"
2857
}
2958
sm64_paintings_to_level = { painting: level for (level,painting) in sm64_level_to_paintings.items() }
30-
# sm64secrets is list of secret areas, same format
31-
sm64_level_to_secrets = {
32-
271: "The Princess's Secret Slide",
33-
201: "The Secret Aquarium",
34-
171: "Bowser in the Dark World",
35-
291: "Tower of the Wing Cap",
36-
281: "Cavern of the Metal Cap",
37-
181: "Vanish Cap under the Moat",
38-
191: "Bowser in the Fire Sea",
39-
311: "Wing Mario over the Rainbow"
59+
60+
# sm64secrets is a dict of secret areas, same format as sm64paintings
61+
sm64_level_to_secrets: typing.Dict[SM64Levels, str] = {
62+
SM64Levels.THE_PRINCESS_SECRET_SLIDE: "The Princess's Secret Slide",
63+
SM64Levels.THE_SECRET_AQUARIUM: "The Secret Aquarium",
64+
SM64Levels.BOWSER_IN_THE_DARK_WORLD: "Bowser in the Dark World",
65+
SM64Levels.TOWER_OF_THE_WING_CAP: "Tower of the Wing Cap",
66+
SM64Levels.CAVERN_OF_THE_METAL_CAP: "Cavern of the Metal Cap",
67+
SM64Levels.VANISH_CAP_UNDER_THE_MOAT: "Vanish Cap under the Moat",
68+
SM64Levels.BOWSER_IN_THE_FIRE_SEA: "Bowser in the Fire Sea",
69+
SM64Levels.WING_MARIO_OVER_THE_RAINBOW: "Wing Mario over the Rainbow"
4070
}
4171
sm64_secrets_to_level = { secret: level for (level,secret) in sm64_level_to_secrets.items() }
4272

worlds/sm64ex/Rules.py

+19-18
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
from ..generic.Rules import add_rule
2-
from .Regions import connect_regions, sm64_level_to_paintings, sm64_paintings_to_level, sm64_level_to_secrets, sm64_entrances_to_level, sm64_level_to_entrances
2+
from .Regions import connect_regions, SM64Levels, sm64_level_to_paintings, sm64_paintings_to_level, sm64_level_to_secrets, sm64_secrets_to_level, sm64_entrances_to_level, sm64_level_to_entrances
33

44
def shuffle_dict_keys(world, obj: dict) -> dict:
55
keys = list(obj.keys())
66
values = list(obj.values())
77
world.random.shuffle(keys)
88
return dict(zip(keys,values))
99

10-
def fix_reg(entrance_ids, entrance, destination, swapdict, world):
11-
if entrance_ids[entrance] == destination: # Unlucky :C
12-
rand = world.random.choice(swapdict.keys())
13-
entrance_ids[entrance], entrance_ids[swapdict[rand]] = rand, entrance_ids[entrance]
14-
swapdict[rand] = entrance_ids[entrance]
15-
swapdict.pop(entrance)
10+
def fix_reg(entrance_map: dict, entrance: SM64Levels, invalid_regions: set,
11+
swapdict: dict, world):
12+
if entrance_map[entrance] in invalid_regions: # Unlucky :C
13+
replacement_regions = [(rand_region, rand_entrance) for rand_region, rand_entrance in swapdict.items()
14+
if rand_region not in invalid_regions]
15+
rand_region, rand_entrance = world.random.choice(replacement_regions)
16+
old_dest = entrance_map[entrance]
17+
entrance_map[entrance], entrance_map[rand_entrance] = rand_region, old_dest
18+
swapdict[rand_region] = entrance
19+
swapdict.pop(entrance_map[entrance]) # Entrance now fixed to rand_region
1620

1721
def set_rules(world, player: int, area_connections: dict):
1822
randomized_level_to_paintings = sm64_level_to_paintings.copy()
@@ -24,19 +28,16 @@ def set_rules(world, player: int, area_connections: dict):
2428
randomized_entrances = { **randomized_level_to_paintings, **randomized_level_to_secrets }
2529
if world.AreaRandomizer[player].value == 3: # Randomize Courses and Secrets in one pool
2630
randomized_entrances = shuffle_dict_keys(world,randomized_entrances)
31+
swapdict = { entrance: level for (level,entrance) in randomized_entrances.items() }
2732
# Guarantee first entrance is a course
28-
swapdict = { entrance: level for (level,entrance) in randomized_entrances }
29-
if randomized_entrances[91] not in sm64_paintings_to_level.keys(): # Unlucky :C (91 -> BoB Entrance)
30-
rand = world.random.choice(sm64_paintings_to_level.values())
31-
randomized_entrances[91], randomized_entrances[swapdict[rand]] = rand, randomized_entrances[91]
32-
swapdict[rand] = randomized_entrances[91]
33-
swapdict.pop("Bob-omb Battlefield")
34-
# Guarantee COTMC is not mapped to HMC, cuz thats impossible
35-
fix_reg(randomized_entrances, "Cavern of the Metal Cap", "Hazy Maze Cave", swapdict, world)
33+
fix_reg(randomized_entrances, SM64Levels.BOB_OMB_BATTLEFIELD, sm64_secrets_to_level.keys(), swapdict, world)
3634
# Guarantee BITFS is not mapped to DDD
37-
fix_reg(randomized_entrances, "Bowser in the Fire Sea", "Dire, Dire Docks", swapdict, world)
38-
if randomized_entrances[191] == "Hazy Maze Cave": # If BITFS is mapped to HMC...
39-
fix_reg(randomized_entrances, "Cavern of the Metal Cap", "Dire, Dire Docks", swapdict, world) # ... then dont allow COTMC to be mapped to DDD
35+
fix_reg(randomized_entrances, SM64Levels.BOWSER_IN_THE_FIRE_SEA, {"Dire, Dire Docks"}, swapdict, world)
36+
# Guarantee COTMC is not mapped to HMC, cuz thats impossible. If BitFS -> HMC, also no COTMC -> DDD.
37+
if randomized_entrances[SM64Levels.BOWSER_IN_THE_FIRE_SEA] == "Hazy Maze Cave":
38+
fix_reg(randomized_entrances, SM64Levels.CAVERN_OF_THE_METAL_CAP, {"Hazy Maze Cave", "Dire, Dire Docks"}, swapdict, world)
39+
else:
40+
fix_reg(randomized_entrances, SM64Levels.CAVERN_OF_THE_METAL_CAP, {"Hazy Maze Cave"}, swapdict, world)
4041

4142
# Destination Format: LVL | AREA with LVL = LEVEL_x, AREA = Area as used in sm64 code
4243
area_connections.update({entrance_lvl: sm64_entrances_to_level[destination] for (entrance_lvl,destination) in randomized_entrances.items()})

0 commit comments

Comments
 (0)