Reimplement random weapon standard start, the previous one did not make sense in a multiworld context and rework castle chests logic, bombs start is now possible

This commit is contained in:
Bonta-kun 2019-12-11 11:41:05 +01:00
parent 6d50e905e1
commit 4ca063be54
3 changed files with 37 additions and 31 deletions

View File

@ -35,7 +35,7 @@ Difficulty = namedtuple('Difficulty',
'progressivesword', 'basicsword', 'basicbow', 'timedohko', 'timedother',
'triforcehunt', 'triforce_pieces_required', 'retro',
'extras', 'progressive_sword_limit', 'progressive_shield_limit',
'progressive_armor_limit', 'progressive_bottle_limit',
'progressive_armor_limit', 'progressive_bottle_limit',
'progressive_bow_limit', 'heart_piece_limit', 'boss_heart_container_limit'])
total_items_to_place = 153
@ -136,7 +136,7 @@ def generate_itempool(world, player):
world.push_item(world.get_location('Ganon', player), ItemFactory('Nothing', player), False)
else:
world.push_item(world.get_location('Ganon', player), ItemFactory('Triforce', player), False)
if world.goal in ['triforcehunt']:
if world.mode == 'inverted':
region = world.get_region('Light World',player)
@ -153,7 +153,7 @@ def generate_itempool(world, player):
world.push_item(loc, ItemFactory('Triforce', player), False)
loc.event = True
loc.locked = True
world.get_location('Ganon', player).event = True
world.get_location('Ganon', player).locked = True
world.push_item(world.get_location('Agahnim 1', player), ItemFactory('Beat Agahnim 1', player), False)
@ -181,16 +181,41 @@ def generate_itempool(world, player):
world.rupoor_cost = min(world.customitemarray[69], 9999)
else:
(pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle, world.difficulty, world.timer, world.goal, world.mode, world.swords, world.retro)
world.itempool += ItemFactory(pool, player)
for item in precollected_items:
world.push_precollected(ItemFactory(item, player))
if world.mode == 'standard' and not world.state.has_blunt_weapon(player) and "Link's Uncle" not in placed_items:
found_sword = False
found_bow = False
possible_weapons = []
for item in pool:
if item in ['Progressive Sword', 'Fighter Sword', 'Master Sword', 'Tempered Sword', 'Golden Sword']:
if not found_sword and world.swords != 'swordless':
found_sword = True
possible_weapons.append(item)
if item in ['Progressive Bow', 'Bow'] and not found_bow:
found_bow = True
possible_weapons.append(item)
if item in ['Hammer', 'Bombs (10)', 'Fire Rod', 'Cane of Somaria', 'Cane of Byrna']:
if item not in possible_weapons:
possible_weapons.append(item)
starting_weapon = random.choice(possible_weapons)
placed_items["Link's Uncle"] = starting_weapon
pool.remove(starting_weapon)
for (location, item) in placed_items.items():
world.push_item(world.get_location(location, player), ItemFactory(item, player), False)
world.get_location(location, player).event = True
world.get_location(location, player).locked = True
world.itempool += ItemFactory(pool, player)
world.lamps_needed_for_dark_rooms = lamps_needed_for_dark_rooms
if clock_mode is not None:
world.clock_mode = clock_mode
if treasure_hunt_count is not None:
world.treasure_hunt_count = treasure_hunt_count
if treasure_hunt_icon is not None:
@ -235,7 +260,7 @@ take_any_locations = [
def set_up_take_anys(world, player):
if world.mode == 'inverted' and 'Dark Sanctuary Hint' in take_any_locations:
take_any_locations.remove('Dark Sanctuary Hint')
regions = random.sample(take_any_locations, 5)
old_man_take_any = Region("Old Man Sword Cave", RegionType.Cave, 'the sword cave', player)

5
Rom.py
View File

@ -998,6 +998,11 @@ def patch_rom(world, player, rom):
rom.write_bytes(0x180185, [0,0,70]) # Uncle respawn refills (magic, bombs, arrows)
rom.write_bytes(0x180188, [0,0,10]) # Zelda respawn refills (magic, bombs, arrows)
rom.write_bytes(0x18018B, [0,0,10]) # Mantle respawn refills (magic, bombs, arrows)
elif uncle_location.item is not None and uncle_location.item.name in ['Bombs (10)']:
rom.write_byte(0x18004E, 2) # Escape Fill (bombs)
rom.write_bytes(0x180185, [0,50,0]) # Uncle respawn refills (magic, bombs, arrows)
rom.write_bytes(0x180188, [0,3,0]) # Zelda respawn refills (magic, bombs, arrows)
rom.write_bytes(0x18018B, [0,3,0]) # Mantle respawn refills (magic, bombs, arrows)
elif uncle_location.item is not None and uncle_location.item.name in ['Cane of Somaria', 'Cane of Byrna', 'Fire Rod']:
rom.write_byte(0x18004E, 4) # Escape Fill (magic)
rom.write_bytes(0x180185, [0x80,0,0]) # Uncle respawn refills (magic, bombs, arrows)

View File

@ -696,9 +696,6 @@ def no_glitches_rules(world, player):
def open_rules(world, player):
# softlock protection as you can reach the sewers small key door with a guard drop key
forbid_item(world.get_location('Hyrule Castle - Boomerang Chest', player), 'Small Key (Escape)', player)
forbid_item(world.get_location('Hyrule Castle - Zelda\'s Chest', player), 'Small Key (Escape)', player)
set_rule(world.get_location('Hyrule Castle - Boomerang Chest', player), lambda state: state.has_key('Small Key (Escape)', player))
set_rule(world.get_location('Hyrule Castle - Zelda\'s Chest', player), lambda state: state.has_key('Small Key (Escape)', player))
@ -723,32 +720,11 @@ def swordless_rules(world, player):
set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has_misery_mire_medallion(player)) # sword not required to use medallion for opening in swordless (!)
set_rule(world.get_location('Bombos Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has('Hammer', player))
def standard_rules(world, player):
add_rule(world.get_entrance('Sewers Door', player), lambda state: state.can_kill_most_things(player))
def standard_rules(world, player):
set_rule(world.get_entrance('Hyrule Castle Exit (East)', player), lambda state: state.can_reach('Sanctuary', 'Region', player))
set_rule(world.get_entrance('Hyrule Castle Exit (West)', player), lambda state: state.can_reach('Sanctuary', 'Region', player))
# ensures the required weapon for escape lands on uncle (unless player has it pre-equipped)
add_rule(world.get_location('Secret Passage', player), lambda state: state.can_kill_most_things(player))
add_rule(world.get_location('Hyrule Castle - Map Chest', player), lambda state: state.can_kill_most_things(player))
def uncle_item_rule(item):
copy_state = CollectionState(world)
copy_state.collect(item)
copy_state.sweep_for_events()
return copy_state.can_reach('Sanctuary', 'Region', player)
add_item_rule(world.get_location('Link\'s Uncle', player), uncle_item_rule)
# easiest way to enforce key placement not relevant for open
set_rule(world.get_location('Sewers - Dark Cross', player), lambda state: state.can_kill_most_things(player))
set_rule(world.get_location('Hyrule Castle - Boomerang Chest', player), lambda state: state.can_kill_most_things(player))
set_rule(world.get_location('Hyrule Castle - Zelda\'s Chest', player), lambda state: state.can_kill_most_things(player))
def set_trock_key_rules(world, player):
@ -1191,7 +1167,7 @@ def set_inverted_big_bomb_rules(world, player):
'Dark Desert Hint',
'Dark Desert Fairy',
'Misery Mire']
LW_bush_entrances = ['Bush Covered House',
LW_bush_entrances = ['Bush Covered House',
'Light World Bomb Hut',
'Graveyard Cave']