Lighter pottery modes

This commit is contained in:
aerinon
2022-02-16 14:02:21 -07:00
parent 76aed82843
commit ccb7ced735
13 changed files with 48 additions and 20 deletions

View File

@@ -2755,7 +2755,7 @@ mixed_travel_mode = {"prevent": 0, "allow": 1, "force": 2}
# new byte 4: ?DDD PPPP (unused, drop, pottery) # new byte 4: ?DDD PPPP (unused, drop, pottery)
# dropshuffle reserves 2 bits, pottery needs 2 but reserves 2 for future modes) # dropshuffle reserves 2 bits, pottery needs 2 but reserves 2 for future modes)
pottery_mode = {"none": 0, "shuffle": 1, "keys": 2, "lottery": 3} pottery_mode = {"none": 0, "shuffle": 1, "keys": 2, "lottery": 3, 'dungeon': 4, 'cave': 5}
# byte 5: CCCC CTTX (crystals gt, ctr2, experimental) # byte 5: CCCC CTTX (crystals gt, ctr2, experimental)
counter_mode = {"default": 0, "off": 1, "on": 2, "pickup": 3} counter_mode = {"default": 0, "off": 1, "on": 2, "pickup": 3}

View File

@@ -1002,7 +1002,7 @@ def cross_dungeon(world, player):
target_items += 29 # small keys in chests target_items += 29 # small keys in chests
if world.dropshuffle[player]: if world.dropshuffle[player]:
target_items += 14 # 13 dropped smalls + 1 big target_items += 14 # 13 dropped smalls + 1 big
if world.pottery[player] != 'none': if world.pottery[player] not in ['none', 'cave']:
target_items += 19 # 19 pot keys target_items += 19 # 19 pot keys
d_items = target_items - all_dungeon_items_cnt d_items = target_items - all_dungeon_items_cnt
world.pool_adjustment[player] = d_items world.pool_adjustment[player] = d_items
@@ -1064,7 +1064,7 @@ def assign_cross_keys(dungeon_builders, world, player):
remaining = 29 remaining = 29
if world.dropshuffle[player]: if world.dropshuffle[player]:
remaining += 13 remaining += 13
if world.pottery[player] in ['keys', 'lottery']: if world.pottery[player] not in ['none', 'cave']:
remaining += 19 remaining += 19
else: else:
remaining = len(list(x for dgn in world.dungeons if dgn.player == player for x in dgn.small_keys)) remaining = len(list(x for dgn in world.dungeons if dgn.player == player for x in dgn.small_keys))

View File

@@ -5,7 +5,7 @@ import RaceRandom as random
from BaseClasses import Region, RegionType, Shop, ShopType, Location, CollectionState, PotItem from BaseClasses import Region, RegionType, Shop, ShopType, Location, CollectionState, PotItem
from EntranceShuffle import connect_entrance from EntranceShuffle import connect_entrance
from Regions import shop_to_location_table, retro_shops, shop_table_by_location from Regions import shop_to_location_table, retro_shops, shop_table_by_location, valid_pot_location
from Fill import FillError, fill_restrictive, fast_fill, get_dungeon_item_pool from Fill import FillError, fill_restrictive, fast_fill, get_dungeon_item_pool
from PotShuffle import vanilla_pots from PotShuffle import vanilla_pots
from Items import ItemFactory from Items import ItemFactory
@@ -391,13 +391,13 @@ def generate_itempool(world, player):
set_up_take_anys(world, player) set_up_take_anys(world, player)
if world.dropshuffle[player]: if world.dropshuffle[player]:
world.itempool += [ItemFactory('Small Key (Universal)', player)] * 13 world.itempool += [ItemFactory('Small Key (Universal)', player)] * 13
if world.pottery[player] != 'none': if world.pottery[player] not in ['none', 'cave']:
world.itempool += [ItemFactory('Small Key (Universal)', player)] * 19 world.itempool += [ItemFactory('Small Key (Universal)', player)] * 19
create_dynamic_shop_locations(world, player) create_dynamic_shop_locations(world, player)
if world.pottery[player] == 'lottery': if world.pottery[player] not in ['none', 'keys']:
add_pot_contents(world, player) add_pot_contents(world, player)
@@ -759,6 +759,7 @@ def add_pot_contents(world, player):
for super_tile, pot_list in vanilla_pots.items(): for super_tile, pot_list in vanilla_pots.items():
for pot in pot_list: for pot in pot_list:
if pot.item not in [PotItem.Hole, PotItem.Key, PotItem.Switch]: if pot.item not in [PotItem.Hole, PotItem.Key, PotItem.Switch]:
if valid_pot_location(pot, world, player):
world.itempool.append(ItemFactory(pot_items[pot.item], player)) world.itempool.append(ItemFactory(pot_items[pot.item], player))

