diff --git a/ItemList.py b/ItemList.py index 32da56cc..ecff7555 100644 --- a/ItemList.py +++ b/ItemList.py @@ -287,6 +287,42 @@ def generate_itempool(world, player): for _ in range(0, amt): pool.append('Rupees (20)') + if world.shopsanity[player] and not skip_pool_adjustments: + for shop in world.shops[player]: + if shop.region.name in shop_to_location_table: + for index, slot in enumerate(shop.inventory): + if slot: + item = slot['item'] + if shop.region.name == 'Capacity Upgrade' and world.difficulty[player] != 'normal': + pool.append('Rupees (20)') + else: + pool.append(item) + + if (world.customizer and world.customizer.get_item_pool_adjust() + and player in world.customizer.get_item_pool_adjust()): + diff = difficulties[world.difficulty[player]] + for item_name, delta in world.customizer.get_item_pool_adjust()[player].items(): + if not isinstance(delta, int): + continue + if delta > 0: + if item_name == 'Bottle (Random)': + for _ in range(delta): + pool.append(random.choice(diff.bottles)) + else: + pool.extend([item_name] * delta) + elif delta < 0: + remove_count = abs(delta) + if item_name == 'Bottle (Random)': + bottle_names = set(diff.bottles) + for _ in range(remove_count): + bottle = next((x for x in pool if x in bottle_names), None) + if bottle: + pool.remove(bottle) + else: + for _ in range(remove_count): + if item_name in pool: + pool.remove(item_name) + if world.logic[player] == 'hybridglitches' and world.pottery[player] not in ['none', 'cave']: # In HMG force swamp smalls in pots to allow getting out of swamp palace placed_items['Swamp Palace - Trench 1 Pot Key'] = 'Small Key (Swamp Palace)' @@ -329,17 +365,6 @@ def generate_itempool(world, player): world.get_location(location, player).event = True world.get_location(location, player).locked = True - if world.shopsanity[player] and not skip_pool_adjustments: - for shop in world.shops[player]: - if shop.region.name in shop_to_location_table: - for index, slot in enumerate(shop.inventory): - if slot: - item = slot['item'] - if shop.region.name == 'Capacity Upgrade' and world.difficulty[player] != 'normal': - pool.append('Rupees (20)') - else: - pool.append(item) - items = ItemFactory(pool, player) if world.shopsanity[player]: for potion in ['Green Potion', 'Blue Potion', 'Red Potion']: diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 0a098615..af6ac06b 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -2,5 +2,6 @@ * 1.5.6 * Multiworld: Fixed a generation crash when beemizer is active and pottery is enabled. Pot locations are now properly filled with same-player items when the MW limit is hit even when beemizer has replaced native pot items. + * Customizer: Added `item_pool_adjust` section to apply additive/subtractive deltas to the base item pool rather than replacing it entirely. diff --git a/docs/Customizer.md b/docs/Customizer.md index 2c76da96..b8b7af28 100644 --- a/docs/Customizer.md +++ b/docs/Customizer.md @@ -64,10 +64,30 @@ Then each player can have the entire item pool defined. The name of item should `Bottle (Random)` is supported to randomize bottle contents according to those allowed by difficulty. Pendants and crystals are supported here. -##### Caveat - +**Note**: `item_pool` is a **full replacement** of the base item pool. Every item the player will receive must be listed. If you only want to tweak the default pool, use `item_pool_adjust` instead. + +##### Caveat + Dungeon items amount can be increased (but not decreased as the minimum of each dungeon item is either pre-determined or calculated by door rando) if the type of dungeon item is not shuffled then it is attempted to be placed in the dungeon. Extra item beyond dungeon capacity not be confined to the dungeon. +### item_pool_adjust + +This must be defined by player. Each player number should be listed with the appropriate adjustments. + +Unlike `item_pool`, this section **adjusts** the base item pool generated by the randomizer settings rather than replacing it. Use positive values to add items and negative values to remove items. + +```yaml +item_pool_adjust: + 1: + Bottle (Random): 2 # add 2 extra random bottles + Rupees (300): 1 # add 1 extra rupee pack + Boss Heart Container: -3 # remove 3 heart containers from the base pool +``` + +`Bottle (Random)` follows the same bottle randomization rules as in `item_pool`. When removing bottles with `Bottle (Random): -N`, any bottle (regardless of contents) will be removed. + +Removals that exceed the number of that item currently in the pool are silently ignored. Item pool adjustments are applied after beemizer but before the standard-mode Link's Uncle weapon selection, so weapons added here are eligible for that placement. + ### placements This must be defined by player. Each player number should be listed with the appropriate placement list. diff --git a/docs/customizer_example.yaml b/docs/customizer_example.yaml index 82f3fb7b..17c6f90c 100644 --- a/docs/customizer_example.yaml +++ b/docs/customizer_example.yaml @@ -60,6 +60,11 @@ item_pool: Green Potion: 1 Blue Potion: 1 Red Potion: 1 +item_pool_adjust: + 1: + Bottle (Random): 2 # add 2 extra random bottles on top of the base pool + Magic Upgrade (1/2): 1 # add 1 extra half-magic + Boss Heart Container: -3 # remove 3 heart containers from the base pool placements: 1: Palace of Darkness - Big Chest: Hammer diff --git a/source/classes/CustomSettings.py b/source/classes/CustomSettings.py index a9ef34d9..80b25d44 100644 --- a/source/classes/CustomSettings.py +++ b/source/classes/CustomSettings.py @@ -202,6 +202,11 @@ class CustomSettings(object): return self.file_source['item_pool'] return None + def get_item_pool_adjust(self): + if 'item_pool_adjust' in self.file_source: + return self.file_source['item_pool_adjust'] + return None + def get_placements(self): if 'placements' in self.file_source: return self.file_source['placements']