diff --git a/BaseClasses.py b/BaseClasses.py index bc562515..bc168cb4 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -53,8 +53,6 @@ class World(object): self._location_cache = {} self.required_locations = [] self.shuffle_bonk_prizes = False - self.light_world_light_cone = False - self.dark_world_light_cone = False self.clock_mode = 'none' self.rupoor_cost = 10 self.aga_randomness = True diff --git a/InitialSram.py b/InitialSram.py index 67c7dc83..b697823e 100644 --- a/InitialSram.py +++ b/InitialSram.py @@ -53,18 +53,17 @@ class InitialSram: def pre_open_pyramid_hole(self): self._or_value(OVERWORLD_DATA+0x5B, 0x20) + def pre_open_tr_bomb_doors(self): + self._or_value(ROOM_DATA+0x47, 0x80) + self._or_value(ROOM_DATA+0x01AB, 0x80) + def set_starting_equipment(self, world: object, player: int): equip = [0] * (0x340 + 0x4F) equip[0x36C] = 0x18 equip[0x36D] = 0x18 equip[0x379] = 0x68 - if world.bombbag[player]: - starting_max_bombs = 0 - else: - starting_max_bombs = 10 - starting_max_arrows = 30 - starting_bomb_cap_upgrades = 0 - starting_arrow_cap_upgrades = 0 + starting_bomb_cap_upgrades = 10 if not world.bombbag[player] else 0 + starting_arrow_cap_upgrades = 30 starting_bombs = 0 starting_arrows = 0 @@ -204,8 +203,8 @@ class InitialSram: equip[0x370] = min(starting_bomb_cap_upgrades, 50) equip[0x371] = min(starting_arrow_cap_upgrades, 70) - equip[0x343] = min(starting_bombs, (equip[0x370] + starting_max_bombs)) - equip[0x377] = min(starting_arrows, (equip[0x371] + starting_max_arrows)) + equip[0x343] = min(starting_bombs, equip[0x370]) + equip[0x377] = min(starting_arrows, equip[0x371]) # Assertion and copy equip to initial_sram_bytes assert equip[:0x340] == [0] * 0x340 diff --git a/Items.py b/Items.py index 579de263..5043c1a3 100644 --- a/Items.py +++ b/Items.py @@ -60,19 +60,19 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'You have\nchosen the\narche 'Progressive Sword': (True, False, 'Sword', 0x5E, 150, 'A better copy\nof your sword\nfor your time', 'the unknown sword', 'sword-wielding kid', 'sword for sale', 'fungus for some slasher', 'sword boy fights again', 'a sword'), 'Progressive Glove': (True, False, None, 0x61, 150, 'A way to lift\nheavier things', 'and the lift upgrade', 'body-building kid', 'some glove for sale', 'fungus for gloves', 'body-building boy lifts again', 'a glove'), 'Silver Arrows': (True, False, None, 0x58, 100, 'Do you fancy\nsilver tipped\narrows?', 'and the ganonsbane', 'ganon-killing kid', 'ganon doom for sale', 'fungus for pork', 'archer boy shines again', 'the silver arrows'), - 'Green Pendant': (True, False, 'Crystal', [0x04, 0x38, 0x62, 0x00, 0x69, 0x01, 0x08], 999, None, None, None, None, None, None, None), - 'Blue Pendant': (True, False, 'Crystal', [0x02, 0x34, 0x60, 0x00, 0x69, 0x02, 0x09], 999, None, None, None, None, None, None, None), - 'Red Pendant': (True, False, 'Crystal', [0x01, 0x32, 0x60, 0x00, 0x69, 0x03, 0x0a], 999, None, None, None, None, None, None, None), + 'Green Pendant': (True, False, 'Crystal', [0x04, 0x38, 0x62, 0x00, 0x69, 0x37, 0x08], 999, None, None, None, None, None, None, None), + 'Blue Pendant': (True, False, 'Crystal', [0x02, 0x34, 0x60, 0x00, 0x69, 0x38, 0x09], 999, None, None, None, None, None, None, None), + 'Red Pendant': (True, False, 'Crystal', [0x01, 0x32, 0x60, 0x00, 0x69, 0x39, 0x0a], 999, None, None, None, None, None, None, None), 'Triforce': (True, False, None, 0x6A, 777, '\n YOU WIN!', 'and the triforce', 'victorious kid', 'victory for sale', 'fungus for the win', 'greedy boy wins game again', 'the Triforce'), 'Power Star': (True, False, None, 0x6B, 100, 'A small victory', 'and the power star', 'star-struck kid', 'star for sale', 'see stars with shroom', 'mario powers up again', 'a Power Star'), 'Triforce Piece': (True, False, None, 0x6C, 100, 'A small victory', 'and the thirdforce', 'triangular kid', 'triangle for sale', 'fungus for triangle', 'wise boy has triangle again', 'a Triforce piece'), - 'Crystal 1': (True, False, 'Crystal', [0x02, 0x34, 0x64, 0x40, 0x7F, 0x06, 0x01], 999, None, None, None, None, None, None, None), - 'Crystal 2': (True, False, 'Crystal', [0x10, 0x34, 0x64, 0x40, 0x79, 0x06, 0x02], 999, None, None, None, None, None, None, None), - 'Crystal 3': (True, False, 'Crystal', [0x40, 0x34, 0x64, 0x40, 0x6C, 0x06, 0x03], 999, None, None, None, None, None, None, None), - 'Crystal 4': (True, False, 'Crystal', [0x20, 0x34, 0x64, 0x40, 0x6D, 0x06, 0x04], 999, None, None, None, None, None, None, None), - 'Crystal 5': (True, False, 'Crystal', [0x04, 0x32, 0x64, 0x40, 0x6E, 0x06, 0x05], 999, None, None, None, None, None, None, None), - 'Crystal 6': (True, False, 'Crystal', [0x01, 0x32, 0x64, 0x40, 0x6F, 0x06, 0x06], 999, None, None, None, None, None, None, None), - 'Crystal 7': (True, False, 'Crystal', [0x08, 0x34, 0x64, 0x40, 0x7C, 0x06, 0x07], 999, None, None, None, None, None, None, None), + 'Crystal 1': (True, False, 'Crystal', [0x02, 0x34, 0x64, 0x40, 0x7F, 0x20, 0x01], 999, None, None, None, None, None, None, None), + 'Crystal 2': (True, False, 'Crystal', [0x10, 0x34, 0x64, 0x40, 0x79, 0x20, 0x02], 999, None, None, None, None, None, None, None), + 'Crystal 3': (True, False, 'Crystal', [0x40, 0x34, 0x64, 0x40, 0x6C, 0x20, 0x03], 999, None, None, None, None, None, None, None), + 'Crystal 4': (True, False, 'Crystal', [0x20, 0x34, 0x64, 0x40, 0x6D, 0x20, 0x04], 999, None, None, None, None, None, None, None), + 'Crystal 5': (True, False, 'Crystal', [0x04, 0x32, 0x64, 0x40, 0x6E, 0x20, 0x05], 999, None, None, None, None, None, None, None), + 'Crystal 6': (True, False, 'Crystal', [0x01, 0x32, 0x64, 0x40, 0x6F, 0x20, 0x06], 999, None, None, None, None, None, None, None), + 'Crystal 7': (True, False, 'Crystal', [0x08, 0x34, 0x64, 0x40, 0x7C, 0x20, 0x07], 999, None, None, None, None, None, None, None), 'Single Arrow': (False, False, None, 0x43, 3, 'A lonely arrow\nsits here.', 'and the arrow', 'stick-collecting kid', 'sewing needle for sale', 'fungus for arrow', 'archer boy sews again', 'an arrow'), 'Arrows (10)': (False, False, None, 0x44, 30, 'This will give\nyou ten shots\nwith your bow!', 'and the arrow pack', 'stick-collecting kid', 'sewing kit for sale', 'fungus for arrows', 'archer boy sews again', 'ten arrows'), 'Arrow Upgrade (+10)': (False, False, None, 0x54, 100, 'Increase arrow\nstorage, low\nlow price', 'and the quiver', 'quiver-enlarging kid', 'arrow boost for sale', 'witch and more skewers', 'upgrade boy sews more again', 'arrow capacity'), diff --git a/Main.py b/Main.py index 21b24eb2..eaba8769 100644 --- a/Main.py +++ b/Main.py @@ -445,8 +445,6 @@ def copy_world(world): ret.treasure_hunt_count = world.treasure_hunt_count.copy() ret.treasure_hunt_icon = world.treasure_hunt_icon.copy() ret.sewer_light_cone = world.sewer_light_cone.copy() - ret.light_world_light_cone = world.light_world_light_cone - ret.dark_world_light_cone = world.dark_world_light_cone ret.seed = world.seed ret.can_access_trock_eyebridge = world.can_access_trock_eyebridge.copy() ret.can_access_trock_front = world.can_access_trock_front.copy() diff --git a/Plando.py b/Plando.py index c32c75cd..4374b706 100755 --- a/Plando.py +++ b/Plando.py @@ -122,12 +122,6 @@ def fill_world(world, plando, text_patches): elif line.startswith('!light_cone_sewers'): _, sewerstr = line.split(':', 1) world.sewer_light_cone = {1: sewerstr.strip().lower() == 'true'} - elif line.startswith('!light_cone_lw'): - _, lwconestr = line.split(':', 1) - world.light_world_light_cone = lwconestr.strip().lower() == 'true' - elif line.startswith('!light_cone_dw'): - _, dwconestr = line.split(':', 1) - world.dark_world_light_cone = dwconestr.strip().lower() == 'true' elif line.startswith('!fix_trock_doors'): _, trdstr = line.split(':', 1) world.fix_trock_doors = {1: trdstr.strip().lower() == 'true'} diff --git a/Rom.py b/Rom.py index 42f0cfa8..f74566f0 100644 --- a/Rom.py +++ b/Rom.py @@ -40,7 +40,7 @@ from source.enemizer.Enemizer import write_enemy_shuffle_settings JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '6d43fb7bd4cf5ec2d10d03cf04772240' +RANDOMIZERBASEHASH = '51a592209991a054bb40b7e7789738c3' class JsonRom(object): @@ -549,6 +549,7 @@ def patch_rom(world, rom, player, team, is_mystery=False): if ((world.collection_rate[player] or world.goal[player] == 'completionist') and world.goal[player] not in ['triforcehunt', 'trinity', 'ganonhunt']): dr_flags |= DROptions.Debug + rom.write_byte(snes_to_pc(0x308039), 1) if world.doorShuffle[player] not in ['vanilla', 'basic'] and world.logic[player] != 'nologic'\ and world.mixed_travel[player] == 'prevent': # PoD Falling Bridge or Hammjump @@ -615,10 +616,10 @@ def patch_rom(world, rom, player, team, is_mystery=False): for name, layout in world.key_layout[player].items(): offset = compass_data[name][4]//2 if world.keyshuffle[player] == 'universal': - rom.write_byte(0x13f030+offset, layout.max_chests + layout.max_drops) + rom.write_byte(0x187010+offset, layout.max_chests + layout.max_drops) else: rom.write_byte(0x13f020+offset, layout.max_chests + layout.max_drops) # not currently used - rom.write_byte(0x13f030+offset, layout.max_chests) + rom.write_byte(0x187010+offset, layout.max_chests) builder = world.dungeon_layouts[player][name] valid_cnt = len(valid_loc_by_dungeon[name]) if valid_cnt > 256: @@ -727,7 +728,7 @@ def patch_rom(world, rom, player, team, is_mystery=False): rom.write_byte(snes_to_pc(0x0DB457), 0x40) rom.write_byte(snes_to_pc(0x28AA56), 0 if world.pottery[player] == 'none' else 1) - write_int16(rom, 0x187010, credits_total) # dynamic credits + write_int16(rom, 0x180196, credits_total) # dynamic credits if credits_total != 216: # collection rate address (hi): cr_address = 0x238055 @@ -737,12 +738,12 @@ def patch_rom(world, rom, player, team, is_mystery=False): last_top, last_bot = credits_digit(credits_total % 10) if credits_total >= 1000: thousands_top, thousands_bot = credits_digit((credits_total // 1000) % 10) - rom.write_byte(cr_pc, 0xa2) # slash + rom.write_byte(cr_pc, 0xDB) # slash rom.write_byte(cr_pc+1, thousands_top) - rom.write_byte(cr_pc+0x1e, 0xc2) # slash + rom.write_byte(cr_pc+0x1e, 0xEE) # slash rom.write_byte(cr_pc+0x1f, thousands_bot) # modify stat config - stat_address = 0x23B969 + stat_address = 0x2297B2 # 0x23B969 - old stat_pc = snes_to_pc(stat_address) rom.write_byte(stat_pc, 0xa9) # change to pos 21 (from b1) rom.write_byte(stat_pc+2, 0xc0) # change to 12 bits (from a0) @@ -803,8 +804,6 @@ def patch_rom(world, rom, player, team, is_mystery=False): # set light cones rom.write_byte(0x180038, 0x01 if world.sewer_light_cone[player] else 0x00) - rom.write_byte(0x180039, 0x01 if world.light_world_light_cone else 0x00) - rom.write_byte(0x18003A, 0x01 if world.dark_world_light_cone else 0x00) GREEN_TWENTY_RUPEES = 0x47 TRIFORCE_PIECE = ItemFactory('Triforce Piece', player).code @@ -1133,8 +1132,6 @@ def patch_rom(world, rom, player, team, is_mystery=False): if world.pseudoboots[player]: rom.write_byte(0x18008E, 0x01) rom.initial_sram.set_starting_equipment(world, player) - rom.write_byte(0x180034, 10 if not world.bombbag[player] else 0) # starting max bombs - rom.write_byte(0x180035, 30) # starting max arrows rom.write_byte(0x18004A, 0x00 if world.mode[player] != 'inverted' else 0x01) # Inverted mode rom.write_byte(0x18005D, 0x00) # Hammer always breaks barrier @@ -1150,20 +1147,21 @@ def patch_rom(world, rom, player, team, is_mystery=False): (0x04 if 'magic' in world.escape_assist[player] else 0x00))) # Escape assist if world.goal[player] in ['pedestal', 'triforcehunt']: - rom.write_byte(0x18003E, 0x01) # make ganon invincible + rom.write_byte(0x1801A8, 0x01) # make ganon invincible elif world.goal[player] in ['dungeons']: - rom.write_byte(0x18003E, 0x02) # make ganon invincible until all dungeons are beat + rom.write_byte(0x1801A8, 0x02) # make ganon invincible until all dungeons are beat elif world.goal[player] in ['crystals', 'trinity']: - rom.write_byte(0x18003E, 0x04) # make ganon invincible until all crystals + rom.write_byte(0x1801A8, 0x04) # make ganon invincible until all crystals elif world.goal[player] in ['ganonhunt']: - rom.write_byte(0x18003E, 0x05) # make ganon invincible until all triforce pieces collected + rom.write_byte(0x1801A8, 0x05) # make ganon invincible until all triforce pieces collected elif world.goal[player] in ['completionist']: - rom.write_byte(0x18003E, 0x0a) # make ganon invincible until everything is collected + rom.write_byte(0x1801A8, 0x0B) # make ganon invincible until everything is collected else: - rom.write_byte(0x18003E, 0x03) # make ganon invincible until all crystals and aga 2 are collected + rom.write_byte(0x1801A8, 0x03) # make ganon invincible until all crystals and aga 2 are collected - rom.write_byte(0x18005E, world.crystals_needed_for_gt[player]) - rom.write_byte(0x18005F, world.crystals_needed_for_ganon[player]) + rom.write_byte(0x18019A, world.crystals_needed_for_gt[player]) + rom.write_byte(0x1801A6, world.crystals_needed_for_ganon[player]) + rom.write_byte(0x1801A2, 0x00) # ped requirement is vanilla, set to 0x1 for special requirements # block HC upstairs doors in rain state in standard mode prevent_rain = world.mode[player] == "standard" and world.shuffle[player] != 'vanilla' @@ -1248,7 +1246,8 @@ def patch_rom(world, rom, player, team, is_mystery=False): # Bitfield - enable free items to show up in menu # - # ----dcba + # ---edcba + # e - Bosses # d - Compass # c - Map # b - Big Key @@ -1258,7 +1257,8 @@ def patch_rom(world, rom, player, team, is_mystery=False): rom.write_byte(0x180045, ((0x01 if world.keyshuffle[player] == 'wild' else 0x00) | (0x02 if world.bigkeyshuffle[player] else 0x00) | (0x04 if world.mapshuffle[player] or enable_menu_map_check else 0x00) - | (0x08 if world.compassshuffle[player] else 0x00))) # free roaming items in menu + | (0x08 if world.compassshuffle[player] else 0x00) # free roaming items in menu + | (0x10 if world.logic[player] == 'nologic' else 0))) # boss icon # Map reveals reveal_bytes = { @@ -1385,8 +1385,7 @@ def patch_rom(world, rom, player, team, is_mystery=False): if world.get_door('TR Eye Bridge SW', player).entranceFlag: world.get_room(0xd5, player).change(0, DoorKind.CaveEntrance) # do this unconditionally - gets overwritten by RoomData in doorShufflemodes - rom.write_byte(0xFED31, 0x0E) # preopen bombable exit - rom.write_byte(0xFEE41, 0x0E) # preopen bombable exit + rom.initial_sram.pre_open_tr_bomb_doors() # preopen bombable exits if world.boss_shuffle[player] != 'none' or world.doorShuffle[player] != 'vanilla': rom.write_byte(snes_to_pc(0x30835A), 1) # fix Prize On The Eyes @@ -1579,17 +1578,7 @@ def apply_rom_settings(rom, beep, color, quickswap, fastmenu, disable_music, spr # set heart color if color == 'random': color = random.choice(['red', 'blue', 'green', 'yellow']) - rom.write_byte(0x6FA1E, {'red': 0x24, 'blue': 0x2C, 'green': 0x3C, 'yellow': 0x28}[color]) - rom.write_byte(0x6FA20, {'red': 0x24, 'blue': 0x2C, 'green': 0x3C, 'yellow': 0x28}[color]) - rom.write_byte(0x6FA22, {'red': 0x24, 'blue': 0x2C, 'green': 0x3C, 'yellow': 0x28}[color]) - rom.write_byte(0x6FA24, {'red': 0x24, 'blue': 0x2C, 'green': 0x3C, 'yellow': 0x28}[color]) - rom.write_byte(0x6FA26, {'red': 0x24, 'blue': 0x2C, 'green': 0x3C, 'yellow': 0x28}[color]) - rom.write_byte(0x6FA28, {'red': 0x24, 'blue': 0x2C, 'green': 0x3C, 'yellow': 0x28}[color]) - rom.write_byte(0x6FA2A, {'red': 0x24, 'blue': 0x2C, 'green': 0x3C, 'yellow': 0x28}[color]) - rom.write_byte(0x6FA2C, {'red': 0x24, 'blue': 0x2C, 'green': 0x3C, 'yellow': 0x28}[color]) - rom.write_byte(0x6FA2E, {'red': 0x24, 'blue': 0x2C, 'green': 0x3C, 'yellow': 0x28}[color]) - rom.write_byte(0x6FA30, {'red': 0x24, 'blue': 0x2C, 'green': 0x3C, 'yellow': 0x28}[color]) - rom.write_byte(0x65561, {'red': 0x05, 'blue': 0x0D, 'green': 0x19, 'yellow': 0x09}[color]) + rom.write_byte(0x187020, {'red': 0, 'blue': 1, 'green': 2, 'yellow': 3}[color]) # write link sprite if required if sprite is not None: @@ -1838,6 +1827,16 @@ def write_string_to_rom(rom, target, string): def write_strings(rom, world, player, team): tt = TextTable() tt.removeUnwantedText() + if world.shuffle[player] != 'vanilla': + tt['houlihan_room'] = CompressedTextMapper.convert( + " Crosskeys\n" + " Tournament\n" + " Winners\n{HARP}\n" + " ~~~2022~~~\n Schulzer\n\n" + " ~~~2021~~~\n Goomba\n\n" + " ~~~2020~~~\n Linlinlin\n\n" + " ~~~2019~~~\n Kohrek\n" + ) # Let's keep this guy's text accurate to the shuffle setting. if world.shuffle[player] in ['vanilla', 'dungeonsfull', 'dungeonssimple']: diff --git a/Rules.py b/Rules.py index 70b58273..3fdaed07 100644 --- a/Rules.py +++ b/Rules.py @@ -1065,8 +1065,7 @@ def add_conditional_lamps(world, player): spot = world.get_location(spot, player) else: spot = world.get_entrance(spot, player) - if (not world.dark_world_light_cone and check_is_dark_world(world.get_region(region, player))) or (not world.light_world_light_cone and not check_is_dark_world(world.get_region(region, player))): - add_lamp_requirement(spot, player) + add_lamp_requirement(spot, player) dark_rooms = { 'TR Dark Ride': {'sewer': False, 'entrances': ['TR Dark Ride Up Stairs', 'TR Dark Ride SW', 'TR Dark Ride Path'], 'locations': []}, diff --git a/Text.py b/Text.py index 796723d3..ca068926 100644 --- a/Text.py +++ b/Text.py @@ -478,7 +478,7 @@ class Credits(object): ], 'pedestal': [ SceneSmallCreditLine(19, 'and the master sword'), - SceneSmallAltCreditLine(21, 'sleeps again...'), + SceneSmallAltCreditLine(21, 'sleeps again···'), SceneLargeCreditLine(23, 'Forever!'), ], } @@ -826,6 +826,7 @@ class CharTextMapper(object): class RawMBTextMapper(CharTextMapper): char_map = {' ': 0xFF, + '≥': 0x99, # Cursor '『': 0xC4, '』': 0xC5, '?': 0xC6, @@ -834,22 +835,15 @@ class RawMBTextMapper(CharTextMapper): '-': 0xC9, "🡄": 0xCA, "🡆": 0xCB, - '…': 0xCC, + '…': 0x9F, '.': 0xCD, '~': 0xCE, '~': 0xCE, + ':': 0xEA, '@': [0x6A], # Links name (only works if compressed) '>': [0x00, 0xD2, 0x00, 0xD3], # Link's face - "'": 0xD8, + "'": 0x9D, '’': 0xD8, - '%': 0xDD, # Hylian Bird - '^': 0xDE, # Hylian Ankh - '=': 0xDF, # Hylian Wavy Lines - '↑': 0xE0, - '↓': 0xE1, - '→': 0xE2, - '←': 0xE3, - '≥': 0xE4, # Cursor '¼': [0x00, 0xE5, 0x00, 0xE7], # ¼ heart '½': [0x00, 0xE6, 0x00, 0xE7], # ½ heart '¾': [0x00, 0xE8, 0x00, 0xE9], # ¾ heart @@ -1034,22 +1028,29 @@ class RawMBTextMapper(CharTextMapper): "司": 0x0D, "書": 0x0E, "戻": 0x0F, - "様": 0x10, - "子": 0x11, - "湖": 0x12, - "達": 0x13, - "彼": 0x14, - "女": 0x15, - "言": 0x16, - "祭": 0x17, - "早": 0x18, - "雨": 0x19, - "剣": 0x1A, - "盾": 0x1B, - "解": 0x1C, - "抜": 0x1D, - "者": 0x1E, - "味": 0x1F, + "%": 0x10, # Hylian Bird + "^": 0x11, # Hylian Ankh + "=": 0x12, # Hylian Wavy Lines + "↑": 0x13, + "↓": 0x14, + "→": 0x15, + "←": 0x16, + #"様": 0x10, + #"子": 0x11, + #"湖": 0x12, + #"達": 0x13, + #"彼": 0x14, + #"女": 0x15, + #"言": 0x16, + #"祭": 0x17, + #"早": 0x18, + #"雨": 0x19, + #"剣": 0x1A, + #"盾": 0x1B, + #"解": 0x1C, + #"抜": 0x1D, + #"者": 0x1E, + #"味": 0x1F, "方": 0x20, "無": 0x21, "事": 0x22, @@ -1275,7 +1276,7 @@ class RawMBTextMapper(CharTextMapper): "月": 0xFE, "姫": 0xFF} alpha_offset = 0x49 - alpha_lower_offset = -0x31 + alpha_lower_offset = 0x6F number_offset = 0x70 @classmethod @@ -1298,7 +1299,7 @@ class RawMBTextMapper(CharTextMapper): class GoldCreditMapper(CharTextMapper): char_map = {' ': 0x9F, - ',': 0x34, + ',': 0x34, # apostrophe/comma top "'": 0x35, '-': 0x36, '.': 0x37,} @@ -1319,21 +1320,23 @@ class RedCreditMapper(CharTextMapper): class LargeCreditTopMapper(CharTextMapper): char_map = {' ': 0x9F, - "'": 0x77, - '!': 0x78, - '.': 0xA0, - '#': 0xA1, - '/': 0xA2, - ':': 0xA3, - ',': 0xA4, - '?': 0xA5, - '=': 0xA6, - '"': 0xA7, - '-': 0xA8, - '·': 0xA9, - '•': 0xA9, - '◢': 0xAA, - '◣': 0xAB,} + "'": 0xD9, + '"': 0xDA, + '/': 0xDB, + '.': 0xDC, + ':': 0xDD, + '_': 0xDE, + '·': 0xDF, + '•': 0xDF, + '…': 0xE0, + '#': 0xE1, + '@': 0xE2, + '>': 0xE3, + '?': 0xE4, + '!': 0xE5, + '~': 0xE6, + ',': 0xE7, + '-': 0xE8,} alpha_offset = -0x04 alpha_lower_offset = -0x04 number_offset = 0x23 @@ -1341,21 +1344,23 @@ class LargeCreditTopMapper(CharTextMapper): class LargeCreditBottomMapper(CharTextMapper): char_map = {' ': 0x9F, - "'": 0x9D, - '!': 0x9E, - '.': 0xC0, - '#': 0xC1, - '/': 0xC2, - ':': 0xC3, - ',': 0xC4, - '?': 0xC5, - '=': 0xC6, - '"': 0xC7, - '-': 0xC8, - '·': 0xC9, - '•': 0xC9, - '◢': 0xCA, - '◣': 0xCB,} + "'": 0xEC, + '"': 0xED, + '/': 0xEE, + '.': 0xEF, + ':': 0xF0, + '_': 0xF1, + '·': 0xF2, + '•': 0xF2, + '…': 0xF3, + '#': 0xF4, + '@': 0xF5, + '>': 0xF6, + '?': 0xF7, + '!': 0xF8, + '~': 0xF9, + ',': 0xFA, + '-': 0xFB,} alpha_offset = 0x22 alpha_lower_offset = 0x22 number_offset = 0x49 @@ -1568,16 +1573,16 @@ class TextTable(object): def setDefaultText(self): text = self._text - text['set_cursor'] = bytearray([0xFB, 0xFC, 0x00, 0xF9, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xE4, 0xFE, 0x68]) - text['set_cursor2'] = bytearray([0xFB, 0xFC, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xE4, 0xFE, 0x68]) + text['set_cursor'] = bytearray([0xFB, 0xFC, 0x00, 0xF9, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0x99, 0xFE, 0x68]) + text['set_cursor2'] = bytearray([0xFB, 0xFC, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0x99, 0xFE, 0x68]) text['game_over_menu'] = CompressedTextMapper.convert("{SPEED0}\nSave-Continue\nSave-Quit\nContinue", False) text['var_test'] = CompressedTextMapper.convert("0= ᚋ, 1= ᚌ\n2= ᚍ, 3= ᚎ", False) text['follower_no_enter'] = CompressedTextMapper.convert("Can't you take me some place nice.") - text['choice_1_3'] = bytearray([0xFB, 0xFC, 0x00, 0xF7, 0xE4, 0xF8, 0xFF, 0xF9, 0xFF, 0xFE, 0x71]) - text['choice_2_3'] = bytearray([0xFB, 0xFC, 0x00, 0xF7, 0xFF, 0xF8, 0xE4, 0xF9, 0xFF, 0xFE, 0x71]) - text['choice_3_3'] = bytearray([0xFB, 0xFC, 0x00, 0xF7, 0xFF, 0xF8, 0xFF, 0xF9, 0xE4, 0xFE, 0x71]) - text['choice_1_2'] = bytearray([0xFB, 0xFC, 0x00, 0xF7, 0xE4, 0xF8, 0xFF, 0xFE, 0x72]) - text['choice_2_2'] = bytearray([0xFB, 0xFC, 0x00, 0xF7, 0xFF, 0xF8, 0xE4, 0xFE, 0x72]) + text['choice_1_3'] = bytearray([0xFB, 0xFC, 0x00, 0xF7, 0x99, 0xF8, 0xFF, 0xF9, 0xFF, 0xFE, 0x71]) + text['choice_2_3'] = bytearray([0xFB, 0xFC, 0x00, 0xF7, 0xFF, 0xF8, 0x99, 0xF9, 0xFF, 0xFE, 0x71]) + text['choice_3_3'] = bytearray([0xFB, 0xFC, 0x00, 0xF7, 0xFF, 0xF8, 0xFF, 0xF9, 0x99, 0xFE, 0x71]) + text['choice_1_2'] = bytearray([0xFB, 0xFC, 0x00, 0xF7, 0x99, 0xF8, 0xFF, 0xFE, 0x72]) + text['choice_2_2'] = bytearray([0xFB, 0xFC, 0x00, 0xF7, 0xFF, 0xF8, 0x99, 0xFE, 0x72]) text['uncle_leaving_text'] = CompressedTextMapper.convert("I'm just going out for a pack of smokes.") text['uncle_dying_sewer'] = CompressedTextMapper.convert("I've fallen and I can't get up, take this.") text['tutorial_guard_1'] = CompressedTextMapper.convert("Only adults should travel at night.") @@ -1640,7 +1645,7 @@ class TextTable(object): text['sign_outside_magic_shop'] = CompressedTextMapper.convert("Welcome to the Magic Shoppe") # 40 text['sign_death_mountain_cave_back'] = CompressedTextMapper.convert("Cave away from sky cabbages") - text['sign_east_of_links_house'] = CompressedTextMapper.convert("↓ Lake Hylia\n\n Also, a shop") + text['sign_east_of_links_house'] = CompressedTextMapper.convert("↓Lake Hylia\n\n Also, a shop") text['sign_south_of_lumberjacks'] = CompressedTextMapper.convert("← Kakariko\n Village") text['sign_east_of_desert'] = CompressedTextMapper.convert("← Desert\n\n It's hot.") text['sign_east_of_sanctuary'] = CompressedTextMapper.convert("↑→ Potions!\n\nWish waterfall") @@ -1772,7 +1777,10 @@ class TextTable(object): text['telepathic_tile_misery_mire'] = CompressedTextMapper.convert("{NOBORDER}\nLighting 4 torches will open your way forward!") text['hylian_text_2'] = CompressedTextMapper.convert("%%^= %==%\n ^ =%^=\n==%= ^^%^") text['desert_entry_translated'] = CompressedTextMapper.convert("Kneel before this stone, and magic will move around you.") - text['telepathic_tile_under_ganon'] = CompressedTextMapper.convert("Doors Async League winners\n{HARP}\n ~~~2022~~~\nAndy\n\n ~~~2021~~~\nprdwong") + text['telepathic_tile_under_ganon'] = CompressedTextMapper.convert("Doors Async League winners\n{HARP}\n" + " ~~~2023~~~\nEriror\n\n" + " ~~~2022~~~\nAndy\n\n" + " ~~~2021~~~\nprdwong") text['telepathic_tile_palace_of_darkness'] = CompressedTextMapper.convert("{NOBORDER}\nThis is a funny looking Enemizer") # C0 text['telepathic_tile_desert_bonk_torch_room'] = CompressedTextMapper.convert("{NOBORDER}\nThings can be knocked down, if you fancy yourself a dashing dude.") @@ -1782,7 +1790,13 @@ class TextTable(object): text['telepathic_tile_ice_entrance'] = CompressedTextMapper.convert("{NOBORDER}\nYou can use Fire Rod or Bombos to pass.") text['telepathic_tile_ice_stalfos_knights_room'] = CompressedTextMapper.convert("{NOBORDER}\nKnock 'em down and then bomb them dead.") text['telepathic_tile_tower_of_hera_entrance'] = CompressedTextMapper.convert("{NOBORDER}\nThis is a bad place, with a guy who will make you fall…\n\n\na lot.") - text['houlihan_room'] = CompressedTextMapper.convert("Randomizer tournament winners\n{HARP}\n ~~~2021~~~\nDaaanty\n\n ~~~2019~~~\nJet082\n\n ~~~2018~~~\nAndy\n\n ~~~2017~~~\nA: ajneb174\nS: ajneb174") + text['houlihan_room'] = CompressedTextMapper.convert("Randomizer tournament winners\n{HARP}\n" + " ~~~2023~~~\nnGanonsGoneWild\n\n" + " ~~~2022~~~\nObscure\n\n" + " ~~~2021~~~\nDaaanty\n\n" + " ~~~2019~~~\nJet082\n\n" + " ~~~2018~~~\nAndy\n\n" + " ~~~2017~~~\nA: ajneb174\nS: ajneb174") text['caught_a_bee'] = CompressedTextMapper.convert("Caught a Bee\n ≥ Keep\n Release\n{CHOICE}") text['caught_a_fairy'] = CompressedTextMapper.convert("Caught Fairy!\n ≥ Keep\n Release\n{CHOICE}") text['no_empty_bottles'] = CompressedTextMapper.convert("Whoa, bucko!\nNo empty bottles.") @@ -2010,7 +2024,10 @@ class TextTable(object): text['ganon_fall_in_alt'] = CompressedTextMapper.convert("You think you are ready to face me?\n\nI will not die unless you complete your goals. Dingus!") text['ganon_phase_3_alt'] = CompressedTextMapper.convert("Got wax in your ears? I cannot die!") # 190 - text['sign_east_death_mountain_bridge'] = CompressedTextMapper.convert("Glitched\ntournament\nwinners\n{HARP}\n~~~HMG 2021~~~\nKrithel\n\n~~~OWG 2019~~~\nGlan\n\n~~~OWG 2018~~~\nChristosOwen\nthe numpty") + text['sign_east_death_mountain_bridge'] = CompressedTextMapper.convert("Glitched\ntournament\nwinners\n{HARP}\n" + "~~~HMG 2021~~~\nKrithel\n\n" + "~~~OWG 2019~~~\nGlan\n\n" + "~~~OWG 2018~~~\nChristosOwen\nthe numpty") text['fish_money'] = CompressedTextMapper.convert("It's a secret to everyone.") text['sign_ganons_tower'] = CompressedTextMapper.convert("You need all 7 crystals to enter.") text['sign_ganon'] = CompressedTextMapper.convert("You need all 7 crystals to beat Ganon.") diff --git a/data/base2current.bps b/data/base2current.bps index a51a2d26..3dbf4fe0 100644 Binary files a/data/base2current.bps and b/data/base2current.bps differ