From 952d878442112026181a832fb3216dd1d1c81bfd Mon Sep 17 00:00:00 2001 From: Jarno Westhof Date: Sun, 10 Oct 2021 13:05:41 +0200 Subject: [PATCH] Marked items as never exclude + some more refactorings --- worlds/timespinner/Items.py | 105 +++++++++++++++++---------------- worlds/timespinner/__init__.py | 50 ++++++++-------- 2 files changed, 78 insertions(+), 77 deletions(-) diff --git a/worlds/timespinner/Items.py b/worlds/timespinner/Items.py index 8641cb9a..cfa1bc45 100644 --- a/worlds/timespinner/Items.py +++ b/worlds/timespinner/Items.py @@ -5,10 +5,11 @@ class ItemData(NamedTuple): code: int count: int = 1 progression: bool = False + never_exclude: bool = False # A lot of items arent normally dropped by the randomizer as they are mostly enemy drops, but they can be enabled if desired item_table: Dict[str, ItemData] = { - 'Eternal Crown': ItemData('Equipment', 1337000), + 'Eternal Crown': ItemData('Equipment', 1337000, never_exclude=True), 'Security Visor': ItemData('Equipment', 1337001, 0), 'Engineer Goggles': ItemData('Equipment', 1337002, 0), 'Leather Helmet': ItemData('Equipment', 1337003, 0), @@ -21,8 +22,8 @@ item_table: Dict[str, ItemData] = { 'Combat Helmet': ItemData('Equipment', 1337010, 0), 'Captain\'s Cap': ItemData('Equipment', 1337011), 'Lab Glasses': ItemData('Equipment', 1337012), - 'Empire Crown': ItemData('Equipment', 1337013), - 'Viletian Crown': ItemData('Equipment', 1337014), + 'Empire Crown': ItemData('Equipment', 1337013, never_exclude=True), + 'Viletian Crown': ItemData('Equipment', 1337014, never_exclude=True), 'Sunglasses': ItemData('Equipment', 1337015, 0), 'Old Coat': ItemData('Equipment', 1337016), 'Trendy Jacket': ItemData('Equipment', 1337017, 0), @@ -37,26 +38,26 @@ item_table: Dict[str, ItemData] = { 'Military Armor': ItemData('Equipment', 1337026, 0), 'Captain\'s Uniform': ItemData('Equipment', 1337027), 'Lab Coat': ItemData('Equipment', 1337028), - 'Empress Robe': ItemData('Equipment', 1337029), - 'Princess Dress': ItemData('Equipment', 1337030), - 'Eternal Coat': ItemData('Equipment', 1337031), + 'Empress Robe': ItemData('Equipment', 1337029, never_exclude=True), + 'Princess Dress': ItemData('Equipment', 1337030, never_exclude=True), + 'Eternal Coat': ItemData('Equipment', 1337031, never_exclude=True), 'Synthetic Plume': ItemData('Equipment', 1337032, 0), 'Cheveur Plume': ItemData('Equipment', 1337033, 0), 'Metal Wristband': ItemData('Equipment', 1337034), 'Nymph Hairband': ItemData('Equipment', 1337035, 0), 'Mother o\' Pearl': ItemData('Equipment', 1337036, 0), - 'Bird Statue': ItemData('Equipment', 1337037), + 'Bird Statue': ItemData('Equipment', 1337037, never_exclude=True), 'Chaos Stole': ItemData('Equipment', 1337038, 0), - 'Pendulum': ItemData('Equipment', 1337039), + 'Pendulum': ItemData('Equipment', 1337039, never_exclude=True), 'Chaos Horn': ItemData('Equipment', 1337040, 0), - 'Filigree Clasp': ItemData('Equipment', 1337041), + 'Filigree Clasp': ItemData('Equipment', 1337041, never_exclude=True), 'Azure Stole': ItemData('Equipment', 1337042, 0), - 'Ancient Coin': ItemData('Equipment', 1337043), + 'Ancient Coin': ItemData('Equipment', 1337043, never_exclude=True), 'Shiny Rock': ItemData('Equipment', 1337044, 0), - 'Galaxy Earrings': ItemData('Equipment', 1337045), - 'Selen\'s Bangle': ItemData('Equipment', 1337046), - 'Glass Pumpkin': ItemData('Equipment', 1337047), - 'Gilded Egg': ItemData('Equipment', 1337048), + 'Galaxy Earrings': ItemData('Equipment', 1337045, never_exclude=True), + 'Selen\'s Bangle': ItemData('Equipment', 1337046, never_exclude=True), + 'Glass Pumpkin': ItemData('Equipment', 1337047, never_exclude=True), + 'Gilded Egg': ItemData('Equipment', 1337048, never_exclude=True), 'Meyef': ItemData('Familiar', 1337049), 'Griffin': ItemData('Familiar', 1337050), 'Merchant Crow': ItemData('Familiar', 1337051), @@ -134,58 +135,58 @@ item_table: Dict[str, ItemData] = { 'Library Keycard V': ItemData('Relic', 1337123, progression=True), 'Tablet': ItemData('Relic', 1337124, progression=True), 'Elevator Keycard': ItemData('Relic', 1337125, progression=True), - 'Jewelry Box': ItemData('Relic', 1337126), + 'Jewelry Box': ItemData('Relic', 1337126, never_exclude=True), 'Goddess Brooch': ItemData('Relic', 1337127), 'Wyrm Brooch': ItemData('Relic', 1337128), 'Greed Brooch': ItemData('Relic', 1337129), 'Eternal Brooch': ItemData('Relic', 1337130), - 'Blue Orb': ItemData('Orb Melee', 1337131), - 'Blade Orb': ItemData('Orb Melee', 1337132), - 'Fire Orb': ItemData('Orb Melee', 1337133, progression=True), - 'Plasma Orb': ItemData('Orb Melee', 1337134, progression=True), - 'Iron Orb': ItemData('Orb Melee', 1337135), - 'Ice Orb': ItemData('Orb Melee', 1337136), - 'Wind Orb': ItemData('Orb Melee', 1337137), - 'Gun Orb': ItemData('Orb Melee', 1337138), - 'Umbra Orb': ItemData('Orb Melee', 1337139), - 'Empire Orb': ItemData('Orb Melee', 1337140), - 'Eye Orb': ItemData('Orb Melee', 1337141), - 'Blood Orb': ItemData('Orb Melee', 1337142), - 'Forbidden Tome': ItemData('Orb Melee', 1337143), - 'Shattered Orb': ItemData('Orb Melee', 1337144), - 'Nether Orb': ItemData('Orb Melee', 1337145), - 'Radiant Orb': ItemData('Orb Melee', 1337146), - 'Aura Blast': ItemData('Orb Spell', 1337147), - 'Colossal Blade': ItemData('Orb Spell', 1337148), - 'Infernal Flames': ItemData('Orb Spell', 1337149, progression=True), - 'Plasma Geyser': ItemData('Orb Spell', 1337150, progression=True), - 'Colossal Hammer': ItemData('Orb Spell', 1337151), - 'Frozen Spires': ItemData('Orb Spell', 1337152), - 'Storm Eye': ItemData('Orb Spell', 1337153), - 'Arm Cannon': ItemData('Orb Spell', 1337154), - 'Dark Flames': ItemData('Orb Spell', 1337155), - 'Aura Serpent': ItemData('Orb Spell', 1337156), - 'Chaos Blades': ItemData('Orb Spell', 1337157), - 'Crimson Vortex': ItemData('Orb Spell', 1337158), - 'Djinn Inferno': ItemData('Orb Spell', 1337159, progression=True), - 'Bombardment': ItemData('Orb Spell', 1337160), - 'Corruption': ItemData('Orb Spell', 1337161), - 'Lightwall': ItemData('Orb Spell', 1337162, progression=True), - 'Bleak Ring': ItemData('Orb Passive', 1337163), + 'Blue Orb': ItemData('Orb Melee', 1337131, never_exclude=True), + 'Blade Orb': ItemData('Orb Melee', 1337132, never_exclude=True), + 'Fire Orb': ItemData('Orb Melee', 1337133, never_exclude=True, progression=True), + 'Plasma Orb': ItemData('Orb Melee', 1337134, never_exclude=True, progression=True), + 'Iron Orb': ItemData('Orb Melee', 1337135, never_exclude=True), + 'Ice Orb': ItemData('Orb Melee', 1337136, never_exclude=True), + 'Wind Orb': ItemData('Orb Melee', 1337137, never_exclude=True), + 'Gun Orb': ItemData('Orb Melee', 1337138, never_exclude=True), + 'Umbra Orb': ItemData('Orb Melee', 1337139, never_exclude=True), + 'Empire Orb': ItemData('Orb Melee', 1337140, never_exclude=True), + 'Eye Orb': ItemData('Orb Melee', 1337141, never_exclude=True), + 'Blood Orb': ItemData('Orb Melee', 1337142, never_exclude=True), + 'Forbidden Tome': ItemData('Orb Melee', 1337143, never_exclude=True), + 'Shattered Orb': ItemData('Orb Melee', 1337144, never_exclude=True), + 'Nether Orb': ItemData('Orb Melee', 1337145, never_exclude=True), + 'Radiant Orb': ItemData('Orb Melee', 1337146, never_exclude=True), + 'Aura Blast': ItemData('Orb Spell', 1337147, never_exclude=True), + 'Colossal Blade': ItemData('Orb Spell', 1337148, never_exclude=True), + 'Infernal Flames': ItemData('Orb Spell', 1337149, never_exclude=True, progression=True), + 'Plasma Geyser': ItemData('Orb Spell', 1337150, never_exclude=True, progression=True), + 'Colossal Hammer': ItemData('Orb Spell', 1337151, never_exclude=True), + 'Frozen Spires': ItemData('Orb Spell', 1337152, never_exclude=True), + 'Storm Eye': ItemData('Orb Spell', 1337153, never_exclude=True), + 'Arm Cannon': ItemData('Orb Spell', 1337154, never_exclude=True), + 'Dark Flames': ItemData('Orb Spell', 1337155, never_exclude=True), + 'Aura Serpent': ItemData('Orb Spell', 1337156, never_exclude=True), + 'Chaos Blades': ItemData('Orb Spell', 1337157, never_exclude=True), + 'Crimson Vortex': ItemData('Orb Spell', 1337158, never_exclude=True), + 'Djinn Inferno': ItemData('Orb Spell', 1337159, never_exclude=True, progression=True), + 'Bombardment': ItemData('Orb Spell', 1337160, never_exclude=True), + 'Corruption': ItemData('Orb Spell', 1337161, never_exclude=True), + 'Lightwall': ItemData('Orb Spell', 1337162, never_exclude=True, progression=True), + 'Bleak Ring': ItemData('Orb Passive', 1337163, never_exclude=True), 'Scythe Ring': ItemData('Orb Passive', 1337164), - 'Pyro Ring': ItemData('Orb Passive', 1337165, progression=True), - 'Royal Ring': ItemData('Orb Passive', 1337166, progression=True), + 'Pyro Ring': ItemData('Orb Passive', 1337165, never_exclude=True, progression=True), + 'Royal Ring': ItemData('Orb Passive', 1337166, never_exclude=True, progression=True), 'Shield Ring': ItemData('Orb Passive', 1337167), 'Icicle Ring': ItemData('Orb Passive', 1337168), 'Tailwind Ring': ItemData('Orb Passive', 1337169), 'Economizer Ring': ItemData('Orb Passive', 1337170), 'Dusk Ring': ItemData('Orb Passive', 1337171), - 'Star of Lachiem': ItemData('Orb Passive', 1337172), + 'Star of Lachiem': ItemData('Orb Passive', 1337172, never_exclude=True), 'Oculus Ring': ItemData('Orb Passive', 1337173, progression=True), 'Sanguine Ring': ItemData('Orb Passive', 1337174), 'Sun Ring': ItemData('Orb Passive', 1337175), 'Silence Ring': ItemData('Orb Passive', 1337176), - 'Shadow Seal': ItemData('Orb Passive', 1337177), + 'Shadow Seal': ItemData('Orb Passive', 1337177, never_exclude=True), 'Hope Ring': ItemData('Orb Passive', 1337178), 'Max HP': ItemData('Stat', 1337179, 12), 'Max Aura': ItemData('Stat', 1337180, 13), diff --git a/worlds/timespinner/__init__.py b/worlds/timespinner/__init__.py index e58d0d92..468e2b78 100644 --- a/worlds/timespinner/__init__.py +++ b/worlds/timespinner/__init__.py @@ -40,11 +40,11 @@ class TimespinnerWorld(World): def create_item(self, name: str) -> Item: - return create_item(name, self.player) + return create_item_with_correct_settings(self.world, self.player, name) def set_rules(self): - setup_events(self.world, self.player, self.locked_locations[self.player]) + setup_events(self.world, self.player, self.locked_locations[self.player], self.location_cache[self.player]) self.world.completion_condition[self.player] = lambda state: state.has('Killed Nightmare', self.player) @@ -59,7 +59,7 @@ class TimespinnerWorld(World): pool = get_item_pool(self.world, self.player, excluded_items) - fill_item_pool_with_dummy_items(self.world, self.player, self.locked_locations[self.player], pool) + fill_item_pool_with_dummy_items(self.world, self.player, self.locked_locations[self.player], self.location_cache[self.player], pool) self.world.itempool += pool @@ -79,11 +79,6 @@ class TimespinnerWorld(World): return slot_data -def create_item(name: str, player: int) -> Item: - data = item_table[name] - return Item(name, data.progression, data.code, player) - - def get_excluded_items_based_on_options(world: MultiWorld, player: int) -> Set[str]: excluded_items: Set[str] = set() @@ -104,8 +99,8 @@ def assign_starter_items(world: MultiWorld, player: int, excluded_items: Set[str excluded_items.add(melee_weapon) excluded_items.add(spell) - melee_weapon_item = create_item(melee_weapon, player) - spell_item = create_item(spell, player) + melee_weapon_item = create_item_with_correct_settings(world, player, melee_weapon) + spell_item = create_item_with_correct_settings(world, player, spell) world.get_location('Yo Momma 1', player).place_locked_item(melee_weapon_item) world.get_location('Yo Momma 2', player).place_locked_item(spell_item) @@ -120,15 +115,16 @@ def get_item_pool(world: MultiWorld, player: int, excluded_items: Set[str]) -> L for name, data in item_table.items(): if not name in excluded_items: for _ in range(data.count): - item = update_progressive_state_based_flags(world, player, name, create_item(name, player)) + item = create_item_with_correct_settings(world, player, name) pool.append(item) return pool -def fill_item_pool_with_dummy_items(world: MultiWorld, player: int, locked_locations: List[str], pool: List[Item]): - for _ in range(len(get_locations(world, player)) - len(locked_locations) - len(pool)): - item = create_item(world.random.choice(filler_items), player) +def fill_item_pool_with_dummy_items(world: MultiWorld, player: int, locked_locations: List[str], + location_cache: List[Location], pool: List[Item]): + for _ in range(len(location_cache) - len(locked_locations) - len(pool)): + item = create_item_with_correct_settings(world, player, world.random.choice(filler_items)) pool.append(item) @@ -139,27 +135,31 @@ def place_first_progression_item(world: MultiWorld, player: int, excluded_items: excluded_items.add(progression_item) locked_locations.append(location) - item = create_item(progression_item, player) + item = create_item_with_correct_settings(world, player, progression_item) world.get_location(location, player).place_locked_item(item) -def update_progressive_state_based_flags(world: MultiWorld, player: int, name: str, data: Item) -> Item: - if not data.advancement: - return data +def create_item_with_correct_settings(world: MultiWorld, player: int, name: str) -> Item: + data = item_table[name] + + item = Item(name, data.progression, data.code, player) + item.never_exclude = data.never_exclude + + if not item.advancement: + return item if (name == 'Tablet' or name == 'Library Keycard V') and not is_option_enabled(world, player, "DownloadableItems"): - data.advancement = False + item.advancement = False if name == 'Oculus Ring' and not is_option_enabled(world, player, "FacebookMode"): - data.advancement = False + item.advancement = False - return data + return item -def setup_events(world: MultiWorld, player: int, locked_locations: List[str]): - for location in get_locations(world, player): - if location.code == EventId: - location = world.get_location(location.name, player) +def setup_events(world: MultiWorld, player: int, locked_locations: List[str], location_cache: List[Location]): + for location in location_cache: + if location.address == EventId: item = Item(location.name, True, EventId, player) locked_locations.append(location.name)