diff --git a/worlds/pizzatower/Items.py b/worlds/pizzatower/Items.py index 0fcb149b2c62..69969584ec90 100644 --- a/worlds/pizzatower/Items.py +++ b/worlds/pizzatower/Items.py @@ -1,9 +1,10 @@ import math +from dataclasses import dataclass from BaseClasses import Item, ItemClassification, MultiWorld from .Names import * -from typing import Dict, NamedTuple, Optional - +from typing import NamedTuple, Optional +from .Options import * class ItemData(NamedTuple): code: Optional[int] @@ -18,12 +19,12 @@ class PizzaTowerItem(Item): game: str = "Pizza Tower" -def create_item(world: MultiWorld, name: str, player: int) -> PizzaTowerItem: +def create_item(world: MultiWorld, name: str, player: int, world_options: PizzaTowerOptions) -> PizzaTowerItem: item_data = item_table[name] if item_data.required: classification = ItemClassification.progression elif item_data.treasure: - if world.john[player].value: + if world_options.john: classification = ItemClassification.progression else: classification = ItemClassification.useful @@ -37,11 +38,11 @@ def create_item(world: MultiWorld, name: str, player: int) -> PizzaTowerItem: return item -def create_all_items(world: MultiWorld, player: int) -> None: +def create_all_items(world: MultiWorld, player: int, world_options: PizzaTowerOptions) -> None: exclude = [item for item in world.precollected_items[player]] exclude.append(world.create_item("Victory", player)) - if world.boss_keys[player].value == 0: + if world_options.boss_keys.value == 0: exclude.append(world.create_item(pepperman + " Boss Key", player)) exclude.append(world.create_item(vigilante + " Boss Key", player)) exclude.append(world.create_item(noise + " Boss Key", player)) @@ -57,31 +58,31 @@ def create_all_items(world: MultiWorld, player: int) -> None: if item not in exclude: world.itempool.append(item) - if world.treasure_check[player].value: + if world_options.treasure_check: for name, data in treasure_table.items(): item = world.create_item(name, player) if item not in exclude: world.itempool.append(item) - if world.pumpkin_hunt[player].value: + if world_options.pumpkin_hunt: for name, data in pumpkin_table.items(): item = world.create_item(name, player) if item not in exclude: world.itempool.append(item) - if world.secret_eye_check[player].value: + if world_options.secret_eye_check: for name, data in secret_table.items(): item = world.create_item(name, player) if item not in exclude: world.itempool.append(item) - junk_count = 21 + junk_count = 22 trap_weights = [] - trap_weights += (["Stun Trap"] * world.timer_trap[player].value) - trap_weights += (["Timer Trap"] * world.stun_trap[player].value) - trap_weights += (["Transformation Trap"] * world.transformation_trap[player].value) + trap_weights += (["Stun Trap"] * world_options.timer_trap.value) + trap_weights += (["Timer Trap"] * world_options.stun_trap.value) + trap_weights += (["Transformation Trap"] * world_options.transformation_trap.value) trap_count = 0 if (len(trap_weights) == 0) else math.ceil( - junk_count * (world.trap_fill_percentage[player].value / 100.0)) + junk_count * (world_options.trap_fill_percentage / 100.0)) junk_count -= trap_count trap_pool = [] diff --git a/worlds/pizzatower/Locations.py b/worlds/pizzatower/Locations.py index 1146b68b3c35..88b881ff3aca 100644 --- a/worlds/pizzatower/Locations.py +++ b/worlds/pizzatower/Locations.py @@ -1,5 +1,6 @@ from BaseClasses import Location import typing +from dataclasses import dataclass from .Names import * diff --git a/worlds/pizzatower/Options.py b/worlds/pizzatower/Options.py index 1909af3befa4..b547d99ce512 100644 --- a/worlds/pizzatower/Options.py +++ b/worlds/pizzatower/Options.py @@ -1,5 +1,6 @@ +from dataclasses import dataclass import typing -from Options import Choice, Toggle, Option, DeathLink, Range +from Options import Choice, Toggle, DeathLink, Range, PerGameCommonOptions class BaseTrapWeight(Choice): @@ -113,24 +114,24 @@ class TowerSecretEye(Toggle): display_name = "Secrets" -pizza_tower_options: typing.Dict[str, type(Option)] = { - "death_link": DeathLink, +@dataclass +class PizzaTowerOptions(PerGameCommonOptions): + death_link: DeathLink - "boss_keys": BossKeys, - "treasure_check": TowerSecretTreasure, - "secret_eye_check": TowerSecretEye, - "pumpkin_hunt": PumpkinHunt, + boss_keys: BossKeys + treasure_check: TowerSecretTreasure + secret_eye_check: TowerSecretEye + pumpkin_hunt: PumpkinHunt - "timer_trap": TimerTrap, - "timer_reduce": TimerTrapReduce, - "stun_trap": StunTrap, - "transformation_trap": TransformationTrap, - "transformation_time": TransformationTrapTime, - "trap_fill_percentage": TrapFillPercentage, + timer_trap: TimerTrap + timer_reduce: TimerTrapReduce + stun_trap: StunTrap + transformation_trap: TransformationTrap + transformation_time: TransformationTrapTime + trap_fill_percentage: TrapFillPercentage - "shuffle_level": LevelShuffle, + shuffle_level: LevelShuffle - "rank_needed": RankRequirement, - "goal": JudgementRequirement, - "john": JohnNeeded, -} + rank_needed: RankRequirement + goal: JudgementRequirement + john: JohnNeeded diff --git a/worlds/pizzatower/Regions.py b/worlds/pizzatower/Regions.py index 1d288b313e82..74b196926f6a 100644 --- a/worlds/pizzatower/Regions.py +++ b/worlds/pizzatower/Regions.py @@ -1,17 +1,18 @@ from BaseClasses import MultiWorld, Region, Entrance from .Names import * from .Locations import location_table, LocationData, PizzaTowerLocation +from .Options import * -def create_region(world: MultiWorld, player: int, name: str, exits=None): +def create_region(world: MultiWorld, player: int, name: str, world_options: PizzaTowerOptions, exits=None): region = Region(name, player, world) loc_name: str location: LocationData for loc_name in location_table: if location_table[loc_name].region == name: - is_treasure_allowed = (not location_table[loc_name].treasure) or world.treasure_check[player].value - is_secret_allowed = (not location_table[loc_name].secret) or world.secret_eye_check[player].value - is_pumpkin_allowed = (not location_table[loc_name].pumpkin) or world.pumpkin_hunt[player].value + is_treasure_allowed = (not location_table[loc_name].treasure) or bool(world_options.treasure_check.value) + is_secret_allowed = (not location_table[loc_name].secret) or bool(world_options.secret_eye_check.value) + is_pumpkin_allowed = (not location_table[loc_name].pumpkin) or bool(world_options.pumpkin_hunt.value) if is_treasure_allowed and is_secret_allowed and is_pumpkin_allowed: region.locations.append(PizzaTowerLocation(player, loc_name, location_table[loc_name].id, region)) @@ -22,14 +23,14 @@ def create_region(world: MultiWorld, player: int, name: str, exits=None): return region -def create_regions(world: MultiWorld, player: int): +def create_regions(world: MultiWorld, player: int, world_options: PizzaTowerOptions): for region_name in pizza_tower_regions: - world.regions.append(create_region(world, player, region_name, pizza_tower_regions[region_name])) + world.regions.append(create_region(world, player, region_name, world_options, pizza_tower_regions[region_name])) for region_exit in mandatory_connections: world.get_entrance(region_exit, player) \ .connect(world.get_region(mandatory_connections[region_exit], player)) - if world.shuffle_level[player].value: + if world_options.shuffle_level: entrances = list(default_connections.keys()) regions = list(default_connections.values()) world.random.shuffle(regions) diff --git a/worlds/pizzatower/Rules.py b/worlds/pizzatower/Rules.py index 4854943f4c2c..9270519e481b 100644 --- a/worlds/pizzatower/Rules.py +++ b/worlds/pizzatower/Rules.py @@ -1,9 +1,10 @@ from BaseClasses import MultiWorld from ..generic.Rules import add_rule from .Names import * +from .Options import * -def set_rules(world: MultiWorld, player: int): +def set_rules(world: MultiWorld, player: int, world_options: PizzaTowerOptions): world.completion_condition[player] = lambda state: \ state.has("Victory", player) @@ -31,6 +32,6 @@ def set_rules(world: MultiWorld, player: int): lambda state: state.count_group("pumpkins", player) >= 20) add_rule(world.get_location("Escape " + trickytreat, player), - lambda state: world.pumpkin_hunt[player].value) + lambda state: bool(world_options.pumpkin_hunt.value)) add_rule(world.get_location("Escape " + secretlevel, player), - lambda state: world.secret_eye_check[player].value) + lambda state: bool(world_options.secret_eye_check.value)) diff --git a/worlds/pizzatower/__init__.py b/worlds/pizzatower/__init__.py index d63dccb3a9e8..f399b0e104af 100644 --- a/worlds/pizzatower/__init__.py +++ b/worlds/pizzatower/__init__.py @@ -1,7 +1,7 @@ from BaseClasses import Tutorial from .Rules import set_rules from ..AutoWorld import World, WebWorld -from .Options import pizza_tower_options +from .Options import PizzaTowerOptions from .Items import item_table, PizzaTowerItem, toppin_table, pumpkin_table, treasure_table from .Locations import PizzaTowerLocation, location_table from . import Options, Items, Locations, Regions, Rules @@ -29,7 +29,8 @@ class PizzaTowerWorld(World): escape sequences, and bosses.""" game = "Pizza Tower" - option_definitions = pizza_tower_options + options_dataclass = PizzaTowerOptions + options: PizzaTowerOptions web = PizzaTowerWeb() item_name_to_id = {name: data.code for name, data in item_table.items()} @@ -45,35 +46,36 @@ class PizzaTowerWorld(World): "pumpkins": set(pumpkin_table.keys()) } - def get_option(self, name): - return getattr(self.multiworld, name)[self.player].value - def fill_slot_data(self): - slot_data = {} - - for option_name in self.option_definitions: - slot_data[option_name] = self.get_option(option_name) - - return slot_data + return { + "death_link": self.options.death_link.value, + "treasure_check": self.options.treasure_check.value, + "secret_eye_check": self.options.secret_eye_check.value, + "pumpkin_hunt": self.options.pumpkin_hunt.value, + "shuffle_level": self.options.shuffle_level.value, + "rank_needed": self.options.rank_needed.value, + "goal": self.options.goal.value, + "john": self.options.john.value + } def create_item(self, name: str) -> PizzaTowerItem: - return Items.create_item(self.multiworld, name, self.player) + return Items.create_item(self.multiworld, name, self.player, self.options) def create_regions(self) -> None: - create_regions(self.multiworld, self.player) + create_regions(self.multiworld, self.player, self.options) def create_items(self) -> None: - Items.create_all_items(self.multiworld, self.player) + Items.create_all_items(self.multiworld, self.player, self.options) def set_rules(self) -> None: - set_rules(self.multiworld, self.player) + set_rules(self.multiworld, self.player, self.options) def generate_basic(self) -> None: world = self.multiworld victory_item = world.create_item("Victory", self.player) self.multiworld.get_location("Escape " + tower, self.player).place_locked_item(victory_item) - if world.boss_keys[self.player].value == 0: + if self.options.boss_keys.value == 0: pepperman_key = world.create_item(pepperman + " Boss Key", self.player) self.multiworld.get_location("Defeat " + pepperman, self.player).place_locked_item(pepperman_key) vigilante_key = world.create_item(vigilante + " Boss Key", self.player)