mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-05-27 10:29:55 -07:00
SML2: Send logic affecting randomiser options as slot_data (#5751)
* Send logic affecting randomiser options as slot_data * SML2 - Universal Tracker support * Remove debug logs * Only check generation_is_fake once --------- Co-authored-by: alchav <alchav@jalchavware.com>
This commit is contained in:
@@ -56,6 +56,9 @@ class MarioLand2World(World):
|
||||
|
||||
web = MarioLand2WebWorld()
|
||||
|
||||
ut_can_gen_without_yaml = True
|
||||
glitches_item_name = "ut_glitch"
|
||||
|
||||
item_name_groups = {
|
||||
"Level Progression": {
|
||||
item_name for item_name in items if item_name.endswith(("Progression", "Secret", "Secret 1", "Secret 2"))
|
||||
@@ -94,42 +97,51 @@ class MarioLand2World(World):
|
||||
self.max_coin_locations = {}
|
||||
self.sprite_data = {}
|
||||
self.coin_fragments_required = 0
|
||||
self.ut = False
|
||||
|
||||
def generate_early(self):
|
||||
self.sprite_data = deepcopy(level_sprites)
|
||||
if self.options.randomize_enemies:
|
||||
randomize_enemies(self.sprite_data, self.random)
|
||||
if self.options.randomize_platforms:
|
||||
randomize_platforms(self.sprite_data, self.random)
|
||||
|
||||
if self.options.marios_castle_midway_bell:
|
||||
self.sprite_data["Mario's Castle"][35]["sprite"] = "Midway Bell"
|
||||
|
||||
if self.options.auto_scroll_chances == "vanilla":
|
||||
self.auto_scroll_levels = [int(i in [19, 25, 30]) for i in range(32)]
|
||||
if hasattr(self.multiworld, "re_gen_passthrough") and self.game in self.multiworld.re_gen_passthrough:
|
||||
self.ut = True
|
||||
for key, value in self.multiworld.re_gen_passthrough[self.game].items():
|
||||
if hasattr(self.options, key):
|
||||
getattr(self.options, key).value = value
|
||||
else:
|
||||
setattr(self, key, value)
|
||||
else:
|
||||
self.auto_scroll_levels = [int(self.random.randint(1, 100) <= self.options.auto_scroll_chances)
|
||||
for _ in range(32)]
|
||||
self.sprite_data = deepcopy(level_sprites)
|
||||
|
||||
self.auto_scroll_levels[level_name_to_id["Mario's Castle"]] = 0
|
||||
unbeatable_scroll_levels = ["Tree Zone 3", "Macro Zone 2", "Space Zone 1", "Turtle Zone 2", "Pumpkin Zone 2"]
|
||||
if not self.options.shuffle_midway_bells:
|
||||
unbeatable_scroll_levels.append("Pumpkin Zone 1")
|
||||
for level, i in enumerate(self.auto_scroll_levels):
|
||||
if i == 1:
|
||||
if self.options.auto_scroll_mode in ("global_cancel_item", "level_cancel_items"):
|
||||
self.auto_scroll_levels[level] = 2
|
||||
elif self.options.auto_scroll_mode == "chaos":
|
||||
if (self.options.accessibility == "full"
|
||||
and level_id_to_name[level] in unbeatable_scroll_levels):
|
||||
if self.options.marios_castle_midway_bell:
|
||||
self.sprite_data["Mario's Castle"][35]["sprite"] = "Midway Bell"
|
||||
if self.options.randomize_enemies:
|
||||
randomize_enemies(self.sprite_data, self.random)
|
||||
if self.options.randomize_platforms:
|
||||
randomize_platforms(self.sprite_data, self.random)
|
||||
|
||||
if self.options.auto_scroll_chances == "vanilla":
|
||||
self.auto_scroll_levels = [int(i in [19, 25, 30]) for i in range(32)]
|
||||
else:
|
||||
self.auto_scroll_levels = [int(self.random.randint(1, 100) <= self.options.auto_scroll_chances)
|
||||
for _ in range(32)]
|
||||
|
||||
self.auto_scroll_levels[level_name_to_id["Mario's Castle"]] = 0
|
||||
unbeatable_scroll_levels = ["Tree Zone 3", "Macro Zone 2", "Space Zone 1", "Turtle Zone 2", "Pumpkin Zone 2"]
|
||||
if not self.options.shuffle_midway_bells:
|
||||
unbeatable_scroll_levels.append("Pumpkin Zone 1")
|
||||
for level, i in enumerate(self.auto_scroll_levels):
|
||||
if i == 1:
|
||||
if self.options.auto_scroll_mode in ("global_cancel_item", "level_cancel_items"):
|
||||
self.auto_scroll_levels[level] = 2
|
||||
else:
|
||||
self.auto_scroll_levels[level] = self.random.randint(1, 3)
|
||||
elif (self.options.accessibility == "full"
|
||||
and level_id_to_name[level] in unbeatable_scroll_levels):
|
||||
self.auto_scroll_levels[level] = 0
|
||||
if self.auto_scroll_levels[level] == 1 and "trap" in self.options.auto_scroll_mode.current_key:
|
||||
self.auto_scroll_levels[level] = 3
|
||||
elif self.options.auto_scroll_mode == "chaos":
|
||||
if (self.options.accessibility == "full"
|
||||
and level_id_to_name[level] in unbeatable_scroll_levels):
|
||||
self.auto_scroll_levels[level] = 2
|
||||
else:
|
||||
self.auto_scroll_levels[level] = self.random.randint(1, 3)
|
||||
elif (self.options.accessibility == "full"
|
||||
and level_id_to_name[level] in unbeatable_scroll_levels):
|
||||
self.auto_scroll_levels[level] = 0
|
||||
if self.auto_scroll_levels[level] == 1 and "trap" in self.options.auto_scroll_mode.current_key:
|
||||
self.auto_scroll_levels[level] = 3
|
||||
|
||||
def create_regions(self):
|
||||
menu_region = Region("Menu", self.player, self.multiworld)
|
||||
@@ -178,7 +190,10 @@ class MarioLand2World(World):
|
||||
wario.place_locked_item(MarioLand2Item("Wario Defeated", ItemClassification.progression, None, self.player))
|
||||
|
||||
if self.options.coinsanity:
|
||||
coinsanity_checks = self.options.coinsanity_checks.value
|
||||
if hasattr(self.multiworld, "generation_is_fake"):
|
||||
coinsanity_checks = self.options.coinsanity_checks.range_end
|
||||
else:
|
||||
coinsanity_checks = self.options.coinsanity_checks.value
|
||||
self.num_coin_locations = [[region, 1] for region in created_regions if region != "Mario's Castle"]
|
||||
self.max_coin_locations = {region: len(coins_coords[region]) for region in created_regions
|
||||
if region != "Mario's Castle"}
|
||||
@@ -423,12 +438,40 @@ class MarioLand2World(World):
|
||||
self.multiworld.itempool += [self.create_item(item_name) for _ in range(count)]
|
||||
|
||||
def fill_slot_data(self):
|
||||
return {
|
||||
"energy_link": self.options.energy_link.value
|
||||
}
|
||||
# Expose settings for accurate tracker logic
|
||||
shark_count: int = [
|
||||
self.multiworld.worlds[self.player].sprite_data["Turtle Zone 1"][i]["sprite"]
|
||||
for i in (27, 28)
|
||||
].count("Shark")
|
||||
crane_count: int = [
|
||||
self.multiworld.worlds[self.player].sprite_data["Mario Zone 3"][i]["sprite"]
|
||||
for i in (17, 18, 25)
|
||||
].count("Claw Grabber")
|
||||
options_dict = self.options.as_dict(
|
||||
"energy_link",
|
||||
"shuffle_golden_coins",
|
||||
"required_golden_coins",
|
||||
"coinsanity",
|
||||
"shuffle_midway_bells",
|
||||
"marios_castle_midway_bell",
|
||||
"shuffle_pipe_traversal",
|
||||
"auto_scroll_mode"
|
||||
)
|
||||
options_dict.update({
|
||||
"auto_scroll_levels": self.auto_scroll_levels,
|
||||
"turtle_zone_1_shark_count": shark_count,
|
||||
"mario_zone_3_crane_count": crane_count,
|
||||
"coin_fragments_required": self.coin_fragments_required
|
||||
})
|
||||
return options_dict
|
||||
|
||||
@staticmethod
|
||||
def interpret_slot_data(slot_data):
|
||||
return slot_data
|
||||
|
||||
def create_item(self, name: str) -> Item:
|
||||
return MarioLand2Item(name, items[name], self.item_name_to_id[name], self.player)
|
||||
return MarioLand2Item(name, items[name] if name in items else ItemClassification.progression,
|
||||
self.item_name_to_id[name] if name in self.item_name_to_id else None, self.player)
|
||||
|
||||
def get_filler_item_name(self):
|
||||
return "1 Coin"
|
||||
|
||||
@@ -5,6 +5,8 @@ def is_auto_scroll(state, player, level):
|
||||
level_id = level_name_to_id[level]
|
||||
if state.has_any(["Cancel Auto Scroll", f"Cancel Auto Scroll - {level}"], player):
|
||||
return False
|
||||
if state.has("ut_glitch", player) and state.multiworld.worlds[player].auto_scroll_levels[level_id] == 3:
|
||||
return state.has(f"Auto Scroll - {level}", player)
|
||||
return state.multiworld.worlds[player].auto_scroll_levels[level_id] > 0
|
||||
|
||||
|
||||
@@ -287,8 +289,12 @@ def mario_zone_3_coins(state, player, coins):
|
||||
if state.has("Carrot", player):
|
||||
reachable_spike_coins = 15
|
||||
else:
|
||||
sprites = state.multiworld.worlds[player].sprite_data["Mario Zone 3"]
|
||||
reachable_spike_coins = min(3, len({sprites[i]["sprite"] == "Claw Grabber" for i in (17, 18, 25)})
|
||||
if state.multiworld.worlds[player].ut:
|
||||
claw_grabbers = state.multiworld.worlds[player].mario_zone_3_crane_count
|
||||
else:
|
||||
sprites = state.multiworld.worlds[player].sprite_data["Mario Zone 3"]
|
||||
claw_grabbers = len({sprites[i]["sprite"] == "Claw Grabber" for i in (17, 18, 25)})
|
||||
reachable_spike_coins = min(3, claw_grabbers
|
||||
+ state.has("Mushroom", player) + state.has("Fire Flower", player)) * 5
|
||||
reachable_coins += reachable_spike_coins
|
||||
if not auto_scroll:
|
||||
@@ -309,8 +315,11 @@ def mario_zone_4_coins(state, player, coins):
|
||||
|
||||
|
||||
def not_blocked_by_sharks(state, player):
|
||||
sharks = [state.multiworld.worlds[player].sprite_data["Turtle Zone 1"][i]["sprite"]
|
||||
for i in (27, 28)].count("Shark")
|
||||
if state.multiworld.worlds[player].ut:
|
||||
sharks = state.multiworld.worlds[player].turtle_zone_1_shark_count
|
||||
else:
|
||||
sharks = [state.multiworld.worlds[player].sprite_data["Turtle Zone 1"][i]["sprite"]
|
||||
for i in (27, 28)].count("Shark")
|
||||
if state.has("Carrot", player) or not sharks:
|
||||
return True
|
||||
if sharks == 2:
|
||||
|
||||
Reference in New Issue
Block a user