Ocarina of Time 7.0 (#1277)

## What is this fixing or adding?
- Adds the majority of OoTR 7.0 features:
  - Pot shuffle, Freestanding item shuffle, Crate shuffle, Beehive shuffle
  - Key rings mode
  - Dungeon shortcuts to speed up dungeons
  - "Regional" shuffle for dungeon items
  - New options for shop pricing in shopsanity
  - Expanded Ganon's Boss Key shuffle options
  - Pre-planted beans
  - Improved Chest Appearance Matches Contents mode
  - Blue Fire Arrows
  - Bonk self-damage
  - Finer control over MQ dungeons and spawn position randomization
- Several bugfixes as a result of the update:
  - Items recognized by the server and valid starting items are now in a 1-to-1 correspondence. In particular, starting with keys is now supported.
  - Entrance randomization success rate improved. Hopefully it is now at 100%. 

Co-authored-by: Zach Parks <zach@alliware.com>
This commit is contained in:
espeon65536
2022-12-10 21:11:40 -06:00
committed by GitHub
parent 2cdd03f786
commit aee0df5359
110 changed files with 37691 additions and 18648 deletions

View File

@@ -1,7 +1,6 @@
from collections import deque
import logging
from .SaveContext import SaveContext
from .Regions import TimeOfDay
from .Items import oot_is_item_of_type
@@ -21,9 +20,18 @@ class OOTLogic(LogicMixin):
def _oot_has_dungeon_rewards(self, count, player):
return self.has_group("rewards", player, count)
def _oot_has_hearts(self, count, player):
containers = self.count("Heart Container", player)
pieces = self.count("Piece of Heart", player) + self.count("Piece of Heart (Treasure Chest Game)", player)
total_hearts = 3 + containers + int(pieces / 4)
return total_hearts >= count
def _oot_has_bottle(self, player):
return self.has_group("logic_bottles", player)
def _oot_has_beans(self, player):
return self.has("Magic Bean Pack", player) or self.has("Buy Magic Bean", player) or self.has("Magic Bean", player, 10)
# Used for fall damage and other situations where damage is unavoidable
def _oot_can_live_dmg(self, player, hearts):
mult = self.multiworld.worlds[player].damage_multiplier
@@ -32,6 +40,11 @@ class OOTLogic(LogicMixin):
else:
return mult != 'ohko'
# Figure out if the given region's parent dungeon has shortcuts enabled
def _oot_region_has_shortcuts(self, player, regionname):
return self.multiworld.worlds[player].region_has_shortcuts(regionname)
# This function operates by assuming different behavior based on the "level of recursion", handled manually.
# If it's called while self.age[player] is None, then it will set the age variable and then attempt to reach the region.
# If self.age[player] is not None, then it will compare it to the 'age' parameter, and return True iff they are equal.
@@ -125,12 +138,14 @@ def set_rules(ootworld):
# is_child = ootworld.parser.parse_rule('is_child')
guarantee_hint = ootworld.parser.parse_rule('guarantee_hint')
for location in filter(lambda location: location.name in ootworld.shop_prices or 'Deku Scrub' in location.name, ootworld.get_locations()):
for location in filter(lambda location: location.name in ootworld.shop_prices
or location.type in {'Scrub', 'GrottoScrub'}, ootworld.get_locations()):
if location.type == 'Shop':
location.price = ootworld.shop_prices[location.name]
add_rule(location, create_shop_rule(location, ootworld.parser))
if ootworld.dungeon_mq['Forest Temple'] and ootworld.shuffle_bosskeys == 'dungeon' and ootworld.shuffle_smallkeys == 'dungeon' and ootworld.tokensanity == 'off':
if (ootworld.dungeon_mq['Forest Temple'] and ootworld.shuffle_bosskeys == 'dungeon'
and ootworld.shuffle_smallkeys == 'dungeon' and ootworld.tokensanity == 'off'):
# First room chest needs to be a small key. Make sure the boss key isn't placed here.
location = world.get_location('Forest Temple MQ First Room Chest', player)
forbid_item(location, 'Boss Key (Forest Temple)', ootworld.player)
@@ -141,11 +156,6 @@ def set_rules(ootworld):
location = world.get_location('Sheik in Ice Cavern', player)
add_item_rule(location, lambda item: item.player == player and oot_is_item_of_type(item, 'Song'))
if ootworld.skip_child_zelda:
# If skip child zelda is on, the item at Song from Impa must be giveable by the save context.
location = world.get_location('Song from Impa', player)
add_item_rule(location, lambda item: item.name in SaveContext.giveable_items)
for name in ootworld.always_hints:
add_rule(world.get_location(name, player), guarantee_hint)