diff --git a/worlds/sm64ex/Items.py b/worlds/sm64ex/Items.py index 546f1abd316b..28fcd744846b 100644 --- a/worlds/sm64ex/Items.py +++ b/worlds/sm64ex/Items.py @@ -1,47 +1,58 @@ -from BaseClasses import Item +from typing import NamedTuple +from BaseClasses import Item, ItemClassification + +sm64ex_base_id: int = 3626000 class SM64Item(Item): game: str = "Super Mario 64" - -generic_item_table = { - "Power Star": 3626000, - "Basement Key": 3626178, - "Second Floor Key": 3626179, - "Progressive Key": 3626180, - "Wing Cap": 3626181, - "Metal Cap": 3626182, - "Vanish Cap": 3626183, - "1Up Mushroom": 3626184 +class SM64ItemData(NamedTuple): + code: int | None = None + classification: ItemClassification = ItemClassification.progression + +generic_item_data_table: dict[str, SM64ItemData] = { + "Power Star": SM64ItemData(sm64ex_base_id + 0, ItemClassification.progression_skip_balancing), + "Basement Key": SM64ItemData(sm64ex_base_id + 178), + "Second Floor Key": SM64ItemData(sm64ex_base_id + 179), + "Progressive Key": SM64ItemData(sm64ex_base_id + 180), + "Wing Cap": SM64ItemData(sm64ex_base_id + 181), + "Metal Cap": SM64ItemData(sm64ex_base_id + 182), + "Vanish Cap": SM64ItemData(sm64ex_base_id + 183), + "1Up Mushroom": SM64ItemData(sm64ex_base_id + 184, ItemClassification.filler), } -action_item_table = { - "Double Jump": 3626185, - "Triple Jump": 3626186, - "Long Jump": 3626187, - "Backflip": 3626188, - "Side Flip": 3626189, - "Wall Kick": 3626190, - "Dive": 3626191, - "Ground Pound": 3626192, - "Kick": 3626193, - "Climb": 3626194, - "Ledge Grab": 3626195 +action_item_data_table: dict[str, SM64ItemData] = { + "Double Jump": SM64ItemData(sm64ex_base_id + 185), + "Triple Jump": SM64ItemData(sm64ex_base_id + 186), + "Long Jump": SM64ItemData(sm64ex_base_id + 187), + "Backflip": SM64ItemData(sm64ex_base_id + 188), + "Side Flip": SM64ItemData(sm64ex_base_id + 189), + "Wall Kick": SM64ItemData(sm64ex_base_id + 190), + "Dive": SM64ItemData(sm64ex_base_id + 191), + "Ground Pound": SM64ItemData(sm64ex_base_id + 192), + "Kick": SM64ItemData(sm64ex_base_id + 193), + "Climb": SM64ItemData(sm64ex_base_id + 194), + "Ledge Grab": SM64ItemData(sm64ex_base_id + 195), } +cannon_item_data_table: dict[str, SM64ItemData] = { + "Cannon Unlock BoB": SM64ItemData(sm64ex_base_id + 200), + "Cannon Unlock WF": SM64ItemData(sm64ex_base_id + 201), + "Cannon Unlock JRB": SM64ItemData(sm64ex_base_id + 202), + "Cannon Unlock CCM": SM64ItemData(sm64ex_base_id + 203), + "Cannon Unlock SSL": SM64ItemData(sm64ex_base_id + 207), + "Cannon Unlock SL": SM64ItemData(sm64ex_base_id + 209), + "Cannon Unlock WDW": SM64ItemData(sm64ex_base_id + 210), + "Cannon Unlock TTM": SM64ItemData(sm64ex_base_id + 211), + "Cannon Unlock THI": SM64ItemData(sm64ex_base_id + 212), + "Cannon Unlock RR": SM64ItemData(sm64ex_base_id + 214), +} -cannon_item_table = { - "Cannon Unlock BoB": 3626200, - "Cannon Unlock WF": 3626201, - "Cannon Unlock JRB": 3626202, - "Cannon Unlock CCM": 3626203, - "Cannon Unlock SSL": 3626207, - "Cannon Unlock SL": 3626209, - "Cannon Unlock WDW": 3626210, - "Cannon Unlock TTM": 3626211, - "Cannon Unlock THI": 3626212, - "Cannon Unlock RR": 3626214 +item_data_table = { + **generic_item_data_table, + **action_item_data_table, + **cannon_item_data_table } -item_table = {**generic_item_table, **action_item_table, **cannon_item_table} \ No newline at end of file +item_table = {name: data.code for name, data in item_data_table.items() if data.code is not None} diff --git a/worlds/sm64ex/Options.py b/worlds/sm64ex/Options.py index 9c428c99590e..47cda7507d23 100644 --- a/worlds/sm64ex/Options.py +++ b/worlds/sm64ex/Options.py @@ -1,7 +1,7 @@ import typing from dataclasses import dataclass from Options import DefaultOnToggle, Range, Toggle, DeathLink, Choice, PerGameCommonOptions, OptionSet, OptionGroup -from .Items import action_item_table +from .Items import action_item_data_table class EnableCoinStars(Choice): """ @@ -135,7 +135,7 @@ class MoveRandomizerActions(OptionSet): """Which actions to randomize when Move Randomizer is enabled""" display_name = "Randomized Moves" # HACK: Disable randomization for double jump - valid_keys = [action for action in action_item_table if action != 'Double Jump'] + valid_keys = [action for action in action_item_data_table if action != 'Double Jump'] default = valid_keys sm64_options_groups = [ diff --git a/worlds/sm64ex/Rules.py b/worlds/sm64ex/Rules.py index 1535f9ca1fde..f5305dab6c71 100644 --- a/worlds/sm64ex/Rules.py +++ b/worlds/sm64ex/Rules.py @@ -6,7 +6,7 @@ from .Options import SM64Options 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 -from .Items import action_item_table +from .Items import action_item_data_table def shuffle_dict_keys(world, dictionary: dict) -> dict: keys = list(dictionary.keys()) @@ -372,8 +372,9 @@ def parse_token(self, token: str, cannon_name: str) -> Union[str, bool]: item = self.token_table.get(token, None) if not item: raise Exception(f"Invalid token: '{item}'") - if item in action_item_table: - if self.move_rando_bitvec & (1 << (action_item_table[item] - action_item_table['Double Jump'])) == 0: + if item in action_item_data_table: + double_jump_bitvec_offset = action_item_data_table['Double Jump'].code + if self.move_rando_bitvec & (1 << (action_item_data_table[item].code - double_jump_bitvec_offset)) == 0: # This action item is not randomized. return True return item diff --git a/worlds/sm64ex/__init__.py b/worlds/sm64ex/__init__.py index afa67f233c69..5a751cb6b8c1 100644 --- a/worlds/sm64ex/__init__.py +++ b/worlds/sm64ex/__init__.py @@ -1,7 +1,7 @@ import typing import os import json -from .Items import item_table, action_item_table, cannon_item_table, SM64Item +from .Items import item_data_table, action_item_data_table, cannon_item_data_table, item_table, SM64Item from .Locations import location_table, SM64Location from .Options import sm64_options_groups, SM64Options from .Rules import set_rules @@ -54,9 +54,10 @@ def generate_early(self): max_stars -= 15 self.move_rando_bitvec = 0 if self.options.enable_move_rando: + double_jump_bitvec_offset = action_item_data_table['Double Jump'].code for action in self.options.move_rando_actions.value: max_stars -= 1 - self.move_rando_bitvec |= (1 << (action_item_table[action] - action_item_table['Double Jump'])) + self.move_rando_bitvec |= (1 << (action_item_data_table[action].code - double_jump_bitvec_offset)) if self.options.exclamation_boxes: max_stars += 29 self.number_of_stars = min(self.options.amount_of_stars, max_stars) @@ -89,14 +90,8 @@ def set_rules(self): 'entrance', self.player) def create_item(self, name: str) -> Item: - item_id = item_table[name] - if name == "1Up Mushroom": - classification = ItemClassification.filler - elif name == "Power Star": - classification = ItemClassification.progression_skip_balancing - else: - classification = ItemClassification.progression - item = SM64Item(name, classification, item_id, self.player) + data = item_data_table[name] + item = SM64Item(name, data.classification, data.code, self.player) return item @@ -120,11 +115,12 @@ def create_items(self): self.multiworld.itempool += [self.create_item(cap_name) for cap_name in ["Wing Cap", "Metal Cap", "Vanish Cap"]] # Cannons if (self.options.buddy_checks): - self.multiworld.itempool += [self.create_item(name) for name, id in cannon_item_table.items()] + self.multiworld.itempool += [self.create_item(cannon_name) for cannon_name in cannon_item_data_table.keys()] # Moves + double_jump_bitvec_offset = action_item_data_table['Double Jump'].code self.multiworld.itempool += [self.create_item(action) - for action, itemid in action_item_table.items() - if self.move_rando_bitvec & (1 << itemid - action_item_table['Double Jump'])] + for action, itemdata in action_item_data_table.items() + if self.move_rando_bitvec & (1 << itemdata.code - double_jump_bitvec_offset)] def generate_basic(self): if not (self.options.buddy_checks):