View File

@@ -158,7 +158,7 @@ def main(args, seed=None, fish=None):
logger.info(world.fish.translate("cli", "cli", "shuffling.pots")) logger.info(world.fish.translate("cli", "cli", "shuffling.pots"))
for player in range(1, world.players + 1): for player in range(1, world.players + 1):
if world.potshuffle[player]: if world.potshuffle[player]:
if world.pottery[player] != 'lottery': if world.pottery[player] not in ['lottery', 'dungeon']:
shuffle_pots(world, player) shuffle_pots(world, player)
else: else:
shuffle_pot_switches(world, player) shuffle_pot_switches(world, player)

View File

@@ -4,10 +4,12 @@
### Pottery ### Pottery
New pottery option that control which pots are in the locations pool: New pottery option that control which pots (and large blocks) are in the locations pool:
* None: No pots are in the pool, like normal randomizer * None: No pots are in the pool, like normal randomizer
* Key Pots: The pots that have keys are in the pool. This is about half of the old keydropshuffle option * Key Pots: The pots that have keys are in the pool. This is about half of the old keydropshuffle option
* Cave Pots: The pots that are not found in dungeon are in the pool. (Includes the large block in Spike Cave)
* Dungeon Pots: The pots that are in dungeons are in the pool. (Includes serveral large blocks)
* Lottery: All pots and large blocks are in the pool * Lottery: All pots and large blocks are in the pool
By default, switches remain in their vanilla location (unless you turn on the legacy option below) By default, switches remain in their vanilla location (unless you turn on the legacy option below)
@@ -145,8 +147,12 @@ Same as above but both small keys and bigs keys of the dungeon are not allowed o
#### Volatile #### Volatile
* 1.0.1.5 * 1.0.1.5
* A couple new options for lighter pottery modes
* New option for Boss Shuffle: Unique (Prize bosses will be one of each, but GT bosses can be anything)
* Fix for Hera Basement Cage item inheriting last pot checked * Fix for Hera Basement Cage item inheriting last pot checked
* Update indicators on keysanity menu for overworld map option * Update indicators on keysanity menu for overworld map option
* Fix for Standard ER where locations in rain state could be in logic
* Fix for Ice Refill room pots, require being able to hit a switch for bombbag mode
* 1.0.1.4 * 1.0.1.4
* Reverted SRAM change (the underlying refactor isn't done yet) * Reverted SRAM change (the underlying refactor isn't done yet)
* 1.0.1.3 * 1.0.1.3

View File

@@ -1007,7 +1007,7 @@ def adjust_locations(world, player):
loc.address = pot_address(pot_index, datum[1]) loc.address = pot_address(pot_index, datum[1])
loc.pot = pot loc.pot = pot
if (not world.dropshuffle[player] and drop_location)\ if (not world.dropshuffle[player] and drop_location)\
or (not drop_location and world.pottery[player] == 'none'): or (not drop_location and world.pottery[player] in ['none', 'cave']):
loc.skip = True loc.skip = True
else: else:
key_item = loc.item key_item = loc.item
@@ -1030,7 +1030,8 @@ def adjust_locations(world, player):
else: else:
pot = pot_orig.copy() pot = pot_orig.copy()
world.pot_contents[player].room_map[super_tile].append(pot) world.pot_contents[player].room_map[super_tile].append(pot)
if world.pottery[player] == 'lottery':
if valid_pot_location(pot, world, player):
create_pot_location(pot, pot_index, super_tile, world, player) create_pot_location(pot, pot_index, super_tile, world, player)
if world.shopsanity[player]: if world.shopsanity[player]:
index = 0 index = 0
@@ -1053,9 +1054,20 @@ def adjust_locations(world, player):
location.skip = True location.skip = True
def valid_pot_location(pot, world, player):
if world.pottery[player] == 'lottery':
return True
if world.pottery[player] == 'dungeon' and world.get_region(pot.room, player).type == RegionType.Dungeon:
return True
if world.pottery[player] == 'cave' and world.get_region(pot.room, player).type == RegionType.Cave:
return True
return False
def create_pot_location(pot, pot_index, super_tile, world, player): def create_pot_location(pot, pot_index, super_tile, world, player):
if (pot.item not in [PotItem.Key, PotItem.Hole] if (pot.item not in [PotItem.Key, PotItem.Hole]
and (pot.item != PotItem.Switch or world.potshuffle[player])): and (pot.item != PotItem.Switch or (world.potshuffle[player]
and world.pottery[player] in ['lottery', 'dungeon']))):
address = pot_address(pot_index, super_tile) address = pot_address(pot_index, super_tile)
region = pot.room region = pot.room
if world.mode[player] == 'inverted': if world.mode[player] == 'inverted':

