fix(key logic): typo
This commit is contained in:
@@ -10,7 +10,6 @@ try:
|
||||
except ImportError:
|
||||
from enum import IntFlag as FastEnum
|
||||
|
||||
|
||||
from source.classes.BabelFish import BabelFish
|
||||
from EntranceShuffle import door_addresses, indirect_connections
|
||||
from Utils import int16_as_bytes
|
||||
@@ -94,6 +93,7 @@ class World(object):
|
||||
for player in range(1, players + 1):
|
||||
def set_player_attr(attr, val):
|
||||
self.__dict__.setdefault(attr, {})[player] = val
|
||||
|
||||
set_player_attr('_region_cache', {})
|
||||
set_player_attr('player_names', [])
|
||||
set_player_attr('remote_items', False)
|
||||
@@ -1013,7 +1013,6 @@ class CollectionState(object):
|
||||
self.collect(event.item, True, event)
|
||||
new_locations = True
|
||||
|
||||
|
||||
def can_reach_blue(self, region, player):
|
||||
return region in self.reachable_regions[player] and self.reachable_regions[player][region] in [CrystalBarrier.Blue, CrystalBarrier.Either]
|
||||
|
||||
@@ -1124,7 +1123,7 @@ class CollectionState(object):
|
||||
def can_lift_heavy_rocks(self, player):
|
||||
return self.has('Titans Mitts', player)
|
||||
|
||||
def can_extend_magic(self, player, smallmagic=16, fullrefill=False): #This reflects the total magic Link has, not the total extra he has.
|
||||
def can_extend_magic(self, player, smallmagic=16, fullrefill=False): # This reflects the total magic Link has, not the total extra he has.
|
||||
basemagic = 8
|
||||
if self.has('Magic Upgrade (1/4)', player):
|
||||
basemagic = 32
|
||||
@@ -1174,7 +1173,7 @@ class CollectionState(object):
|
||||
|
||||
def can_shoot_arrows(self, player):
|
||||
if self.world.bow_mode[player] in ['retro', 'retro_silvers']:
|
||||
#todo: Non-progressive silvers grant wooden arrows, but progressive bows do not. Always require shop arrows to be safe
|
||||
# todo: Non-progressive silvers grant wooden arrows, but progressive bows do not. Always require shop arrows to be safe
|
||||
return self.has('Bow', player) and (self.can_buy_unlimited('Single Arrow', player) or self.has('Single Arrow', player))
|
||||
return self.has('Bow', player)
|
||||
|
||||
@@ -1403,13 +1402,14 @@ class CollectionState(object):
|
||||
def __getattr__(self, item):
|
||||
if item.startswith('can_reach_'):
|
||||
return self.can_reach(item[10])
|
||||
#elif item.startswith('has_'):
|
||||
# elif item.startswith('has_'):
|
||||
# return self.has(item[4])
|
||||
if item == '__len__':
|
||||
return
|
||||
|
||||
raise RuntimeError('Cannot parse %s.' % item)
|
||||
|
||||
|
||||
@unique
|
||||
class RegionType(Enum):
|
||||
Menu = 0
|
||||
@@ -1747,7 +1747,7 @@ class Door(object):
|
||||
self.edge_id = None
|
||||
self.edge_width = None
|
||||
|
||||
#portal items
|
||||
# portal items
|
||||
self.portalAble = False
|
||||
self.roomLayout = 0x22 # free scroll- both directions
|
||||
self.entranceFlag = False
|
||||
@@ -2093,17 +2093,17 @@ class Portal(object):
|
||||
return self.door.roomIndex
|
||||
|
||||
def relative_coords(self):
|
||||
y_rel = (self.door.roomIndex & 0xf0) >> 3 #todo: fix the shift!!!!
|
||||
y_rel = (self.door.roomIndex & 0xf0) >> 3 # todo: fix the shift!!!!
|
||||
x_rel = (self.door.roomIndex & 0x0f) * 2
|
||||
quad = self.door.quadrant
|
||||
if quad == 0:
|
||||
return [y_rel, y_rel, y_rel, y_rel+1, x_rel, x_rel, x_rel, x_rel+1]
|
||||
return [y_rel, y_rel, y_rel, y_rel + 1, x_rel, x_rel, x_rel, x_rel + 1]
|
||||
elif quad == 1:
|
||||
return [y_rel, y_rel, y_rel, y_rel+1, x_rel+1, x_rel, x_rel+1, x_rel+1]
|
||||
return [y_rel, y_rel, y_rel, y_rel + 1, x_rel + 1, x_rel, x_rel + 1, x_rel + 1]
|
||||
elif quad == 2:
|
||||
return [y_rel+1, y_rel, y_rel+1, y_rel+1, x_rel, x_rel, x_rel, x_rel+1]
|
||||
return [y_rel + 1, y_rel, y_rel + 1, y_rel + 1, x_rel, x_rel, x_rel, x_rel + 1]
|
||||
else:
|
||||
return [y_rel+1, y_rel, y_rel+1, y_rel+1, x_rel+1, x_rel, x_rel+1, x_rel+1]
|
||||
return [y_rel + 1, y_rel, y_rel + 1, y_rel + 1, x_rel + 1, x_rel, x_rel + 1, x_rel + 1]
|
||||
|
||||
def scroll_x(self):
|
||||
x_rel = (self.door.roomIndex & 0x0f) * 2
|
||||
@@ -2112,7 +2112,7 @@ class Portal(object):
|
||||
elif self.door.doorIndex == 1:
|
||||
return [0x80, x_rel]
|
||||
else:
|
||||
return [0x00, x_rel+1]
|
||||
return [0x00, x_rel + 1]
|
||||
|
||||
def scroll_y(self):
|
||||
y_rel = ((self.door.roomIndex & 0xf0) >> 3) + 1
|
||||
@@ -2132,7 +2132,7 @@ class Portal(object):
|
||||
elif self.door.doorIndex == 1:
|
||||
return [0xf8, x_rel]
|
||||
else:
|
||||
return [0x78, x_rel+1]
|
||||
return [0x78, x_rel + 1]
|
||||
|
||||
# def camera_y(self):
|
||||
# return [0x87, 0x01]
|
||||
@@ -2191,6 +2191,7 @@ class Boss(object):
|
||||
def can_defeat(self, state):
|
||||
return self.defeat_rule(state, self.player)
|
||||
|
||||
|
||||
class Location(object):
|
||||
def __init__(self, player, name='', address=None, crystal=False, hint_text=None, parent=None, forced_item=None,
|
||||
player_address=None, note=None):
|
||||
@@ -2353,12 +2354,14 @@ class Item(object):
|
||||
class Crystal(Item):
|
||||
pass
|
||||
|
||||
|
||||
@unique
|
||||
class ShopType(Enum):
|
||||
Shop = 0
|
||||
TakeAny = 1
|
||||
UpgradeShop = 2
|
||||
|
||||
|
||||
class Shop(object):
|
||||
def __init__(self, region, room_id, type, shopkeeper_config, custom, locked, sram_address):
|
||||
self.region = region
|
||||
@@ -2382,7 +2385,7 @@ class Shop(object):
|
||||
entrances = self.region.entrances
|
||||
config = self.item_count
|
||||
if len(entrances) == 1 and entrances[0].name in door_addresses:
|
||||
door_id = door_addresses[entrances[0].name][0]+1
|
||||
door_id = door_addresses[entrances[0].name][0] + 1
|
||||
else:
|
||||
door_id = 0
|
||||
config |= 0x40 # ignore door id
|
||||
@@ -2390,7 +2393,7 @@ class Shop(object):
|
||||
config |= 0x80
|
||||
if self.type == ShopType.UpgradeShop:
|
||||
config |= 0x10 # Alt. VRAM
|
||||
return [0x00]+int16_as_bytes(self.room_id)+[door_id, 0x00, config, self.shopkeeper_config, 0x00]
|
||||
return [0x00] + int16_as_bytes(self.room_id) + [door_id, 0x00, config, self.shopkeeper_config, 0x00]
|
||||
|
||||
def has_unlimited(self, item):
|
||||
for inv in self.inventory:
|
||||
@@ -2632,7 +2635,7 @@ class Spoiler(object):
|
||||
out['Special'] = self.medallions
|
||||
out['Bottles'] = self.bottles
|
||||
if self.hashes:
|
||||
out['Hashes'] = {f"{self.world.player_names[player][team]} (Team {team+1})": hash for (player, team), hash in self.hashes.items()}
|
||||
out['Hashes'] = {f"{self.world.player_names[player][team]} (Team {team + 1})": hash for (player, team), hash in self.hashes.items()}
|
||||
if self.shops:
|
||||
out['Shops'] = self.shops
|
||||
out['playthrough'] = self.playthrough
|
||||
@@ -2723,7 +2726,7 @@ class Spoiler(object):
|
||||
|
||||
if self.startinventory:
|
||||
outfile.write('Starting Inventory:'.ljust(line_width))
|
||||
outfile.write('\n'.ljust(line_width+1).join(self.startinventory) + '\n')
|
||||
outfile.write('\n'.ljust(line_width + 1).join(self.startinventory) + '\n')
|
||||
|
||||
def hashes_to_file(self, filename):
|
||||
with open(filename, 'r') as infile:
|
||||
@@ -2743,7 +2746,7 @@ class Spoiler(object):
|
||||
if len(self.hashes) > 0:
|
||||
for team in range(self.world.teams):
|
||||
player_name = self.world.player_names[player][team]
|
||||
label = f"Hash - {player_name} (Team {team+1}): " if self.world.teams > 1 else 'Hash: '
|
||||
label = f"Hash - {player_name} (Team {team + 1}): " if self.world.teams > 1 else 'Hash: '
|
||||
idx = insert(contents, idx, f'{label}{self.hashes[player, team]}\n')
|
||||
if self.world.players > 1:
|
||||
insert(contents, idx, '\n') # return value ignored here, if you want to add more lines
|
||||
@@ -2774,16 +2777,16 @@ class Spoiler(object):
|
||||
if self.entrances:
|
||||
# entrances: To/From overworld; Checking w/ & w/out "Exit" and translating accordingly
|
||||
outfile.write('\nEntrances:\n\n')
|
||||
outfile.write('\n'.join(['%s%s %s %s' % (f'{self.world.get_player_names(entry["player"])}: ' if self.world.players > 1 else '', self.world.fish.translate("meta","entrances",entry['entrance']), '<=>' if entry['direction'] == 'both' else '<=' if entry['direction'] == 'exit' else '=>', self.world.fish.translate("meta","entrances",entry['exit'])) for entry in self.entrances.values()]))
|
||||
outfile.write('\n'.join(['%s%s %s %s' % (f'{self.world.get_player_names(entry["player"])}: ' if self.world.players > 1 else '', self.world.fish.translate("meta", "entrances", entry['entrance']), '<=>' if entry['direction'] == 'both' else '<=' if entry['direction'] == 'exit' else '=>', self.world.fish.translate("meta", "entrances", entry['exit'])) for entry in self.entrances.values()]))
|
||||
|
||||
if self.doors:
|
||||
outfile.write('\n\nDoors:\n\n')
|
||||
outfile.write('\n'.join(
|
||||
['%s%s %s %s %s' % ('Player {0}: '.format(entry['player']) if self.world.players > 1 else '',
|
||||
self.world.fish.translate("meta","doors",entry['entrance']),
|
||||
self.world.fish.translate("meta", "doors", entry['entrance']),
|
||||
'<=>' if entry['direction'] == 'both' else '<=' if entry['direction'] == 'exit' else '=>',
|
||||
self.world.fish.translate("meta","doors",entry['exit']),
|
||||
'({0})'.format(entry['dname']) if self.world.doorShuffle[entry['player']] == 'crossed' else '') for
|
||||
self.world.fish.translate("meta", "doors", entry['exit']),
|
||||
'({0})'.format(entry['dname']) if self.world.doorShuffle[entry['player']] != 'basic' else '') for
|
||||
entry in self.doors.values()]))
|
||||
if self.lobbies:
|
||||
outfile.write('\n\nDungeon Lobbies:\n\n')
|
||||
@@ -2795,7 +2798,7 @@ class Spoiler(object):
|
||||
# doorNames: For some reason these come in combined, somehow need to split on the thing to translate
|
||||
# doorTypes: Small Key, Bombable, Bonkable
|
||||
outfile.write('\n\nDoor Types:\n\n')
|
||||
outfile.write('\n'.join(['%s%s %s' % ('Player {0}: '.format(entry['player']) if self.world.players > 1 else '', self.world.fish.translate("meta","doors",entry['doorNames']), self.world.fish.translate("meta","doorTypes",entry['type'])) for entry in self.doorTypes.values()]))
|
||||
outfile.write('\n'.join(['%s%s %s' % ('Player {0}: '.format(entry['player']) if self.world.players > 1 else '', self.world.fish.translate("meta", "doors", entry['doorNames']), self.world.fish.translate("meta", "doorTypes", entry['type'])) for entry in self.doorTypes.values()]))
|
||||
|
||||
# locations: Change up location names; in the instance of a location with multiple sections, it'll try to translate the room name
|
||||
# items: Item names
|
||||
@@ -2805,7 +2808,7 @@ class Spoiler(object):
|
||||
# locations: Change up location names; in the instance of a location with multiple sections, it'll try to translate the room name
|
||||
# items: Item names
|
||||
outfile.write('\n\nShops:\n\n')
|
||||
outfile.write('\n'.join("{} [{}]\n {}".format(self.world.fish.translate("meta","locations",shop['location']), shop['type'], "\n ".join(self.world.fish.translate("meta","items",item) for item in [shop.get('item_0', None), shop.get('item_1', None), shop.get('item_2', None)] if item)) for shop in self.shops))
|
||||
outfile.write('\n'.join("{} [{}]\n {}".format(self.world.fish.translate("meta", "locations", shop['location']), shop['type'], "\n ".join(self.world.fish.translate("meta", "items", item) for item in [shop.get('item_0', None), shop.get('item_1', None), shop.get('item_2', None)] if item)) for shop in self.shops))
|
||||
|
||||
for player in range(1, self.world.players + 1):
|
||||
if self.world.boss_shuffle[player] != 'none':
|
||||
@@ -2818,23 +2821,23 @@ class Spoiler(object):
|
||||
with open(filename, 'a') as outfile:
|
||||
outfile.write('\n\nOverworld Enemies:\n\n')
|
||||
for player in range(1, self.world.players + 1):
|
||||
player_tag = ' '+self.world.get_player_names(player) if self.world.players > 1 else ''
|
||||
player_tag = ' ' + self.world.get_player_names(player) if self.world.players > 1 else ''
|
||||
for area, sprite_list in self.world.data_tables[player].ow_enemy_table.items():
|
||||
for idx, sprite in enumerate(sprite_list):
|
||||
outfile.write(f'{hex(area)} Enemy #{idx+1}{player_tag}: {str(sprite)}\n')
|
||||
outfile.write(f'{hex(area)} Enemy #{idx + 1}{player_tag}: {str(sprite)}\n')
|
||||
outfile.write('\n\nUnderworld Enemies:\n\n')
|
||||
for player in range(1, self.world.players + 1):
|
||||
player_tag = ' '+self.world.get_player_names(player) if self.world.players > 1 else ''
|
||||
player_tag = ' ' + self.world.get_player_names(player) if self.world.players > 1 else ''
|
||||
for area, sprite_list in self.world.data_tables[player].uw_enemy_table.room_map.items():
|
||||
for idx, sprite in enumerate(sprite_list):
|
||||
outfile.write(f'{hex(area)} Enemy #{idx+1}{player_tag}: {str(sprite)}\n')
|
||||
outfile.write(f'{hex(area)} Enemy #{idx + 1}{player_tag}: {str(sprite)}\n')
|
||||
|
||||
def playthrough_to_file(self, filename):
|
||||
with open(filename, 'a') as outfile:
|
||||
# locations: Change up location names; in the instance of a location with multiple sections, it'll try to translate the room name
|
||||
# items: Item names
|
||||
outfile.write('\n\nPlaythrough:\n\n')
|
||||
outfile.write('\n'.join(['%s: {\n%s\n}' % (sphere_nr, '\n'.join([' %s: %s' % (self.world.fish.translate("meta","locations",location), self.world.fish.translate("meta","items",item)) for (location, item) in sphere.items()] if sphere_nr != '0' else [f' {item}' for item in sphere])) for (sphere_nr, sphere) in self.playthrough.items()]))
|
||||
outfile.write('\n'.join(['%s: {\n%s\n}' % (sphere_nr, '\n'.join([' %s: %s' % (self.world.fish.translate("meta", "locations", location), self.world.fish.translate("meta", "items", item)) for (location, item) in sphere.items()] if sphere_nr != '0' else [f' {item}' for item in sphere])) for (sphere_nr, sphere) in self.playthrough.items()]))
|
||||
if self.unreachables:
|
||||
# locations: Change up location names; in the instance of a location with multiple sections, it'll try to translate the room name
|
||||
# items: Item names
|
||||
@@ -2852,10 +2855,10 @@ class Spoiler(object):
|
||||
path_lines = []
|
||||
for region, exit in path:
|
||||
if exit is not None:
|
||||
path_lines.append("{} -> {}".format(self.world.fish.translate("meta","rooms",region), self.world.fish.translate("meta","entrances",exit)))
|
||||
path_lines.append("{} -> {}".format(self.world.fish.translate("meta", "rooms", region), self.world.fish.translate("meta", "entrances", exit)))
|
||||
else:
|
||||
path_lines.append(self.world.fish.translate("meta","rooms",region))
|
||||
path_listings.append("{}\n {}".format(self.world.fish.translate("meta","locations",location), "\n => ".join(path_lines)))
|
||||
path_lines.append(self.world.fish.translate("meta", "rooms", region))
|
||||
path_listings.append("{}\n {}".format(self.world.fish.translate("meta", "locations", location), "\n => ".join(path_lines)))
|
||||
|
||||
outfile.write('\n'.join(path_listings))
|
||||
|
||||
@@ -2887,6 +2890,7 @@ dungeon_keys = {
|
||||
'Universal': 'Small Key (Universal)'
|
||||
}
|
||||
|
||||
|
||||
class PotItem(FastEnum):
|
||||
Nothing = 0x0
|
||||
OneRupee = 0x1
|
||||
@@ -3008,7 +3012,6 @@ rb_mode = {"none": 0, "mapcompass": 1, "dungeon": 2}
|
||||
algo_mode = {"balanced": 0, "equitable": 1, "vanilla_fill": 2, "dungeon_only": 3, "district": 4, 'major_only': 5}
|
||||
boss_mode = {"none": 0, "simple": 1, "full": 2, "chaos": 3, 'random': 3, 'unique': 4}
|
||||
|
||||
|
||||
# byte 10: settings_version
|
||||
# byte 11: FBBB TTSS (flute_mode, bow_mode, take_any, small_key_mode)
|
||||
flute_mode = {'normal': 0, 'active': 1}
|
||||
|
||||
@@ -1800,7 +1800,7 @@ def imp_locations_factory(world, player):
|
||||
imp_locations = ['Agahnim 1', 'Agahnim 2', 'Attic Cracked Floor', 'Suspicious Maiden']
|
||||
if world.mode[player] == 'standard':
|
||||
imp_locations.append('Zelda Pickup')
|
||||
imp_locations.append('Zelda Dropoff')
|
||||
imp_locations.append('Zelda Drop Off')
|
||||
return imp_locations
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user