Super Mario 64: ItemData class and tables (#4321)

* sm64ex: use item data class

* rearrange imports

* Dict to dict

* remove optional typing

* bonus item descriptions since we can also add stuff for webworld easily

* remove item descriptions (rip) and decrease verbosity for classifications

* formatting
This commit is contained in:
josephwhite
2025-03-08 12:07:50 -05:00
committed by GitHub
parent 54094c6331
commit ce34b60712
4 changed files with 61 additions and 53 deletions

View File

@@ -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"
class SM64ItemData(NamedTuple):
code: int | None = None
classification: ItemClassification = ItemClassification.progression
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
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_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
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),
}
item_table = {**generic_item_table, **action_item_table, **cannon_item_table}
item_data_table = {
**generic_item_data_table,
**action_item_data_table,
**cannon_item_data_table
}
item_table = {name: data.code for name, data in item_data_table.items() if data.code is not None}

View File

@@ -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 = [

View File

@@ -6,7 +6,7 @@ from .Locations import location_table
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 @@ class RuleFactory:
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

View File

@@ -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
@@ -65,9 +65,10 @@ class SM64World(World):
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)
@@ -100,14 +101,8 @@ class SM64World(World):
'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
@@ -131,11 +126,12 @@ class SM64World(World):
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):