28
28
0x77001C , # 5-4 needs Burning
29
29
}
30
30
31
+ first_world_limit = {
32
+ # We need to limit the number of very restrictive stages in level 1 on solo gens
33
+ * first_stage_blacklist , # all three of the blacklist stages need 2+ items for both checks
34
+ 0x770007 ,
35
+ 0x770008 ,
36
+ 0x770013 ,
37
+ 0x77001E ,
31
38
32
- def generate_valid_level (level , stage , possible_stages , slot_random ):
33
- new_stage = slot_random .choice (possible_stages )
34
- if level == 1 and stage == 0 and new_stage in first_stage_blacklist :
35
- return generate_valid_level (level , stage , possible_stages , slot_random )
36
- else :
37
- return new_stage
39
+ }
40
+
41
+
42
+ def generate_valid_level (world : "KDL3World" , level , stage , possible_stages , placed_stages ):
43
+ new_stage = world .random .choice (possible_stages )
44
+ if level == 1 :
45
+ if stage == 0 and new_stage in first_stage_blacklist :
46
+ return generate_valid_level (world , level , stage , possible_stages , placed_stages )
47
+ elif not (world .multiworld .players > 1 or world .options .consumables or world .options .starsanity ) and \
48
+ new_stage in first_world_limit and \
49
+ sum (p_stage in first_world_limit for p_stage in placed_stages ) >= 2 :
50
+ return generate_valid_level (world , level , stage , possible_stages , placed_stages )
51
+ return new_stage
38
52
39
53
40
- def generate_rooms (world : "KDL3World" , door_shuffle : bool , level_regions : typing .Dict [int , Region ]):
54
+ def generate_rooms (world : "KDL3World" , level_regions : typing .Dict [int , Region ]):
41
55
level_names = {LocationName .level_names [level ]: level for level in LocationName .level_names }
42
56
room_data = orjson .loads (get_data (__name__ , os .path .join ("data" , "Rooms.json" )))
43
57
rooms : typing .Dict [str , KDL3Room ] = dict ()
@@ -49,8 +63,8 @@ def generate_rooms(world: "KDL3World", door_shuffle: bool, level_regions: typing
49
63
room .add_locations ({location : world .location_name_to_id [location ] if location in world .location_name_to_id else
50
64
None for location in room_entry ["locations" ]
51
65
if (not any (x in location for x in ["1-Up" , "Maxim" ]) or
52
- world .options .consumables .value ) and ("Star" not in location
53
- or world .options .starsanity .value )},
66
+ world .options .consumables .value ) and ("Star" not in location
67
+ or world .options .starsanity .value )},
54
68
KDL3Location )
55
69
rooms [room .name ] = room
56
70
for location in room .locations :
@@ -62,33 +76,25 @@ def generate_rooms(world: "KDL3World", door_shuffle: bool, level_regions: typing
62
76
world .multiworld .regions .extend (world .rooms )
63
77
64
78
first_rooms : typing .Dict [int , KDL3Room ] = dict ()
65
- if door_shuffle :
66
- # first, we need to generate the notable edge cases
67
- # 5-6 is the first, being the most restrictive
68
- # half of its rooms are required to be vanilla, but can be in different orders
69
- # the room before it *must* contain the copy ability required to unlock the room's goal
70
-
71
- raise NotImplementedError ()
72
- else :
73
- for name , room in rooms .items ():
74
- if room .room == 0 :
75
- if room .stage == 7 :
76
- first_rooms [0x770200 + room .level - 1 ] = room
77
- else :
78
- first_rooms [0x770000 + ((room .level - 1 ) * 6 ) + room .stage ] = room
79
- exits = dict ()
80
- for def_exit in room .default_exits :
81
- target = f"{ level_names [room .level ]} { room .stage } - { def_exit ['room' ]} "
82
- access_rule = tuple (def_exit ["access_rule" ])
83
- exits [target ] = lambda state , rule = access_rule : state .has_all (rule , world .player )
84
- room .add_exits (
85
- exits .keys (),
86
- exits
87
- )
88
- if world .options .open_world :
89
- if any ("Complete" in location .name for location in room .locations ):
90
- room .add_locations ({f"{ level_names [room .level ]} { room .stage } - Stage Completion" : None },
91
- KDL3Location )
79
+ for name , room in rooms .items ():
80
+ if room .room == 0 :
81
+ if room .stage == 7 :
82
+ first_rooms [0x770200 + room .level - 1 ] = room
83
+ else :
84
+ first_rooms [0x770000 + ((room .level - 1 ) * 6 ) + room .stage ] = room
85
+ exits = dict ()
86
+ for def_exit in room .default_exits :
87
+ target = f"{ level_names [room .level ]} { room .stage } - { def_exit ['room' ]} "
88
+ access_rule = tuple (def_exit ["access_rule" ])
89
+ exits [target ] = lambda state , rule = access_rule : state .has_all (rule , world .player )
90
+ room .add_exits (
91
+ exits .keys (),
92
+ exits
93
+ )
94
+ if world .options .open_world :
95
+ if any ("Complete" in location .name for location in room .locations ):
96
+ room .add_locations ({f"{ level_names [room .level ]} { room .stage } - Stage Completion" : None },
97
+ KDL3Location )
92
98
93
99
for level in world .player_levels :
94
100
for stage in range (6 ):
@@ -102,7 +108,7 @@ def generate_rooms(world: "KDL3World", door_shuffle: bool, level_regions: typing
102
108
if world .options .open_world or stage == 0 :
103
109
level_regions [level ].add_exits ([first_rooms [proper_stage ].name ])
104
110
else :
105
- world .multiworld .get_location (world .location_id_to_name [world .player_levels [level ][stage - 1 ]],
111
+ world .multiworld .get_location (world .location_id_to_name [world .player_levels [level ][stage - 1 ]],
106
112
world .player ).parent_region .add_exits ([first_rooms [proper_stage ].name ])
107
113
level_regions [level ].add_exits ([first_rooms [0x770200 + level - 1 ].name ])
108
114
@@ -141,8 +147,7 @@ def generate_valid_levels(world: "KDL3World", enforce_world: bool, enforce_patte
141
147
or (enforce_pattern and ((candidate - 1 ) & 0x00FFFF ) % 6 == stage )
142
148
or (enforce_pattern == enforce_world )
143
149
]
144
- new_stage = generate_valid_level (level , stage , stage_candidates ,
145
- world .random )
150
+ new_stage = generate_valid_level (world , level , stage , stage_candidates , levels [level ])
146
151
possible_stages .remove (new_stage )
147
152
levels [level ][stage ] = new_stage
148
153
except Exception :
@@ -218,7 +223,7 @@ def create_levels(world: "KDL3World") -> None:
218
223
level_shuffle == 1 ,
219
224
level_shuffle == 2 )
220
225
221
- generate_rooms (world , False , levels )
226
+ generate_rooms (world , levels )
222
227
223
228
level6 .add_locations ({LocationName .goals [world .options .goal ]: None }, KDL3Location )
224
229
0 commit comments