9
Rom.py
View File

@@ -746,7 +746,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
valid_loc_by_dungeon = valid_dungeon_locations(valid_locations) valid_loc_by_dungeon = valid_dungeon_locations(valid_locations)
# fix hc big key problems (map and compass too) # fix hc big key problems (map and compass too)
if world.doorShuffle[player] == 'crossed' or world.dropshuffle[player] or world.pottery[player] != 'none': if world.doorShuffle[player] == 'crossed' or world.dropshuffle[player] or world.pottery[player] not in ['none', 'cave']:
rom.write_byte(0x151f1, 2) rom.write_byte(0x151f1, 2)
rom.write_byte(0x15270, 2) rom.write_byte(0x15270, 2)
sanctuary = world.get_region('Sanctuary', player) sanctuary = world.get_region('Sanctuary', player)
@@ -879,10 +879,11 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
multiClientFlags = ((0x1 if world.dropshuffle[player] else 0) multiClientFlags = ((0x1 if world.dropshuffle[player] else 0)
| (0x2 if world.shopsanity[player] else 0) | (0x2 if world.shopsanity[player] else 0)
| (0x4 if world.retro[player] else 0) | (0x4 if world.retro[player] else 0)
| (0x8 if world.pottery[player] in ['keys', 'lottery'] else 0) | (0x8 if world.pottery[player] != 'none' else 0)
| (0x10 if is_mystery else 0)) | (0x10 if is_mystery else 0))
rom.write_byte(0x142A51, multiClientFlags) rom.write_byte(0x142A51, multiClientFlags)
rom.write_byte(0x142A55, ((0x1 if world.pottery[player] != 'none' else 0) # StandingItemCounterMask # StandingItemCounterMask
rom.write_byte(0x142A55, ((0x1 if world.pottery[player] not in ['none', 'cave'] else 0)
| (0x2 if world.dropshuffle[player] else 0))) | (0x2 if world.dropshuffle[player] else 0)))
if world.pottery[player] not in ['none', 'keys']: if world.pottery[player] not in ['none', 'keys']:
# Cuccos should not prevent kill rooms from opening # Cuccos should not prevent kill rooms from opening
@@ -1466,7 +1467,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
elif world.dungeon_counters[player] == 'on': elif world.dungeon_counters[player] == 'on':
compass_mode = 0x02 # always on compass_mode = 0x02 # always on
elif (world.compassshuffle[player] or world.doorShuffle[player] != 'vanilla' or world.dropshuffle[player] elif (world.compassshuffle[player] or world.doorShuffle[player] != 'vanilla' or world.dropshuffle[player]
or world.dungeon_counters[player] == 'pickup' or world.pottery[player] != 'none'): or world.dungeon_counters[player] == 'pickup' or world.pottery[player] not in ['none', 'cave']):
compass_mode = 0x01 # show on pickup compass_mode = 0x01 # show on pickup
if world.shuffle[player] != 'vanilla' and world.overworld_map[player] != 'default': if world.shuffle[player] != 'vanilla' and world.overworld_map[player] != 'default':
compass_mode |= 0x80 # turn on locating dungeons compass_mode |= 0x80 # turn on locating dungeons

View File

