Revert "Merge branch 'pr/151'"
This reverts commit ffdaed9ea97bdc49d7d81f74f0c2e6462c6a9bdf, reversing changes made to 1ea9197976b6f2ad2626fb453dc52acc787f9ddc.
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -30,5 +30,3 @@ weights/
|
||||
_persistent_storage.yaml
|
||||
mystery_result_*.yaml
|
||||
/db.db3
|
||||
*-errors.txt
|
||||
success.txt
|
||||
|
||||
@@ -6,7 +6,7 @@ import textwrap
|
||||
import sys
|
||||
|
||||
from AdjusterMain import adjust
|
||||
from Rom import Sprite
|
||||
from Rom import get_sprite_from_name
|
||||
|
||||
class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter):
|
||||
|
||||
@@ -55,7 +55,7 @@ def main():
|
||||
input(
|
||||
'Could not find valid rom for patching at expected path %s. Please run with -h to see help for further information. \nPress Enter to exit.' % args.rom)
|
||||
sys.exit(1)
|
||||
if args.sprite is not None and not os.path.isfile(args.sprite) and not Sprite.get_sprite_from_name(args.sprite):
|
||||
if args.sprite is not None and not os.path.isfile(args.sprite) and not get_sprite_from_name(args.sprite):
|
||||
input('Could not find link sprite sheet at given location. \nPress Enter to exit.')
|
||||
sys.exit(1)
|
||||
|
||||
@@ -65,10 +65,7 @@ def main():
|
||||
logging.basicConfig(format='%(message)s', level=loglevel)
|
||||
args, path = adjust(args=args)
|
||||
from Utils import persistent_store
|
||||
from Rom import Sprite
|
||||
if isinstance(args.sprite, Sprite):
|
||||
args.sprite = args.sprite.name
|
||||
persistent_store("adjuster", "last_settings_3", args)
|
||||
persistent_store("adjuster", "last_settings", args)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -27,7 +27,7 @@ def adjust(args):
|
||||
palettes_options['hud']=args.hud_palettes
|
||||
palettes_options['sword']=args.sword_palettes
|
||||
palettes_options['shield']=args.shield_palettes
|
||||
# palettes_options['link']=args.link_palettesvera
|
||||
palettes_options['link']=args.link_palettes
|
||||
|
||||
apply_rom_settings(rom, args.heartbeep, args.heartcolor, args.quickswap, args.fastmenu, args.disablemusic,
|
||||
args.sprite, palettes_options)
|
||||
|
||||
@@ -119,19 +119,13 @@ class World(object):
|
||||
set_player_attr('treasure_hunt_icon', 'Triforce Piece')
|
||||
set_player_attr('treasure_hunt_count', 0)
|
||||
set_player_attr('clock_mode', False)
|
||||
set_player_attr('countdown_start_time', 10)
|
||||
set_player_attr('red_clock_time', -2)
|
||||
set_player_attr('blue_clock_time', 2)
|
||||
set_player_attr('green_clock_time', 4)
|
||||
set_player_attr('can_take_damage', True)
|
||||
set_player_attr('glitch_boots', True)
|
||||
set_player_attr('progression_balancing', True)
|
||||
set_player_attr('local_items', set())
|
||||
set_player_attr('non_local_items', set())
|
||||
set_player_attr('triforce_pieces_available', 30)
|
||||
set_player_attr('triforce_pieces_required', 20)
|
||||
set_player_attr('shop_shuffle', 'off')
|
||||
set_player_attr('shop_shuffle_slots', 0)
|
||||
set_player_attr('shuffle_prizes', "g")
|
||||
set_player_attr('sprite_pool', [])
|
||||
set_player_attr('dark_room_logic', "lamp")
|
||||
@@ -341,27 +335,6 @@ class World(object):
|
||||
if collect:
|
||||
self.state.collect(item, location.event, location)
|
||||
|
||||
# TODO: Prevents fast_filling certain items. Move this to a proper filter.
|
||||
if location.parent_region.shop is not None and location.name != 'Potion Shop': # includes potion shop slots but not potion shop powder
|
||||
slot_num = int(location.name[-1]) - 1
|
||||
my_item = location.parent_region.shop.inventory[slot_num]
|
||||
if (my_item is not None and my_item['item'] == item.name) or 'Rupee' in item.name or ('Bee' in item.name and 'Trap' not in item.name):
|
||||
# this will filter items that match the item in the shop or Rupees, or single bees
|
||||
# really not a way for the player to know a renewable item from a player pool item
|
||||
# bombs can be sitting on top of arrows or a potion refill, but dunno if that's a big deal
|
||||
logging.debug('skipping item shop {}'.format(item.name))
|
||||
else:
|
||||
if my_item is None:
|
||||
location.parent_region.shop.add_inventory(slot_num, 'None', 0)
|
||||
my_item = location.parent_region.shop.inventory[slot_num]
|
||||
else:
|
||||
my_item['replacement'] = my_item['item']
|
||||
my_item['replacement_price'] = my_item['price']
|
||||
my_item['item'] = item.name
|
||||
my_item['price'] = self.random.randrange(1, 61) * 5 # can probably replace this with a price chart
|
||||
my_item['max'] = 1
|
||||
my_item['player'] = item.player if item.player != location.player else 0
|
||||
|
||||
logging.debug('Placed %s at %s', item, location)
|
||||
else:
|
||||
raise RuntimeError('Cannot assign item %s to location %s.' % (item, location))
|
||||
@@ -1162,8 +1135,7 @@ class Shop():
|
||||
'max': max,
|
||||
'replacement': replacement,
|
||||
'replacement_price': replacement_price,
|
||||
'create_location': create_location,
|
||||
'player': 0
|
||||
'create_location': create_location
|
||||
}
|
||||
|
||||
def push_inventory(self, slot: int, item: str, price: int, max: int = 1):
|
||||
@@ -1176,8 +1148,7 @@ class Shop():
|
||||
'max': max,
|
||||
'replacement': self.inventory[slot]["item"],
|
||||
'replacement_price': self.inventory[slot]["price"],
|
||||
'create_location': self.inventory[slot]["create_location"],
|
||||
'player': self.inventory[slot]["player"]
|
||||
'create_location': self.inventory[slot]["create_location"]
|
||||
}
|
||||
|
||||
|
||||
@@ -1263,10 +1234,6 @@ class Spoiler(object):
|
||||
if item is None:
|
||||
continue
|
||||
shopdata['item_{}'.format(index)] = "{} — {}".format(item['item'], item['price']) if item['price'] else item['item']
|
||||
|
||||
if item['player'] > 0:
|
||||
shopdata['item_{}'.format(index)] = shopdata['item_{}'.format(index)].replace('—', '(Player {}) — '.format(item['player']))
|
||||
|
||||
if item['max'] == 0:
|
||||
continue
|
||||
shopdata['item_{}'.format(index)] += " x {}".format(item['max'])
|
||||
@@ -1340,7 +1307,6 @@ class Spoiler(object):
|
||||
'triforce_pieces_available': self.world.triforce_pieces_available,
|
||||
'triforce_pieces_required': self.world.triforce_pieces_required,
|
||||
'shop_shuffle': self.world.shop_shuffle,
|
||||
'shop_shuffle_slots': self.world.shop_shuffle_slots,
|
||||
'shuffle_prizes': self.world.shuffle_prizes,
|
||||
'sprite_pool': self.world.sprite_pool,
|
||||
'restrict_dungeon_item_on_boss': self.world.restrict_dungeon_item_on_boss
|
||||
|
||||
@@ -8,7 +8,7 @@ import shlex
|
||||
import sys
|
||||
|
||||
from Main import main, get_seed
|
||||
from Rom import Sprite
|
||||
from Rom import get_sprite_from_name
|
||||
from Utils import is_bundled, close_console
|
||||
|
||||
|
||||
@@ -129,14 +129,6 @@ def parse_arguments(argv, no_defaults=False):
|
||||
Timed mode. If time runs out, you lose (but can
|
||||
still keep playing).
|
||||
''')
|
||||
parser.add_argument('--countdown_start_time', default=defval(10), type=int,
|
||||
help='''Set amount of time, in minutes, to start with in Timed Countdown and Timed OHKO modes''')
|
||||
parser.add_argument('--red_clock_time', default=defval(-2), type=int,
|
||||
help='''Set amount of time, in minutes, to add from picking up red clocks; negative removes time instead''')
|
||||
parser.add_argument('--blue_clock_time', default=defval(2), type=int,
|
||||
help='''Set amount of time, in minutes, to add from picking up blue clocks; negative removes time instead''')
|
||||
parser.add_argument('--green_clock_time', default=defval(4), type=int,
|
||||
help='''Set amount of time, in minutes, to add from picking up green clocks; negative removes time instead''')
|
||||
parser.add_argument('--dungeon_counters', default=defval('default'), const='default', nargs='?', choices=['default', 'on', 'pickup', 'off'],
|
||||
help='''\
|
||||
Select dungeon counter display settings. (default: %(default)s)
|
||||
@@ -181,7 +173,7 @@ def parse_arguments(argv, no_defaults=False):
|
||||
slightly biased to placing progression items with
|
||||
less restrictions.
|
||||
''')
|
||||
parser.add_argument('--shuffle', default=defval('vanilla'), const='vanilla', nargs='?', choices=['vanilla', 'simple', 'restricted', 'full', 'crossed', 'insanity', 'restricted_legacy', 'full_legacy', 'madness_legacy', 'insanity_legacy', 'dungeonsfull', 'dungeonssimple'],
|
||||
parser.add_argument('--shuffle', default=defval('full'), const='full', nargs='?', choices=['vanilla', 'simple', 'restricted', 'full', 'crossed', 'insanity', 'restricted_legacy', 'full_legacy', 'madness_legacy', 'insanity_legacy', 'dungeonsfull', 'dungeonssimple'],
|
||||
help='''\
|
||||
Select Entrance Shuffling Algorithm. (default: %(default)s)
|
||||
Full: Mix cave and dungeon entrances freely while limiting
|
||||
@@ -266,8 +258,6 @@ def parse_arguments(argv, no_defaults=False):
|
||||
help='Specifies a list of items that will be in your starting inventory (separated by commas)')
|
||||
parser.add_argument('--local_items', default=defval(''),
|
||||
help='Specifies a list of items that will not spread across the multiworld (separated by commas)')
|
||||
parser.add_argument('--non_local_items', default=defval(''),
|
||||
help='Specifies a list of items that will spread across the multiworld (separated by commas)')
|
||||
parser.add_argument('--custom', default=defval(False), help='Not supported.')
|
||||
parser.add_argument('--customitemarray', default=defval(False), help='Not supported.')
|
||||
parser.add_argument('--accessibility', default=defval('items'), const='items', nargs='?', choices=['items', 'locations', 'none'], help='''\
|
||||
@@ -330,11 +320,6 @@ def parse_arguments(argv, no_defaults=False):
|
||||
p: randomize the prices of the items in shop inventories
|
||||
u: shuffle capacity upgrades into the item pool
|
||||
''')
|
||||
parser.add_argument('--shop_shuffle_slots', default=defval(0),
|
||||
type=lambda value: min(max(int(value), 1), 96),
|
||||
help='''
|
||||
Maximum amount of shop slots able to be filled by items from the item pool.
|
||||
''')
|
||||
parser.add_argument('--shuffle_prizes', default=defval('g'), choices=['', 'g', 'b', 'gb'])
|
||||
parser.add_argument('--sprite_pool', help='''\
|
||||
Specifies a colon separated list of sprites used for random/randomonevent. If not specified, the full sprite pool is used.''')
|
||||
@@ -381,16 +366,14 @@ def parse_arguments(argv, no_defaults=False):
|
||||
|
||||
for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality',
|
||||
'shuffle', 'crystals_ganon', 'crystals_gt', 'open_pyramid', 'timer',
|
||||
'countdown_start_time', 'red_clock_time', 'blue_clock_time', 'green_clock_time',
|
||||
'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory',
|
||||
'local_items', 'non_local_items', 'retro', 'accessibility', 'hints', 'beemizer',
|
||||
'local_items', 'retro', 'accessibility', 'hints', 'beemizer',
|
||||
'shufflebosses', 'enemy_shuffle', 'enemy_health', 'enemy_damage', 'shufflepots',
|
||||
'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor',
|
||||
'heartbeep', "skip_progression_balancing", "triforce_pieces_available",
|
||||
"triforce_pieces_required", "shop_shuffle", "shop_shuffle_slots",
|
||||
"triforce_pieces_required", "shop_shuffle",
|
||||
'remote_items', 'progressive', 'dungeon_counters', 'glitch_boots', 'killable_thieves',
|
||||
'tile_shuffle', 'bush_shuffle', 'shuffle_prizes', 'sprite_pool', 'dark_room_logic', 'restrict_dungeon_item_on_boss',
|
||||
'hud_palettes', 'sword_palettes', 'shield_palettes', 'link_palettes']:
|
||||
'tile_shuffle', 'bush_shuffle', 'shuffle_prizes', 'sprite_pool', 'dark_room_logic', 'restrict_dungeon_item_on_boss']:
|
||||
value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name)
|
||||
if player == 1:
|
||||
setattr(ret, name, {1: value})
|
||||
@@ -417,7 +400,7 @@ def start():
|
||||
input(
|
||||
'Could not find valid base rom for patching at expected path %s. Please run with -h to see help for further information. \nPress Enter to exit.' % args.rom)
|
||||
sys.exit(1)
|
||||
if any([sprite is not None and not os.path.isfile(sprite) and not Sprite.get_sprite_from_name(sprite) for sprite in
|
||||
if any([sprite is not None and not os.path.isfile(sprite) and not get_sprite_from_name(sprite) for sprite in
|
||||
args.sprite.values()]):
|
||||
input('Could not find link sprite sheet at given location. \nPress Enter to exit.')
|
||||
sys.exit(1)
|
||||
|
||||
3
Fill.py
3
Fill.py
@@ -54,9 +54,8 @@ def fill_restrictive(world, base_state: CollectionState, locations, itempool, si
|
||||
for location in region.locations:
|
||||
if location.item and not location.event:
|
||||
placements.append(location)
|
||||
|
||||
raise FillError(f'No more spots to place {item_to_place}, locations {locations} are invalid. '
|
||||
f'Already placed {len(placements)}: {", ".join(str(place) for place in placements)}')
|
||||
f'Already placed {len(placements)}: {", ".join(placements)}')
|
||||
|
||||
world.push_item(spot_to_fill, item_to_place, False)
|
||||
locations.remove(spot_to_fill)
|
||||
|
||||
@@ -14,12 +14,12 @@ def set_icon(window):
|
||||
# some which may be platform specific, or depend on if the TCL library was compiled without
|
||||
# multithreading support. Therefore I will assume it is not thread safe to avoid any possible problems
|
||||
class BackgroundTask(object):
|
||||
def __init__(self, window, code_to_run, *args):
|
||||
def __init__(self, window, code_to_run):
|
||||
self.window = window
|
||||
self.queue = queue.Queue()
|
||||
self.running = True
|
||||
self.process_queue()
|
||||
self.task = threading.Thread(target=code_to_run, args=(self, *args))
|
||||
self.task = threading.Thread(target=code_to_run, args=(self,))
|
||||
self.task.start()
|
||||
|
||||
def stop(self):
|
||||
@@ -45,7 +45,7 @@ class BackgroundTask(object):
|
||||
self.window.after(100, self.process_queue)
|
||||
|
||||
class BackgroundTaskProgress(BackgroundTask):
|
||||
def __init__(self, parent, code_to_run, title, *args):
|
||||
def __init__(self, parent, code_to_run, title):
|
||||
self.parent = parent
|
||||
self.window = tk.Toplevel(parent)
|
||||
self.window['padx'] = 5
|
||||
@@ -65,7 +65,7 @@ class BackgroundTaskProgress(BackgroundTask):
|
||||
|
||||
set_icon(self.window)
|
||||
self.window.focus()
|
||||
super().__init__(self.window, code_to_run, *args)
|
||||
super().__init__(self.window, code_to_run)
|
||||
|
||||
#safe to call from worker thread
|
||||
def update_status(self, text):
|
||||
|
||||
40
Main.py
40
Main.py
@@ -10,7 +10,7 @@ import zlib
|
||||
import concurrent.futures
|
||||
|
||||
from BaseClasses import World, CollectionState, Item, Region, Location, Shop
|
||||
from Items import ItemFactory, item_table
|
||||
from Items import ItemFactory
|
||||
from Regions import create_regions, create_shops, mark_light_world_regions, lookup_vanilla_location_to_entrance
|
||||
from InvertedRegions import create_inverted_regions, mark_dark_world_regions
|
||||
from EntranceShuffle import link_entrances, link_inverted_entrances
|
||||
@@ -72,10 +72,6 @@ def main(args, seed=None):
|
||||
world.tile_shuffle = args.tile_shuffle.copy()
|
||||
world.beemizer = args.beemizer.copy()
|
||||
world.timer = args.timer.copy()
|
||||
world.countdown_start_time = args.countdown_start_time.copy()
|
||||
world.red_clock_time = args.red_clock_time.copy()
|
||||
world.blue_clock_time = args.blue_clock_time.copy()
|
||||
world.green_clock_time = args.green_clock_time.copy()
|
||||
world.shufflepots = args.shufflepots.copy()
|
||||
world.progressive = args.progressive.copy()
|
||||
world.dungeon_counters = args.dungeon_counters.copy()
|
||||
@@ -83,7 +79,6 @@ def main(args, seed=None):
|
||||
world.triforce_pieces_available = args.triforce_pieces_available.copy()
|
||||
world.triforce_pieces_required = args.triforce_pieces_required.copy()
|
||||
world.shop_shuffle = args.shop_shuffle.copy()
|
||||
world.shop_shuffle_slots = args.shop_shuffle_slots.copy()
|
||||
world.progression_balancing = {player: not balance for player, balance in args.skip_progression_balancing.items()}
|
||||
world.shuffle_prizes = args.shuffle_prizes.copy()
|
||||
world.sprite_pool = args.sprite_pool.copy()
|
||||
@@ -111,13 +106,7 @@ def main(args, seed=None):
|
||||
item = ItemFactory(tok.strip(), player)
|
||||
if item:
|
||||
world.push_precollected(item)
|
||||
# item in item_table gets checked in mystery, but not CLI - so we double-check here
|
||||
world.local_items[player] = {item.strip() for item in args.local_items[player].split(',') if
|
||||
item.strip() in item_table}
|
||||
world.non_local_items[player] = {item.strip() for item in args.non_local_items[player].split(',') if
|
||||
item.strip() in item_table}
|
||||
# items can't be both local and non-local, prefer local
|
||||
world.non_local_items[player] -= world.local_items[player]
|
||||
world.local_items[player] = {item.strip() for item in args.local_items[player].split(',')}
|
||||
|
||||
world.triforce_pieces_available[player] = max(world.triforce_pieces_available[player], world.triforce_pieces_required[player])
|
||||
|
||||
@@ -308,30 +297,6 @@ def main(args, seed=None):
|
||||
if lookup_vanilla_location_to_entrance[location.address] != main_entrance.name:
|
||||
er_hint_data[region.player][location.address] = main_entrance.name
|
||||
|
||||
ordered_areas = ('Light World', 'Dark World', 'Hyrule Castle', 'Agahnims Tower', 'Eastern Palace', 'Desert Palace',
|
||||
'Tower of Hera', 'Palace of Darkness', 'Swamp Palace', 'Skull Woods', 'Thieves Town', 'Ice Palace',
|
||||
'Misery Mire', 'Turtle Rock', 'Ganons Tower', "Total")
|
||||
|
||||
checks_in_area = {player: {area: list() for area in ordered_areas}
|
||||
for player in range(1, world.players + 1)}
|
||||
|
||||
for player in range(1, world.players + 1):
|
||||
checks_in_area[player]["Total"] = 0
|
||||
|
||||
for location in [loc for loc in world.get_filled_locations() if type(loc.address) is int]:
|
||||
main_entrance = get_entrance_to_region(location.parent_region)
|
||||
if location.parent_region.dungeon:
|
||||
dungeonname = {'Inverted Agahnims Tower': 'Agahnims Tower',
|
||||
'Inverted Ganons Tower': 'Ganons Tower'}\
|
||||
.get(location.parent_region.dungeon.name, location.parent_region.dungeon.name)
|
||||
checks_in_area[location.player][dungeonname].append(location.address)
|
||||
elif main_entrance.parent_region.type == RegionType.LightWorld:
|
||||
checks_in_area[location.player]["Light World"].append(location.address)
|
||||
elif main_entrance.parent_region.type == RegionType.DarkWorld:
|
||||
checks_in_area[location.player]["Dark World"].append(location.address)
|
||||
checks_in_area[location.player]["Total"] += 1
|
||||
|
||||
|
||||
precollected_items = [[] for player in range(world.players)]
|
||||
for item in world.precollected_items:
|
||||
precollected_items[item.player - 1].append(item.code)
|
||||
@@ -358,7 +323,6 @@ def main(args, seed=None):
|
||||
(location.item.code, location.item.player))
|
||||
for location in world.get_filled_locations() if
|
||||
type(location.address) is int],
|
||||
"checks_in_area": checks_in_area,
|
||||
"server_options": get_options()["server_options"],
|
||||
"er_hint_data": er_hint_data,
|
||||
"precollected_items": precollected_items,
|
||||
|
||||
24
Mystery.py
24
Mystery.py
@@ -11,7 +11,7 @@ import ModuleUpdate
|
||||
ModuleUpdate.update()
|
||||
|
||||
from Utils import parse_yaml
|
||||
from Rom import Sprite
|
||||
from Rom import get_sprite_from_name
|
||||
from EntranceRandomizer import parse_arguments
|
||||
from Main import main as ERmain
|
||||
from Main import get_seed, seeddigits
|
||||
@@ -167,7 +167,7 @@ def main(args=None, callback=ERmain):
|
||||
if path:
|
||||
try:
|
||||
settings = settings_cache[path] if settings_cache[path] else roll_settings(weights_cache[path])
|
||||
if settings.sprite and not os.path.isfile(settings.sprite) and not Sprite.get_sprite_from_name(
|
||||
if settings.sprite and not os.path.isfile(settings.sprite) and not get_sprite_from_name(
|
||||
settings.sprite):
|
||||
logging.warning(
|
||||
f"Warning: The chosen sprite, \"{settings.sprite}\", for yaml \"{path}\", does not exist.")
|
||||
@@ -238,8 +238,6 @@ def convert_to_on_off(value):
|
||||
def get_choice(option, root, value=None) -> typing.Any:
|
||||
if option not in root:
|
||||
return value
|
||||
if type(root[option]) is list:
|
||||
return interpret_on_off(random.choices(root[option])[0])
|
||||
if type(root[option]) is not dict:
|
||||
return interpret_on_off(root[option])
|
||||
if not root[option]:
|
||||
@@ -362,8 +360,6 @@ def roll_settings(weights):
|
||||
# change minimum to required pieces to avoid problems
|
||||
ret.triforce_pieces_available = min(max(ret.triforce_pieces_required, int(ret.triforce_pieces_available)), 90)
|
||||
|
||||
ret.shop_shuffle_slots = int(get_choice('shop_shuffle_slots', weights, '0'))
|
||||
|
||||
ret.shop_shuffle = get_choice('shop_shuffle', weights, '')
|
||||
if not ret.shop_shuffle:
|
||||
ret.shop_shuffle = ''
|
||||
@@ -452,11 +448,6 @@ def roll_settings(weights):
|
||||
'timed_countdown': 'timed-countdown',
|
||||
'display': 'display'}[get_choice('timer', weights, False)]
|
||||
|
||||
ret.countdown_start_time = int(get_choice('countdown_start_time', weights, 10))
|
||||
ret.red_clock_time = int(get_choice('red_clock_time', weights, -2))
|
||||
ret.blue_clock_time = int(get_choice('blue_clock_time', weights, 2))
|
||||
ret.green_clock_time = int(get_choice('green_clock_time', weights, 4))
|
||||
|
||||
ret.dungeon_counters = get_choice('dungeon_counters', weights, 'default')
|
||||
|
||||
ret.progressive = convert_to_on_off(get_choice('progressive', weights, 'on'))
|
||||
@@ -496,17 +487,6 @@ def roll_settings(weights):
|
||||
|
||||
ret.local_items = ",".join(ret.local_items)
|
||||
|
||||
ret.non_local_items = set()
|
||||
for item_name in weights.get('non_local_items', []):
|
||||
items = item_name_groups.get(item_name, {item_name})
|
||||
for item in items:
|
||||
if item in item_table:
|
||||
ret.non_local_items.add(item)
|
||||
else:
|
||||
raise Exception(f"Could not force item {item} to be world-non-local, as it was not recognized.")
|
||||
|
||||
ret.non_local_items = ",".join(ret.non_local_items)
|
||||
|
||||
if 'rom' in weights:
|
||||
romweights = weights['rom']
|
||||
|
||||
|
||||
107
Regions.py
107
Regions.py
@@ -368,17 +368,7 @@ def create_shops(world, player: int):
|
||||
cls_mapping = {ShopType.UpgradeShop: UpgradeShop,
|
||||
ShopType.Shop: Shop,
|
||||
ShopType.TakeAny: TakeAny}
|
||||
option = world.shop_shuffle[player]
|
||||
my_shop_table = dict(shop_table)
|
||||
|
||||
num_slots = int(world.shop_shuffle_slots[player])
|
||||
|
||||
my_shop_slots = ([True] * num_slots + [False] * (len(shop_table) * 3))[:len(shop_table)*3 - 2]
|
||||
|
||||
world.random.shuffle(my_shop_slots)
|
||||
|
||||
from Items import ItemFactory
|
||||
for region_name, (room_id, type, shopkeeper, custom, locked, inventory) in my_shop_table.items():
|
||||
for region_name, (room_id, type, shopkeeper, custom, locked, inventory) in shop_table.items():
|
||||
if world.mode[player] == 'inverted' and region_name == 'Dark Lake Hylia Shop':
|
||||
locked = True
|
||||
inventory = [('Blue Potion', 160), ('Blue Shield', 50), ('Bombs (10)', 50)]
|
||||
@@ -388,19 +378,6 @@ def create_shops(world, player: int):
|
||||
world.shops.append(shop)
|
||||
for index, item in enumerate(inventory):
|
||||
shop.add_inventory(index, *item)
|
||||
if region_name == 'Potion Shop':
|
||||
pass
|
||||
elif region_name == 'Capacity Upgrade':
|
||||
pass
|
||||
else:
|
||||
if my_shop_slots.pop():
|
||||
additional_item = world.random.choice(['Rupees (20)', 'Rupees (50)', 'Rupees (100)'])
|
||||
world.itempool.append(ItemFactory(additional_item, player))
|
||||
loc = Location(player, "{} Slot Item {}".format(shop.region.name, index+1), parent=shop.region)
|
||||
shop.region.locations.append(loc)
|
||||
world.dynamic_locations.append(loc)
|
||||
|
||||
world.clear_location_cache()
|
||||
|
||||
# (type, room_id, shopkeeper, custom, locked, [items])
|
||||
# item = (item, price, max=0, replacement=None, replacement_price=0)
|
||||
@@ -416,63 +393,10 @@ shop_table = {
|
||||
'Light World Death Mountain Shop': (0x00FF, ShopType.Shop, 0xA0, True, False, _basic_shop_defaults),
|
||||
'Kakariko Shop': (0x011F, ShopType.Shop, 0xA0, True, False, _basic_shop_defaults),
|
||||
'Cave Shop (Lake Hylia)': (0x0112, ShopType.Shop, 0xA0, True, False, _basic_shop_defaults),
|
||||
'Potion Shop': (0x0109, ShopType.Shop, 0xA0, True, False, [('Red Potion', 120), ('Green Potion', 60), ('Blue Potion', 160)]),
|
||||
'Potion Shop': (0x0109, ShopType.Shop, 0xFF, False, True, [('Red Potion', 120), ('Green Potion', 60), ('Blue Potion', 160)]),
|
||||
'Capacity Upgrade': (0x0115, ShopType.UpgradeShop, 0x04, True, True, [('Bomb Upgrade (+5)', 100, 7), ('Arrow Upgrade (+5)', 100, 7)])
|
||||
}
|
||||
|
||||
old_location_address_to_new_location_address = {
|
||||
0x2eb18: 0x18001b, # Bottle Merchant
|
||||
0x33d68: 0x18001a, # Purple Chest
|
||||
0x2df45: 0x18001d, # Link's Uncle
|
||||
0x2f1fc: 0x180008, # Sahasrahla
|
||||
0x18002a: 0x18001c, # Black Smith
|
||||
0x339cf: 0x180009, # Sick Kid
|
||||
0x33e7d: 0x180019, # Hobo
|
||||
0x180160: 0x18000b, # Desert Palace - Desert Torch
|
||||
0x289b0: 0x180018, # Master Sword Pedestal
|
||||
0xf69fa: 0x180007, # Old Man
|
||||
0x180162: 0x18000d, # Tower of Hera - Basement Cage
|
||||
0x330c7: 0x18000a, # Stumpy
|
||||
0x180161: 0x18000c # Ganons Tower - Bob's Torch
|
||||
}
|
||||
|
||||
|
||||
key_drop_data = {
|
||||
'Hyrule Castle - Map Guard Key Drop': [0x140036, 0x140037],
|
||||
'Hyrule Castle - Boomerang Guard Key Drop': [0x140033, 0x140034],
|
||||
'Hyrule Castle - Key Rat Key Drop': [0x14000c, 0x14000d],
|
||||
'Hyrule Castle - Big Key Drop': [0x14003c, 0x14003d],
|
||||
'Eastern Palace - Dark Square Pot Key': [0x14005a, 0x14005b],
|
||||
'Eastern Palace - Dark Eyegore Key Drop': [0x140048, 0x140049],
|
||||
'Desert Palace - Desert Tiles 1 Pot Key': [0x140030, 0x140031],
|
||||
'Desert Palace - Beamos Hall Pot Key': [0x14002a, 0x14002b],
|
||||
'Desert Palace - Desert Tiles 2 Pot Key': [0x140027, 0x140028],
|
||||
'Castle Tower - Dark Archer Key Drop': [0x140060, 0x140061],
|
||||
'Castle Tower - Circle of Pots Key Drop': [0x140051, 0x140052],
|
||||
'Swamp Palace - Pot Row Pot Key': [0x140018, 0x140019],
|
||||
'Swamp Palace - Trench 1 Pot Key': [0x140015, 0x140016],
|
||||
'Swamp Palace - Hookshot Pot Key': [0x140012, 0x140013],
|
||||
'Swamp Palace - Trench 2 Pot Key': [0x14000f, 0x140010],
|
||||
'Swamp Palace - Waterway Pot Key': [0x140009, 0x14000a],
|
||||
'Skull Woods - West Lobby Pot Key': [0x14002d, 0x14002e],
|
||||
'Skull Woods - Spike Corner Key Drop': [0x14001b, 0x14001c],
|
||||
'Thieves\' Town - Hallway Pot Key': [0x14005d, 0x14005e],
|
||||
'Thieves\' Town - Spike Switch Pot Key': [0x14004e, 0x14004f],
|
||||
'Ice Palace - Jelly Key Drop': [0x140003, 0x140004],
|
||||
'Ice Palace - Conveyor Key Drop': [0x140021, 0x140022],
|
||||
'Ice Palace - Hammer Block Key Drop': [0x140024, 0x140025],
|
||||
'Ice Palace - Many Pots Pot Key': [0x140045, 0x140046],
|
||||
'Misery Mire - Spikes Pot Key': [0x140054, 0x140055],
|
||||
'Misery Mire - Fishbone Pot Key': [0x14004b, 0x14004c],
|
||||
'Misery Mire - Conveyor Crystal Key Drop': [0x140063, 0x140064],
|
||||
'Turtle Rock - Pokey 1 Key Drop': [0x140057, 0x140058],
|
||||
'Turtle Rock - Pokey 2 Key Drop': [0x140006, 0x140007],
|
||||
'Ganons Tower - Conveyor Cross Pot Key': [0x14003f, 0x140040],
|
||||
'Ganons Tower - Double Switch Pot Key': [0x140042, 0x140043],
|
||||
'Ganons Tower - Conveyor Star Pits Pot Key': [0x140039, 0x14003a],
|
||||
'Ganons Tower - Mini Helmasaur Key Drop': [0x14001e, 0x14001f]
|
||||
}
|
||||
|
||||
location_table = {'Mushroom': (0x180013, 0x186338, False, 'in the woods'),
|
||||
'Bottle Merchant': (0x2eb18, 0x186339, False, 'with a merchant'),
|
||||
'Flute Spot': (0x18014a, 0x18633d, False, 'underground'),
|
||||
@@ -716,9 +640,7 @@ location_table = {'Mushroom': (0x180013, 0x186338, False, 'in the woods'),
|
||||
[0x120A7, 0x53F24, 0x53F25, 0x18005C, 0x180079, 0xC708], None, True, 'Turtle Rock')}
|
||||
|
||||
lookup_id_to_name = {data[0]: name for name, data in location_table.items() if type(data[0]) == int}
|
||||
lookup_id_to_name = {**lookup_id_to_name, **{data[1]: name for name, data in key_drop_data.items()}, -1: "cheat console"}
|
||||
lookup_name_to_id = {name: data[0] for name, data in location_table.items() if type(data[0]) == int}
|
||||
lookup_name_to_id = {**lookup_name_to_id, **{name: data[1] for name, data in key_drop_data.items()}, "cheat console": -1}
|
||||
lookup_id_to_name[-1] = "cheat console"
|
||||
|
||||
lookup_vanilla_location_to_entrance = {1572883: 'Kings Grave Inner Rocks', 191256: 'Kings Grave Inner Rocks',
|
||||
1573194: 'Kings Grave Inner Rocks', 1573189: 'Kings Grave Inner Rocks',
|
||||
@@ -823,28 +745,7 @@ lookup_vanilla_location_to_entrance = {1572883: 'Kings Grave Inner Rocks', 19125
|
||||
60103: 'Ganons Tower', 60106: 'Ganons Tower', 60109: 'Ganons Tower',
|
||||
60127: 'Ganons Tower', 60118: 'Ganons Tower', 60148: 'Ganons Tower',
|
||||
60151: 'Ganons Tower', 60145: 'Ganons Tower', 60157: 'Ganons Tower',
|
||||
60160: 'Ganons Tower', 60163: 'Ganons Tower', 60166: 'Ganons Tower',
|
||||
0x140037: 'Hyrule Castle Entrance (South)',
|
||||
0x140034: 'Hyrule Castle Entrance (South)',
|
||||
0x14000d: 'Hyrule Castle Entrance (South)',
|
||||
0x14003d: 'Hyrule Castle Entrance (South)',
|
||||
0x14005b: 'Eastern Palace', 0x140049: 'Eastern Palace',
|
||||
0x140031: 'Desert Palace Entrance (North)',
|
||||
0x14002b: 'Desert Palace Entrance (North)',
|
||||
0x140028: 'Desert Palace Entrance (North)',
|
||||
0x140061: 'Agahnims Tower', 0x140052: 'Agahnims Tower',
|
||||
0x140019: 'Swamp Palace', 0x140016: 'Swamp Palace', 0x140013: 'Swamp Palace',
|
||||
0x140010: 'Swamp Palace', 0x14000a: 'Swamp Palace',
|
||||
0x14002e: 'Skull Woods Second Section Door (East)',
|
||||
0x14001c: 'Skull Woods Final Section',
|
||||
0x14005e: 'Thieves Town', 0x14004f: 'Thieves Town',
|
||||
0x140004: 'Ice Palace', 0x140022: 'Ice Palace',
|
||||
0x140025: 'Ice Palace', 0x140046: 'Ice Palace',
|
||||
0x140055: 'Misery Mire', 0x14004c: 'Misery Mire',
|
||||
0x140064: 'Misery Mire',
|
||||
0x140058: 'Turtle Rock', 0x140007: 'Dark Death Mountain Ledge (West)',
|
||||
0x140040: 'Ganons Tower', 0x140043: 'Ganons Tower',
|
||||
0x14003a: 'Ganons Tower', 0x14001f: 'Ganons Tower'}
|
||||
60160: 'Ganons Tower', 60163: 'Ganons Tower', 60166: 'Ganons Tower'}
|
||||
|
||||
lookup_prizes = {location for location in location_table if location.endswith(" - Prize")}
|
||||
lookup_boss_drops = {location for location in location_table if location.endswith(" - Boss")}
|
||||
6
Rules.py
6
Rules.py
@@ -104,7 +104,7 @@ def mirrorless_path_to_castle_courtyard(world, player):
|
||||
else:
|
||||
queue.append((entrance.connected_region, new_path))
|
||||
|
||||
raise Exception(f"Could not find mirrorless path to castle courtyard for Player {player} ({world.get_player_names(player)})")
|
||||
raise Exception(f"Could not find mirrorless path to castle courtyard for Player {player}")
|
||||
|
||||
def set_rule(spot, rule):
|
||||
spot.access_rule = rule
|
||||
@@ -179,10 +179,6 @@ def locality_rules(world, player):
|
||||
for location in world.get_locations():
|
||||
if location.player != player:
|
||||
forbid_items_for_player(location, world.local_items[player], player)
|
||||
if world.non_local_items[player]:
|
||||
for location in world.get_locations():
|
||||
if location.player == player:
|
||||
forbid_items_for_player(location, world.non_local_items[player], player)
|
||||
|
||||
|
||||
non_crossover_items = (item_name_groups["Small Keys"] | item_name_groups["Big Keys"] | progression_items) - {
|
||||
|
||||
5
Text.py
5
Text.py
@@ -266,7 +266,7 @@ junk_texts = [
|
||||
"{C:GREEN}\n>Secret power\nis said to be\nin the arrow.",
|
||||
"{C:GREEN}\nAim at the\neyes of Gohma.\n >",
|
||||
"{C:GREEN}\nGrumble,\ngrumble…\n >",
|
||||
# "{C:GREEN}\n10th enemy\nhas the bomb.\n >", removed as people may assume it applies to this game
|
||||
"{C:GREEN}\n10th enemy\nhas the bomb.\n >",
|
||||
"{C:GREEN}\nGo to the\nnext room.\n >",
|
||||
"{C:GREEN}\n>Thanks, @\nYou’re the\nhero of Hyrule",
|
||||
"{C:GREEN}\nThere’s always\nmoney in the\nBanana Stand>",
|
||||
@@ -1228,8 +1228,7 @@ class GoldCreditMapper(CharTextMapper):
|
||||
|
||||
class GreenCreditMapper(CharTextMapper):
|
||||
char_map = {' ': 0x9F,
|
||||
'·': 0x52,
|
||||
'.': 0x52}
|
||||
'·': 0x52}
|
||||
alpha_offset = -0x29
|
||||
|
||||
class RedCreditMapper(CharTextMapper):
|
||||
|
||||
@@ -47,8 +47,6 @@ app.config["PONY"] = {
|
||||
}
|
||||
app.config["MAX_ROLL"] = 20
|
||||
app.config["CACHE_TYPE"] = "simple"
|
||||
app.config["JSON_AS_ASCII"] = False
|
||||
|
||||
app.autoversion = True
|
||||
av = Autoversion(app)
|
||||
cache = Cache(app)
|
||||
|
||||
@@ -37,10 +37,9 @@ def download_raw_patch(seed_id, player_id):
|
||||
return "Patch not found"
|
||||
else:
|
||||
import io
|
||||
if patch.seed.multidata:
|
||||
|
||||
pname = patch.seed.multidata["names"][0][patch.player - 1]
|
||||
else:
|
||||
pname = "unknown"
|
||||
|
||||
patch_data = update_patch_data(patch.data, server="")
|
||||
patch_data = io.BytesIO(patch_data)
|
||||
|
||||
|
||||
@@ -50,5 +50,5 @@ class Generation(db.Entity):
|
||||
id = PrimaryKey(UUID, default=uuid4)
|
||||
owner = Required(UUID)
|
||||
options = Required(bytes, lazy=True) # these didn't work as JSON on mariaDB, so they're getting pickled now
|
||||
meta = Required(bytes, lazy=True) # if state is -1 (error) this will contain an utf-8 encoded error message
|
||||
meta = Required(bytes, lazy=True)
|
||||
state = Required(int, default=0, index=True)
|
||||
|
||||
@@ -3,5 +3,5 @@ pony>=0.7.14
|
||||
waitress>=1.4.4
|
||||
flask-caching>=1.9.0
|
||||
Flask-Autoversion>=0.2.0
|
||||
Flask-Compress>=1.8.0
|
||||
Flask-Compress>=1.7.0
|
||||
Flask-Limiter>=1.4
|
||||
|
||||
@@ -165,6 +165,7 @@ item_pool:
|
||||
normal: 50 # Item availability remains unchanged from vanilla game
|
||||
hard: 0 # Reduced upgrade availability (max: 14 hearts, blue 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)
|
||||
crowd_control: 0 # Sets up the item pool for the crowd control extension. Do not use it without crowd control
|
||||
item_functionality:
|
||||
easy: 0 # Allow Hammer to damage ganon, Allow Hammer tablet collection, Allow swordless medallion use everywhere.
|
||||
normal: 50 # Vanilla item functionality
|
||||
@@ -231,22 +232,6 @@ timer:
|
||||
ohko: 0 # Timer always at zero. Permanent OHKO.
|
||||
timed_countdown: 0 # Starts the clock with forty minutes. Same clocks as timed mode, but if the clock hits zero you lose. You can still keep playing, though.
|
||||
display: 0 # Displays a timer, but otherwise does not affect gameplay or the item pool.
|
||||
countdown_start_time: # For timed_ohko and timed_countdown timer modes, the amount of time in minutes to start with
|
||||
0: 0 # For timed_ohko, starts in OHKO mode when starting the game
|
||||
10: 50
|
||||
20: 0
|
||||
30: 0
|
||||
60: 0
|
||||
red_clock_time: # For all timer modes, the amount of time in minutes to gain or lose when picking up a red clock
|
||||
-2: 50
|
||||
1: 0
|
||||
blue_clock_time: # For all timer modes, the amount of time in minutes to gain or lose when picking up a blue clock
|
||||
1: 0
|
||||
2: 50
|
||||
green_clock_time: # For all timer modes, the amount of time in minutes to gain or lose when picking up a green clock
|
||||
4: 50
|
||||
10: 0
|
||||
15: 0
|
||||
# Can be uncommented to use it
|
||||
# local_items: # Force certain items to appear in your world only, not across the multiworld. Recognizes some group names, like "Swords"
|
||||
# - "Moon Pearl"
|
||||
@@ -304,9 +289,6 @@ intensity: # Only available if the host uses the doors branch, it is ignored oth
|
||||
2: 0 # And shuffles open edges and straight staircases
|
||||
3: 0 # And shuffles dungeon lobbies
|
||||
random: 0 # Picks one of those at random
|
||||
key_drop_shuffle: # Only available if the host uses the doors branch, it is ignored otherwise
|
||||
on: 0 # Enables the small keys dropped by enemies or under pots, and the big key dropped by the Ball & Chain guard to be shuffled into the pool. This extends the number of checks to 249.
|
||||
off: 50
|
||||
experimental: # Only available if the host uses the doors branch, it is ignored otherwise
|
||||
on: 0 # Enables experimental features. Currently, this is just the dungeon keys in chest counter.
|
||||
off: 50
|
||||
@@ -409,3 +391,13 @@ rom:
|
||||
dizzy: 0
|
||||
sick: 0
|
||||
puke: 0
|
||||
uw_palettes: # Change the colors of shields
|
||||
default: 50 # No changes
|
||||
random: 0 # Shuffle the colors
|
||||
blackout: 0 # Never use this
|
||||
grayscale: 0
|
||||
negative: 0
|
||||
classic: 0
|
||||
dizzy: 0
|
||||
sick: 0
|
||||
puke: 0
|
||||
@@ -124,7 +124,7 @@
|
||||
<td>{{ player_names[(team, loop.index)]|e }}</td>
|
||||
{%- for area in ordered_areas -%}
|
||||
{%- set checks_done = checks[area] -%}
|
||||
{%- set checks_total = checks_in_area[player][area] -%}
|
||||
{%- set checks_total = checks_in_area[area] -%}
|
||||
{%- if checks_done == checks_total -%}
|
||||
<td class="item-acquired center-column">
|
||||
{{ checks_done }}/{{ checks_total }}</td>
|
||||
|
||||
@@ -180,25 +180,6 @@ default_locations = {
|
||||
60121, 60124, 60127, 1573217, 60130, 60133, 60136, 60139, 60142, 60145, 60148, 60151, 60157},
|
||||
'Total': set()}
|
||||
|
||||
key_only_locations = {
|
||||
'Light World': set(),
|
||||
'Dark World': set(),
|
||||
'Desert Palace': {0x140031, 0x14002b, 0x140061, 0x140028},
|
||||
'Eastern Palace': {0x14005b, 0x140049},
|
||||
'Hyrule Castle': {0x140037, 0x140034, 0x14000d, 0x14003d},
|
||||
'Agahnims Tower': {0x140061, 0x140052},
|
||||
'Tower of Hera': set(),
|
||||
'Swamp Palace': {0x140019, 0x140016, 0x140013, 0x140010, 0x14000a},
|
||||
'Thieves Town': {0x14005e, 0x14004f},
|
||||
'Skull Woods': {0x14002e, 0x14001c},
|
||||
'Ice Palace': {0x140004, 0x140022, 0x140025, 0x140046},
|
||||
'Misery Mire': {0x140055, 0x14004c, 0x140064},
|
||||
'Turtle Rock': {0x140058, 0x140007},
|
||||
'Palace of Darkness': set(),
|
||||
'Ganons Tower': {0x140040, 0x140043, 0x14003a, 0x14001f},
|
||||
'Total': set()
|
||||
}
|
||||
|
||||
key_locations = {"Desert Palace", "Eastern Palace", "Hyrule Castle", "Agahnims Tower", "Tower of Hera", "Swamp Palace",
|
||||
"Thieves Town", "Skull Woods", "Ice Palace", "Misery Mire", "Turtle Rock", "Palace of Darkness",
|
||||
"Ganons Tower"}
|
||||
@@ -210,10 +191,6 @@ for area, locations in default_locations.items():
|
||||
for location in locations:
|
||||
location_to_area[location] = area
|
||||
|
||||
for area, locations in key_only_locations.items():
|
||||
for location in locations:
|
||||
location_to_area[location] = area
|
||||
|
||||
checks_in_area = {area: len(checks) for area, checks in default_locations.items()}
|
||||
checks_in_area["Total"] = 216
|
||||
|
||||
@@ -258,14 +235,6 @@ def render_timedelta(delta: datetime.timedelta):
|
||||
|
||||
_multidata_cache = {}
|
||||
|
||||
def get_location_table(checks_table: dict) -> dict:
|
||||
loc_to_area = {}
|
||||
for area, locations in checks_table.items():
|
||||
if area == "Total":
|
||||
continue
|
||||
for location in locations:
|
||||
loc_to_area[location] = area
|
||||
return loc_to_area
|
||||
|
||||
def get_static_room_data(room: Room):
|
||||
result = _multidata_cache.get(room.seed.id, None)
|
||||
@@ -275,30 +244,11 @@ def get_static_room_data(room: Room):
|
||||
# in > 100 players this can take a bit of time and is the main reason for the cache
|
||||
locations = {tuple(k): tuple(v) for k, v in multidata['locations']}
|
||||
names = multidata["names"]
|
||||
seed_checks_in_area = checks_in_area.copy()
|
||||
|
||||
use_door_tracker = False
|
||||
if "tags" in multidata:
|
||||
use_door_tracker = "DR" in multidata["tags"]
|
||||
if use_door_tracker:
|
||||
for area, checks in key_only_locations.items():
|
||||
seed_checks_in_area[area] += len(checks)
|
||||
seed_checks_in_area["Total"] = 249
|
||||
if "checks_in_area" not in multidata:
|
||||
player_checks_in_area = {playernumber: (seed_checks_in_area if use_door_tracker and
|
||||
(0x140031, playernumber) in locations else checks_in_area)
|
||||
for playernumber in range(1, len(names[0]) + 1)}
|
||||
player_location_to_area = {playernumber: location_to_area
|
||||
for playernumber in range(1, len(names[0]) + 1)}
|
||||
|
||||
else:
|
||||
player_checks_in_area = {playernumber: {areaname: len(multidata["checks_in_area"][f'{playernumber}'][areaname])
|
||||
if areaname != "Total" else multidata["checks_in_area"][f'{playernumber}']["Total"]
|
||||
for areaname in ordered_areas}
|
||||
for playernumber in range(1, len(names[0]) + 1)}
|
||||
player_location_to_area = {playernumber: get_location_table(multidata["checks_in_area"][f'{playernumber}'])
|
||||
for playernumber in range(1, len(names[0]) + 1)}
|
||||
result = locations, names, use_door_tracker, player_checks_in_area, player_location_to_area
|
||||
result = locations, names, use_door_tracker
|
||||
_multidata_cache[room.seed.id] = result
|
||||
return result
|
||||
|
||||
@@ -309,7 +259,7 @@ def getTracker(tracker: UUID):
|
||||
room = Room.get(tracker=tracker)
|
||||
if not room:
|
||||
abort(404)
|
||||
locations, names, use_door_tracker, seed_checks_in_area, player_location_to_area = get_static_room_data(room)
|
||||
locations, names, use_door_tracker = get_static_room_data(room)
|
||||
|
||||
inventory = {teamnumber: {playernumber: collections.Counter() for playernumber in range(1, len(team) + 1)}
|
||||
for teamnumber, team in enumerate(names)}
|
||||
@@ -330,12 +280,9 @@ def getTracker(tracker: UUID):
|
||||
for item_id in precollected:
|
||||
attribute_item(inventory, team, player, item_id)
|
||||
for location in locations_checked:
|
||||
if (location, player) not in locations or location not in player_location_to_area[player]:
|
||||
continue
|
||||
|
||||
item, recipient = locations[location, player]
|
||||
attribute_item(inventory, team, recipient, item)
|
||||
checks_done[team][player][player_location_to_area[player][location]] += 1
|
||||
checks_done[team][player][location_to_area[location]] += 1
|
||||
checks_done[team][player]["Total"] += 1
|
||||
|
||||
for (team, player), game_state in room.multisave.get("client_game_state", []):
|
||||
@@ -364,7 +311,7 @@ def getTracker(tracker: UUID):
|
||||
lookup_id_to_name=Items.lookup_id_to_name, player_names=player_names,
|
||||
tracking_names=tracking_names, tracking_ids=tracking_ids, room=room, icons=icons,
|
||||
multi_items=multi_items, checks_done=checks_done, ordered_areas=ordered_areas,
|
||||
checks_in_area=seed_checks_in_area, activity_timers=activity_timers,
|
||||
checks_in_area=checks_in_area, activity_timers=activity_timers,
|
||||
key_locations=key_locations, small_key_ids=small_key_ids, big_key_ids=big_key_ids,
|
||||
video=video, big_key_locations=key_locations if use_door_tracker else big_key_locations,
|
||||
hints=hints, long_player_names = long_player_names)
|
||||
|
||||
2
data/sprites/alttpr/.gitignore
vendored
2
data/sprites/alttpr/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
*
|
||||
!.gitignore
|
||||
BIN
data/sprites/alttpr/001.link.1.zspr
Normal file
BIN
data/sprites/alttpr/001.link.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/4slink-armors.1.zspr
Normal file
BIN
data/sprites/alttpr/4slink-armors.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/abigail.1.zspr
Normal file
BIN
data/sprites/alttpr/abigail.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/adol.1.zspr
Normal file
BIN
data/sprites/alttpr/adol.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/aggretsuko.1.zspr
Normal file
BIN
data/sprites/alttpr/aggretsuko.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/alice.1.zspr
Normal file
BIN
data/sprites/alttpr/alice.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/angry-video-game-nerd.1.zspr
Normal file
BIN
data/sprites/alttpr/angry-video-game-nerd.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/arcane.1.zspr
Normal file
BIN
data/sprites/alttpr/arcane.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/ark.2.zspr
Normal file
BIN
data/sprites/alttpr/ark.2.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/arrghus.2.zspr
Normal file
BIN
data/sprites/alttpr/arrghus.2.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/astronaut.1.zspr
Normal file
BIN
data/sprites/alttpr/astronaut.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/badeline.1.zspr
Normal file
BIN
data/sprites/alttpr/badeline.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/bananas-in-pyjamas.1.zspr
Normal file
BIN
data/sprites/alttpr/bananas-in-pyjamas.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/bandit.1.zspr
Normal file
BIN
data/sprites/alttpr/bandit.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/batman.1.zspr
Normal file
BIN
data/sprites/alttpr/batman.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/beau.1.zspr
Normal file
BIN
data/sprites/alttpr/beau.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/bewp.1.zspr
Normal file
BIN
data/sprites/alttpr/bewp.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/bigkey.1.zspr
Normal file
BIN
data/sprites/alttpr/bigkey.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/birb.1.zspr
Normal file
BIN
data/sprites/alttpr/birb.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/birdo.1.zspr
Normal file
BIN
data/sprites/alttpr/birdo.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/blackmage.1.zspr
Normal file
BIN
data/sprites/alttpr/blackmage.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/blacksmithlink.1.zspr
Normal file
BIN
data/sprites/alttpr/blacksmithlink.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/blossom.1.zspr
Normal file
BIN
data/sprites/alttpr/blossom.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/bob.1.zspr
Normal file
BIN
data/sprites/alttpr/bob.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/boo-two.1.zspr
Normal file
BIN
data/sprites/alttpr/boo-two.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/boo.2.zspr
Normal file
BIN
data/sprites/alttpr/boo.2.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/bottle_o_goo.1.zspr
Normal file
BIN
data/sprites/alttpr/bottle_o_goo.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/botw-zelda.1.zspr
Normal file
BIN
data/sprites/alttpr/botw-zelda.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/bowser.1.zspr
Normal file
BIN
data/sprites/alttpr/bowser.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/branch.1.zspr
Normal file
BIN
data/sprites/alttpr/branch.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/brian.1.zspr
Normal file
BIN
data/sprites/alttpr/brian.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/broccoli.1.zspr
Normal file
BIN
data/sprites/alttpr/broccoli.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/bronzor.1.zspr
Normal file
BIN
data/sprites/alttpr/bronzor.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/bsboy.1.zspr
Normal file
BIN
data/sprites/alttpr/bsboy.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/bsgirl.1.zspr
Normal file
BIN
data/sprites/alttpr/bsgirl.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/bubbles.1.zspr
Normal file
BIN
data/sprites/alttpr/bubbles.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/bullet_bill.1.zspr
Normal file
BIN
data/sprites/alttpr/bullet_bill.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/buttercup.1.zspr
Normal file
BIN
data/sprites/alttpr/buttercup.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/cactuar.1.zspr
Normal file
BIN
data/sprites/alttpr/cactuar.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/cadence.1.zspr
Normal file
BIN
data/sprites/alttpr/cadence.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/carlsagan42.1.zspr
Normal file
BIN
data/sprites/alttpr/carlsagan42.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/casual-zelda.1.zspr
Normal file
BIN
data/sprites/alttpr/casual-zelda.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/cat.3.zspr
Normal file
BIN
data/sprites/alttpr/cat.3.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/catboo.1.zspr
Normal file
BIN
data/sprites/alttpr/catboo.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/cdilink.1.zspr
Normal file
BIN
data/sprites/alttpr/cdilink.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/celes.1.zspr
Normal file
BIN
data/sprites/alttpr/celes.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/charizard.1.zspr
Normal file
BIN
data/sprites/alttpr/charizard.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/cheepcheep.1.zspr
Normal file
BIN
data/sprites/alttpr/cheepcheep.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/chibity.1.zspr
Normal file
BIN
data/sprites/alttpr/chibity.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/cirno.1.zspr
Normal file
BIN
data/sprites/alttpr/cirno.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/clifford.1.zspr
Normal file
BIN
data/sprites/alttpr/clifford.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/clyde.1.zspr
Normal file
BIN
data/sprites/alttpr/clyde.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/conker.1.zspr
Normal file
BIN
data/sprites/alttpr/conker.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/cornelius.1.zspr
Normal file
BIN
data/sprites/alttpr/cornelius.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/corona.1.zspr
Normal file
BIN
data/sprites/alttpr/corona.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/cucco.1.zspr
Normal file
BIN
data/sprites/alttpr/cucco.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/cursor.1.zspr
Normal file
BIN
data/sprites/alttpr/cursor.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/d_owls.1.zspr
Normal file
BIN
data/sprites/alttpr/d_owls.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/dark-panda.1.zspr
Normal file
BIN
data/sprites/alttpr/dark-panda.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/darkboy.1.zspr
Normal file
BIN
data/sprites/alttpr/darkboy.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/darkgirl.1.zspr
Normal file
BIN
data/sprites/alttpr/darkgirl.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/darklink-tunic.1.zspr
Normal file
BIN
data/sprites/alttpr/darklink-tunic.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/darklink.1.zspr
Normal file
BIN
data/sprites/alttpr/darklink.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/darkswatchy.1.zspr
Normal file
BIN
data/sprites/alttpr/darkswatchy.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/darkzelda.1.zspr
Normal file
BIN
data/sprites/alttpr/darkzelda.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/darkzora.2.zspr
Normal file
BIN
data/sprites/alttpr/darkzora.2.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/deadpool-mythic.1.zspr
Normal file
BIN
data/sprites/alttpr/deadpool-mythic.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/deadpool.1.zspr
Normal file
BIN
data/sprites/alttpr/deadpool.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/deadrock.1.zspr
Normal file
BIN
data/sprites/alttpr/deadrock.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/decidueye.1.zspr
Normal file
BIN
data/sprites/alttpr/decidueye.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/demonlink.1.zspr
Normal file
BIN
data/sprites/alttpr/demonlink.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/dragonite.2.zspr
Normal file
BIN
data/sprites/alttpr/dragonite.2.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/drake.1.zspr
Normal file
BIN
data/sprites/alttpr/drake.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/eggplant.1.zspr
Normal file
BIN
data/sprites/alttpr/eggplant.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/emosaru.1.zspr
Normal file
BIN
data/sprites/alttpr/emosaru.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/ezlo.1.zspr
Normal file
BIN
data/sprites/alttpr/ezlo.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/fierce-deity-link.1.zspr
Normal file
BIN
data/sprites/alttpr/fierce-deity-link.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/finn.3.zspr
Normal file
BIN
data/sprites/alttpr/finn.3.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/finny_bear.1.zspr
Normal file
BIN
data/sprites/alttpr/finny_bear.1.zspr
Normal file
Binary file not shown.
BIN
data/sprites/alttpr/fish_floodgate.1.zspr
Normal file
BIN
data/sprites/alttpr/fish_floodgate.1.zspr
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user