From 86025745ac76cfc04dd6cc8a46a205bdbd807d31 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sat, 1 Aug 2020 06:22:59 +0200 Subject: [PATCH] reimplement easy item pool Some changes were made. The design chosen is to keep the changes to the same range of changes that hard and expert apply (so no change in lamp count, for example), while trying to keep easy as similar as it was. --- Fill.py | 7 ++++--- ItemList.py | 60 ++++++++++++++++++++++++++++++++++++++++++++--------- easy.yaml | 2 +- 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/Fill.py b/Fill.py index a080c10b..87d56cbc 100644 --- a/Fill.py +++ b/Fill.py @@ -300,10 +300,11 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None fast_fill(world, prioitempool, fill_locations) fast_fill(world, restitempool, fill_locations) + unplaced = [item.name for item in progitempool + prioitempool + restitempool] + unfilled = [location.name for location in fill_locations] - logging.getLogger('').debug('Unplaced items: %s - Unfilled Locations: %s', - [item.name for item in progitempool + prioitempool + restitempool], - [location.name for location in fill_locations]) + if unplaced or unfilled: + logging.warning('Unplaced items: %s - Unfilled Locations: %s', unplaced, unfilled) def fast_fill(world, item_pool, fill_locations): diff --git a/ItemList.py b/ItemList.py index b9e52e5b..6ce98259 100644 --- a/ItemList.py +++ b/ItemList.py @@ -8,17 +8,28 @@ from EntranceShuffle import connect_entrance from Fill import FillError, fill_restrictive from Items import ItemFactory +# This file sets the item pools for various modes. Timed modes and triforce hunt are enforced first, and then extra items are specified per mode to fill in the remaining space. +# Some basic items that various modes require are placed here, including pendants and crystals. Medallion requirements for the two relevant entrances are also decided. -#This file sets the item pools for various modes. Timed modes and triforce hunt are enforced first, and then extra items are specified per mode to fill in the remaining space. -#Some basic items that various modes require are placed here, including pendants and crystals. Medallion requirements for the two relevant entrances are also decided. - -alwaysitems = ['Bombos', 'Book of Mudora', 'Cane of Somaria', 'Ether', 'Fire Rod', 'Flippers', 'Flute', 'Hammer', 'Hookshot', 'Ice Rod', 'Lamp', - 'Cape', 'Magic Powder', 'Mushroom', 'Pegasus Boots', 'Quake', 'Shovel', 'Bug Catching Net', 'Cane of Byrna', 'Blue Boomerang', 'Red Boomerang'] +alwaysitems = ['Bombos', 'Book of Mudora', 'Cane of Somaria', 'Ether', 'Fire Rod', 'Flippers', 'Flute', 'Hammer', + 'Hookshot', 'Ice Rod', 'Lamp', + 'Cape', 'Magic Powder', 'Mushroom', 'Pegasus Boots', 'Quake', 'Shovel', 'Bug Catching Net', + 'Cane of Byrna', 'Blue Boomerang', 'Red Boomerang'] progressivegloves = ['Progressive Glove'] * 2 basicgloves = ['Power Glove', 'Titans Mitts'] -normalbottles = ['Bottle', 'Bottle (Red Potion)', 'Bottle (Green Potion)', 'Bottle (Blue Potion)', 'Bottle (Fairy)', 'Bottle (Bee)', 'Bottle (Good Bee)'] -hardbottles = ['Bottle', 'Bottle (Red Potion)', 'Bottle (Green Potion)', 'Bottle (Blue Potion)', 'Bottle (Bee)', 'Bottle (Good Bee)'] +normalbottles = ['Bottle', 'Bottle (Red Potion)', 'Bottle (Green Potion)', 'Bottle (Blue Potion)', 'Bottle (Fairy)', + 'Bottle (Bee)', 'Bottle (Good Bee)'] +hardbottles = ['Bottle', 'Bottle (Red Potion)', 'Bottle (Green Potion)', 'Bottle (Blue Potion)', 'Bottle (Bee)', + 'Bottle (Good Bee)'] + +easybaseitems = (['Sanctuary Heart Container'] + ['Rupees (300)'] * 4 + ['Magic Upgrade (1/2)'] * 2 + + ['Boss Heart Container'] * 10 + ['Piece of Heart'] * 12) +easyextra = ['Piece of Heart'] * 12 + ['Rupees (300)'] +easyfirst15extra = ['Rupees (100)'] + ['Arrows (10)'] * 7 + ['Bombs (3)'] * 7 +easysecond10extra = ['Bombs (3)'] * 7 + ['Rupee (1)', 'Rupees (50)', 'Bombs (10)'] +easythird5extra = ['Rupees (50)'] * 2 + ['Bombs (3)'] * 2 + ['Arrows (10)'] +easyfinal25extra = ['Rupees (50)'] * 4 + ['Rupees (20)'] * 14 + ['Rupee (1)'] + ['Arrows (10)'] * 4 + ['Rupees (5)'] * 2 normalbaseitems = (['Magic Upgrade (1/2)', 'Single Arrow', 'Sanctuary Heart Container', 'Arrows (10)', 'Bombs (10)'] + ['Rupees (300)'] * 4 + ['Boss Heart Container'] * 10 + ['Piece of Heart'] * 24) @@ -40,8 +51,36 @@ Difficulty = namedtuple('Difficulty', total_items_to_place = 153 difficulties = { + 'easy': Difficulty( + baseitems=easybaseitems, + bottles=normalbottles, + bottle_count=8, + same_bottle=False, + progressiveshield=['Progressive Shield'] * 6, + basicshield=['Blue Shield', 'Red Shield', 'Mirror Shield'] * 2, + progressivearmor=['Progressive Armor'] * 4, + basicarmor=['Blue Mail', 'Red Mail'] * 2, + swordless=['Rupees (20)'] * 8, + progressivesword=['Progressive Sword'] * 8, + basicsword=['Master Sword', 'Tempered Sword', 'Golden Sword', 'Fighter Sword'] * 2, + progressivebow=["Progressive Bow"] * 2, + basicbow=['Bow', 'Silver Bow'] * 2, + timedohko=['Green Clock'] * 25, + timedother=['Green Clock'] * 20 + ['Blue Clock'] * 10 + ['Red Clock'] * 5, + # +5 more Red Clocks if there is room + triforcehunt=['Triforce Piece'] * 30, + retro=['Small Key (Universal)'] * 27, + extras=[easyextra, easyfirst15extra, easysecond10extra, easythird5extra, easyfinal25extra], + progressive_sword_limit=8, + progressive_shield_limit=6, + progressive_armor_limit=2, + progressive_bow_limit=4, + progressive_bottle_limit=8, + boss_heart_container_limit=10, + heart_piece_limit=24, + ), 'normal': Difficulty( - baseitems = normalbaseitems, + baseitems=normalbaseitems, bottles=normalbottles, bottle_count=4, same_bottle=False, @@ -125,9 +164,10 @@ difficulties = { } def generate_itempool(world, player): - if world.difficulty[player] not in ['normal', 'hard', 'expert']: + if world.difficulty[player] not in difficulties: raise NotImplementedError(f"Diffulty {world.difficulty[player]}") - if world.goal[player] not in {'ganon', 'pedestal', 'dungeons', 'triforcehunt', 'localtriforcehunt', 'ganontriforcehunt', 'localganontriforcehunt', 'crystals'}: + if world.goal[player] not in {'ganon', 'pedestal', 'dungeons', 'triforcehunt', 'localtriforcehunt', + 'ganontriforcehunt', 'localganontriforcehunt', 'crystals'}: raise NotImplementedError(f"Goal {world.goal[player]}") if world.mode[player] not in {'open', 'standard', 'inverted'}: raise NotImplementedError(f"Mode {world.mode[player]}") diff --git a/easy.yaml b/easy.yaml index 98d296d3..afb48b6a 100644 --- a/easy.yaml +++ b/easy.yaml @@ -24,7 +24,6 @@ glitches_required: # Determine the logic required to complete the seed minor_glitches: 0 # puts fake flipper and super bunny shenanigans into logic overworld_glitches: 0 # Assumes the player knows how to perform overworld glitches like fake flipper, water walk, etc no_logic: 0 # Items are places completely at random and with no regard for logic. Your fire rod could be on Trinexx -item_placement: basic # This is based on Entrance Randomizer, which does not (yet?) support advanced meta_ignore: # Nullify options specified in the meta.yaml file. Adding an option here guarantees it will not occur in your seed, even if the .yaml file specifies it world_state: - inverted # Never play inverted seeds @@ -134,6 +133,7 @@ weapons: # Specifically, swords vanilla: 0 # Swords are placed in vanilla locations in your own game (Uncle, Pyramid Fairy, Smiths, Pedestal) swordless: 0 # Your swords are replaced by rupees. Gameplay changes have been made to accommodate this change. item_pool: + easy: 0 # doubled upgrades, progressives etc. normal: 1 # Item availability remains unchanged from the vanilla game hard: 0 # Reduced upgrade availability (max: 14 hearts, green mail, tempered sword, fire shield, no silvers unless swordless) expert: 0 # Minimum upgrade availability (max: 8 hearts, green mail, master sword, fighter shield, no silvers unless swordless)