@@ -716,7 +716,7 @@ def bomb_rules(world, player):
def pot_rules(world, player): def pot_rules(world, player):
if world.pottery[player] == 'lottery': if world.pottery[player] in ['lottery', 'cave']:
blocks = [l for l in world.get_locations() if l.type == LocationType.Pot and l.pot.flags & PotFlags.Block] blocks = [l for l in world.get_locations() if l.type == LocationType.Pot and l.pot.flags & PotFlags.Block]
for block_pot in blocks: for block_pot in blocks:
add_rule(block_pot, lambda state: state.can_lift_rocks(player)) add_rule(block_pot, lambda state: state.can_lift_rocks(player))
@@ -740,7 +740,7 @@ def pot_rules(world, player):
if l.type == LocationType.Pot: if l.type == LocationType.Pot:
add_rule(l, lambda state: state.world.can_take_damage or state.has('Hookshot', player)) add_rule(l, lambda state: state.world.can_take_damage or state.has('Hookshot', player))
# dungeons if world.pottery[player] in ['lottery', 'dungeon']:
for l in world.get_region('Ice Hammer Block', player).locations: for l in world.get_region('Ice Hammer Block', player).locations:
if l.type == LocationType.Pot: if l.type == LocationType.Pot:
add_rule(l, lambda state: state.has('Hammer', player) and state.can_lift_rocks(player)) add_rule(l, lambda state: state.has('Hammer', player) and state.can_lift_rocks(player))

View File

@@ -76,6 +76,8 @@
"choices" : [ "choices" : [
"none", "none",
"keys", "keys",
"dungeon",
"cave",
"lottery" "lottery"
] ]
}, },

View File

@@ -256,6 +256,8 @@
"pottery": [ "Controls how items under pots are shuffled and if other items can take their place:", "pottery": [ "Controls how items under pots are shuffled and if other items can take their place:",
"None: No pots are changed", "None: No pots are changed",
"Keys: Key pots are included in the location pool and other items can take their place", "Keys: Key pots are included in the location pool and other items can take their place",
"Cave: Only pots in houses and caves are included in the location pool",
"Dungeon: Only pots in dungeons are included in the location pool",
"Lottery: All pots are part of the location pool" "Lottery: All pots are part of the location pool"
], ],
"shufflepots": [ "Pots and switches are shuffled on the supertile (legacy potshuffle) (default: %(default)s)"], "shufflepots": [ "Pots and switches are shuffled on the supertile (legacy potshuffle) (default: %(default)s)"],

View File

@@ -59,6 +59,8 @@
"randomizer.dungeon.pottery": "Pottery", "randomizer.dungeon.pottery": "Pottery",
"randomizer.dungeon.pottery.none": "None", "randomizer.dungeon.pottery.none": "None",
"randomizer.dungeon.pottery.keys": "Key Pots", "randomizer.dungeon.pottery.keys": "Key Pots",
"randomizer.dungeon.pottery.cave": "Cave Pots",
"randomizer.dungeon.pottery.dungeon": "Dungeon Pots",
"randomizer.dungeon.pottery.lottery": "Lottery (All Pots and Large Blocks)", "randomizer.dungeon.pottery.lottery": "Lottery (All Pots and Large Blocks)",
"randomizer.dungeon.dungeondoorshuffle": "Dungeon Door Shuffle", "randomizer.dungeon.dungeondoorshuffle": "Dungeon Door Shuffle",

View File

@@ -29,6 +29,8 @@
"options": [ "options": [
"none", "none",
"keys", "keys",
"cave",
"dungeon",
"lottery" "lottery"
], ],
"config": { "config": {

View File

@@ -73,7 +73,7 @@ def create_item_pool_config(world):
if world.pottery[player] != 'none': if world.pottery[player] != 'none':
for item, locs in potkeys_vanilla_mapping.items(): for item, locs in potkeys_vanilla_mapping.items():
config.static_placement[player][item].extend(locs) config.static_placement[player][item].extend(locs)
if world.pottery[player] == 'lottery': if world.pottery[player] in ['lottery', 'cave', 'dungeon']:
for super_tile, pot_list in vanilla_pots.items(): for super_tile, pot_list in vanilla_pots.items():
for pot_index, pot in enumerate(pot_list): for pot_index, pot in enumerate(pot_list):
if pot.item not in [PotItem.Key, PotItem.Hole, PotItem.Switch]: if pot.item not in [PotItem.Key, PotItem.Hole, PotItem.Switch]:
@@ -96,7 +96,7 @@ def create_item_pool_config(world):
for item, locs in keydrop_vanilla_mapping.items(): for item, locs in keydrop_vanilla_mapping.items():
if 'Small Key' in item: if 'Small Key' in item:
universal_key_locations.extend(locs) universal_key_locations.extend(locs)
if world.pottery[player] != 'none': if world.pottery[player] not in ['none', 'cave']:
for item, locs in potkeys_vanilla_mapping.items(): for item, locs in potkeys_vanilla_mapping.items():
universal_key_locations.extend(locs) universal_key_locations.extend(locs)
if world.shopsanity[player]: if world.shopsanity[player]: