LTTP: sort of use new options system (#3764)

* LttP: switch to dataclass options definition

* LttP: write old options onto multiworld
LttP: use World.random
This commit is contained in:
Fabian Dill 2024-11-29 05:02:26 +01:00 committed by GitHub
parent ce210cd4ee
commit 30b414429f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 109 additions and 101 deletions

View File

@ -1,7 +1,7 @@
import typing
from dataclasses import dataclass
from BaseClasses import MultiWorld
from Options import Choice, Range, DeathLink, DefaultOnToggle, FreeText, ItemsAccessibility, Option, \
from Options import Choice, Range, DeathLink, DefaultOnToggle, FreeText, ItemsAccessibility, PerGameCommonOptions, \
PlandoBosses, PlandoConnections, PlandoTexts, Removed, StartInventoryPool, Toggle
from .EntranceShuffle import default_connections, default_dungeon_connections, \
inverted_default_connections, inverted_default_dungeon_connections
@ -742,86 +742,86 @@ class ALttPPlandoTexts(PlandoTexts):
valid_keys = TextTable.valid_keys
alttp_options: typing.Dict[str, type(Option)] = {
"accessibility": ItemsAccessibility,
"plando_connections": ALttPPlandoConnections,
"plando_texts": ALttPPlandoTexts,
"start_inventory_from_pool": StartInventoryPool,
"goal": Goal,
"mode": Mode,
"glitches_required": GlitchesRequired,
"dark_room_logic": DarkRoomLogic,
"open_pyramid": OpenPyramid,
"crystals_needed_for_gt": CrystalsTower,
"crystals_needed_for_ganon": CrystalsGanon,
"triforce_pieces_mode": TriforcePiecesMode,
"triforce_pieces_percentage": TriforcePiecesPercentage,
"triforce_pieces_required": TriforcePiecesRequired,
"triforce_pieces_available": TriforcePiecesAvailable,
"triforce_pieces_extra": TriforcePiecesExtra,
"entrance_shuffle": EntranceShuffle,
"entrance_shuffle_seed": EntranceShuffleSeed,
"big_key_shuffle": big_key_shuffle,
"small_key_shuffle": small_key_shuffle,
"key_drop_shuffle": key_drop_shuffle,
"compass_shuffle": compass_shuffle,
"map_shuffle": map_shuffle,
"restrict_dungeon_item_on_boss": RestrictBossItem,
"item_pool": ItemPool,
"item_functionality": ItemFunctionality,
"enemy_health": EnemyHealth,
"enemy_damage": EnemyDamage,
"progressive": Progressive,
"swordless": Swordless,
"dungeon_counters": DungeonCounters,
"retro_bow": RetroBow,
"retro_caves": RetroCaves,
"hints": Hints,
"scams": Scams,
"boss_shuffle": LTTPBosses,
"pot_shuffle": PotShuffle,
"enemy_shuffle": EnemyShuffle,
"killable_thieves": KillableThieves,
"bush_shuffle": BushShuffle,
"shop_item_slots": ShopItemSlots,
"randomize_shop_inventories": RandomizeShopInventories,
"shuffle_shop_inventories": ShuffleShopInventories,
"include_witch_hut": IncludeWitchHut,
"randomize_shop_prices": RandomizeShopPrices,
"randomize_cost_types": RandomizeCostTypes,
"shop_price_modifier": ShopPriceModifier,
"shuffle_capacity_upgrades": ShuffleCapacityUpgrades,
"bombless_start": BomblessStart,
"shuffle_prizes": ShufflePrizes,
"tile_shuffle": TileShuffle,
"misery_mire_medallion": MiseryMireMedallion,
"turtle_rock_medallion": TurtleRockMedallion,
"glitch_boots": GlitchBoots,
"beemizer_total_chance": BeemizerTotalChance,
"beemizer_trap_chance": BeemizerTrapChance,
"timer": Timer,
"countdown_start_time": CountdownStartTime,
"red_clock_time": RedClockTime,
"blue_clock_time": BlueClockTime,
"green_clock_time": GreenClockTime,
"death_link": DeathLink,
"allow_collect": AllowCollect,
"ow_palettes": OWPalette,
"uw_palettes": UWPalette,
"hud_palettes": HUDPalette,
"sword_palettes": SwordPalette,
"shield_palettes": ShieldPalette,
# "link_palettes": LinkPalette,
"heartbeep": HeartBeep,
"heartcolor": HeartColor,
"quickswap": QuickSwap,
"menuspeed": MenuSpeed,
"music": Music,
"reduceflashing": ReduceFlashing,
"triforcehud": TriforceHud,
@dataclass
class ALTTPOptions(PerGameCommonOptions):
accessibility: ItemsAccessibility
plando_connections: ALttPPlandoConnections
plando_texts: ALttPPlandoTexts
start_inventory_from_pool: StartInventoryPool
goal: Goal
mode: Mode
glitches_required: GlitchesRequired
dark_room_logic: DarkRoomLogic
open_pyramid: OpenPyramid
crystals_needed_for_gt: CrystalsTower
crystals_needed_for_ganon: CrystalsGanon
triforce_pieces_mode: TriforcePiecesMode
triforce_pieces_percentage: TriforcePiecesPercentage
triforce_pieces_required: TriforcePiecesRequired
triforce_pieces_available: TriforcePiecesAvailable
triforce_pieces_extra: TriforcePiecesExtra
entrance_shuffle: EntranceShuffle
entrance_shuffle_seed: EntranceShuffleSeed
big_key_shuffle: big_key_shuffle
small_key_shuffle: small_key_shuffle
key_drop_shuffle: key_drop_shuffle
compass_shuffle: compass_shuffle
map_shuffle: map_shuffle
restrict_dungeon_item_on_boss: RestrictBossItem
item_pool: ItemPool
item_functionality: ItemFunctionality
enemy_health: EnemyHealth
enemy_damage: EnemyDamage
progressive: Progressive
swordless: Swordless
dungeon_counters: DungeonCounters
retro_bow: RetroBow
retro_caves: RetroCaves
hints: Hints
scams: Scams
boss_shuffle: LTTPBosses
pot_shuffle: PotShuffle
enemy_shuffle: EnemyShuffle
killable_thieves: KillableThieves
bush_shuffle: BushShuffle
shop_item_slots: ShopItemSlots
randomize_shop_inventories: RandomizeShopInventories
shuffle_shop_inventories: ShuffleShopInventories
include_witch_hut: IncludeWitchHut
randomize_shop_prices: RandomizeShopPrices
randomize_cost_types: RandomizeCostTypes
shop_price_modifier: ShopPriceModifier
shuffle_capacity_upgrades: ShuffleCapacityUpgrades
bombless_start: BomblessStart
shuffle_prizes: ShufflePrizes
tile_shuffle: TileShuffle
misery_mire_medallion: MiseryMireMedallion
turtle_rock_medallion: TurtleRockMedallion
glitch_boots: GlitchBoots
beemizer_total_chance: BeemizerTotalChance
beemizer_trap_chance: BeemizerTrapChance
timer: Timer
countdown_start_time: CountdownStartTime
red_clock_time: RedClockTime
blue_clock_time: BlueClockTime
green_clock_time: GreenClockTime
death_link: DeathLink
allow_collect: AllowCollect
ow_palettes: OWPalette
uw_palettes: UWPalette
hud_palettes: HUDPalette
sword_palettes: SwordPalette
shield_palettes: ShieldPalette
# link_palettes: LinkPalette
heartbeep: HeartBeep
heartcolor: HeartColor
quickswap: QuickSwap
menuspeed: MenuSpeed
music: Music
reduceflashing: ReduceFlashing
triforcehud: TriforceHud
# removed:
"goals": Removed,
"smallkey_shuffle": Removed,
"bigkey_shuffle": Removed,
}
goals: Removed
smallkey_shuffle: Removed
bigkey_shuffle: Removed

View File

@ -782,8 +782,8 @@ def get_nonnative_item_sprite(code: int) -> int:
def patch_rom(world: MultiWorld, rom: LocalRom, player: int, enemized: bool):
local_random = world.per_slot_randoms[player]
local_world = world.worlds[player]
local_random = local_world.random
# patch items
@ -1867,7 +1867,7 @@ def apply_oof_sfx(rom, oof: str):
def apply_rom_settings(rom, beep, color, quickswap, menuspeed, music: bool, sprite: str, oof: str, palettes_options,
world=None, player=1, allow_random_on_event=False, reduceflashing=False,
triforcehud: str = None, deathlink: bool = False, allowcollect: bool = False):
local_random = random if not world else world.per_slot_randoms[player]
local_random = random if not world else world.worlds[player].random
disable_music: bool = not music
# enable instant item menu
if menuspeed == 'instant':
@ -2197,8 +2197,9 @@ def write_string_to_rom(rom, target, string):
def write_strings(rom, world, player):
from . import ALTTPWorld
local_random = world.per_slot_randoms[player]
w: ALTTPWorld = world.worlds[player]
local_random = w.random
tt = TextTable()
tt.removeUnwantedText()
@ -2425,7 +2426,7 @@ def write_strings(rom, world, player):
if world.worlds[player].has_progressive_bows and (w.difficulty_requirements.progressive_bow_limit >= 2 or (
world.swordless[player] or world.glitches_required[player] == 'no_glitches')):
prog_bow_locs = world.find_item_locations('Progressive Bow', player, True)
world.per_slot_randoms[player].shuffle(prog_bow_locs)
local_random.shuffle(prog_bow_locs)
found_bow = False
found_bow_alt = False
while prog_bow_locs and not (found_bow and found_bow_alt):

View File

@ -1,28 +1,27 @@
import logging
import os
import random
import settings
import threading
import typing
import Utils
import settings
from BaseClasses import Item, CollectionState, Tutorial, MultiWorld
from worlds.AutoWorld import World, WebWorld, LogicMixin
from .Client import ALTTPSNIClient
from .Dungeons import create_dungeons, Dungeon
from .EntranceShuffle import link_entrances, link_inverted_entrances, plando_connect
from .InvertedRegions import create_inverted_regions, mark_dark_world_regions
from .ItemPool import generate_itempool, difficulties
from .Items import item_init_table, item_name_groups, item_table, GetBeemizerItem
from .Options import alttp_options, small_key_shuffle
from .Options import ALTTPOptions, small_key_shuffle
from .Regions import lookup_name_to_id, create_regions, mark_light_world_regions, lookup_vanilla_location_to_entrance, \
is_main_entrance, key_drop_data
from .Client import ALTTPSNIClient
from .Rom import LocalRom, patch_rom, patch_race_rom, check_enemizer, patch_enemizer, apply_rom_settings, \
get_hash_string, get_base_rom_path, LttPDeltaPatch
from .Rules import set_rules
from .Shops import create_shops, Shop, push_shop_inventories, ShopType, price_rate_display, price_type_display_name
from .SubClasses import ALttPItem, LTTPRegionType
from worlds.AutoWorld import World, WebWorld, LogicMixin
from .StateHelpers import can_buy_unlimited
from .SubClasses import ALttPItem, LTTPRegionType
lttp_logger = logging.getLogger("A Link to the Past")
@ -132,7 +131,8 @@ class ALTTPWorld(World):
Ganon!
"""
game = "A Link to the Past"
option_definitions = alttp_options
options_dataclass = ALTTPOptions
options: ALTTPOptions
settings_key = "lttp_options"
settings: typing.ClassVar[ALTTPSettings]
topology_present = True
@ -286,13 +286,22 @@ class ALTTPWorld(World):
if not os.path.exists(rom_file):
raise FileNotFoundError(rom_file)
if multiworld.is_race:
import xxtea
import xxtea # noqa
for player in multiworld.get_game_players(cls.game):
if multiworld.worlds[player].use_enemizer:
check_enemizer(multiworld.worlds[player].enemizer_path)
break
def generate_early(self):
# write old options
import dataclasses
is_first = self.player == min(self.multiworld.get_game_players(self.game))
for field in dataclasses.fields(self.options_dataclass):
if is_first:
setattr(self.multiworld, field.name, {})
getattr(self.multiworld, field.name)[self.player] = getattr(self.options, field.name)
# end of old options re-establisher
player = self.player
multiworld = self.multiworld
@ -536,12 +545,10 @@ class ALTTPWorld(World):
@property
def use_enemizer(self) -> bool:
world = self.multiworld
player = self.player
return bool(world.boss_shuffle[player] or world.enemy_shuffle[player]
or world.enemy_health[player] != 'default' or world.enemy_damage[player] != 'default'
or world.pot_shuffle[player] or world.bush_shuffle[player]
or world.killable_thieves[player])
return bool(self.options.boss_shuffle or self.options.enemy_shuffle
or self.options.enemy_health != 'default' or self.options.enemy_damage != 'default'
or self.options.pot_shuffle or self.options.bush_shuffle
or self.options.killable_thieves)
def generate_output(self, output_directory: str):
multiworld = self.multiworld