diff --git a/BaseClasses.py b/BaseClasses.py index f922e11a..725f8d4a 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -131,6 +131,7 @@ class World(object): set_player_attr('treasure_hunt_total', 0) set_player_attr('potshuffle', False) set_player_attr('pot_contents', None) + set_player_attr('fakeboots', False) set_player_attr('shopsanity', False) set_player_attr('keydropshuffle', False) diff --git a/CLI.py b/CLI.py index 222f8a90..9b6e42fb 100644 --- a/CLI.py +++ b/CLI.py @@ -97,7 +97,7 @@ def parse_cli(argv, no_defaults=False): 'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'openpyramid', 'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory', 'triforce_pool_min', 'triforce_pool_max', 'triforce_goal_min', 'triforce_goal_max', - 'triforce_min_difference', 'triforce_goal', 'triforce_pool', 'shufflelinks', + 'triforce_min_difference', 'triforce_goal', 'triforce_pool', 'shufflelinks', 'fakeboots', 'retro', 'accessibility', 'hints', 'beemizer', 'experimental', 'dungeon_counters', 'shufflebosses', 'shuffleenemies', 'enemy_health', 'enemy_damage', 'shufflepots', 'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor', 'heartbeep', @@ -144,6 +144,7 @@ def parse_settings(): "shuffleganon": True, "shuffle": "vanilla", "shufflelinks": False, + "fakeboots": False, "shufflepots": False, "shuffleenemies": "none", diff --git a/Main.py b/Main.py index 339c2472..da6fadbd 100644 --- a/Main.py +++ b/Main.py @@ -90,6 +90,7 @@ def main(args, seed=None, fish=None): world.treasure_hunt_count = args.triforce_goal.copy() world.treasure_hunt_total = args.triforce_pool.copy() world.shufflelinks = args.shufflelinks.copy() + world.fakeboots = args.fakeboots.copy() world.rom_seeds = {player: random.randint(0, 999999999) for player in range(1, world.players + 1)} diff --git a/Mystery.py b/Mystery.py index bd5581d6..0fd85108 100644 --- a/Mystery.py +++ b/Mystery.py @@ -143,6 +143,7 @@ def roll_settings(weights): ret.dungeon_counters = 'pickup' if ret.door_shuffle != 'vanilla' or ret.compassshuffle == 'on' else 'off' ret.shufflelinks = get_choice('shufflelinks') == 'on' + ret.fakeboots = get_choice('fakeboots') == 'on' ret.shopsanity = get_choice('shopsanity') == 'on' ret.keydropshuffle = get_choice('keydropshuffle') == 'on' ret.mixed_travel = get_choice('mixed_travel') if 'mixed_travel' in weights else 'prevent' diff --git a/RELEASENOTES.md b/RELEASENOTES.md index b6258011..dd2ce1fc 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -24,6 +24,18 @@ Thanks to qadan, cheuer, & compiling * Fixed an issue with the credit stats specific to DR (e.g. collection rate total) * More helpful error message when bps is missing? * Minor generation issues involving enemizer and the link sprite + * Baserom updates (from Bonta, kan, qwertymodo, ardnaxelark) + * Boss icon on dungeon map (if you have a compass) + * Progressive bow sprite replacement + * Quickswap - consecutive special swaps + * Bonk Counter + * One mind + * MSU fix + * Chest turn tracking (not yet in credits) + * Damaged and magic stats in credits (gt bk removed) + * Fix for infinite bombs + * Fake boots option + * Always allowed medallions for swordless (no option yet) * 0.4.0.7 * Reduce flashing option added * Sprite author credit added diff --git a/Rom.py b/Rom.py index 7611aaa8..72be78d0 100644 --- a/Rom.py +++ b/Rom.py @@ -18,7 +18,6 @@ except ImportError: from BaseClasses import CollectionState, ShopType, Region, Location, Door, DoorType, RegionType, PotItem from DoorShuffle import compass_data, DROptions, boss_indicator from Dungeons import dungeon_music_addresses -from KeyDoorShuffle import count_locations_exclude_logic from Regions import location_table, shop_to_location_table, retro_shops from RoomData import DoorKind from Text import MultiByteTextMapper, CompressedTextMapper, text_addresses, Credits, TextTable @@ -31,7 +30,7 @@ from EntranceShuffle import door_addresses, exit_ids JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '712324ad3ca7bff751d9f62812a2c3b6' +RANDOMIZERBASEHASH = '736978dd2b3a2bb109ac80ed7c048e67' class JsonRom(object): @@ -809,7 +808,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): write_int16(rom, 0x187010, credits_total) # dynamic credits if credits_total != 216: # collection rate address: - cr_address = 0x2391FA + cr_address = 0x2391F2 cr_pc = cr_address - 0x120000 # convert to pc mid_top, mid_bot = credits_digit((credits_total // 10) % 10) last_top, last_bot = credits_digit(credits_total % 10) @@ -820,25 +819,6 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_byte(cr_pc+0x3a, mid_bot) rom.write_byte(cr_pc+0x3b, last_bot) - if world.keydropshuffle[player] or world.doorShuffle[player] != 'vanilla': - gt = world.dungeon_layouts[player]['Ganons Tower'] - gt_logic = world.key_logic[player]['Ganons Tower'] - total = 0 - for region in gt.master_sector.regions: - total += count_locations_exclude_logic(region.locations, gt_logic) - # rom.write_byte(0x187012, total) # dynamic credits - # gt big key address: - gtbk_address = 0x23911C - gtbk_pc = gtbk_address - 0x120000 # convert to pc - mid_top, mid_bot = credits_digit(total // 10) - last_top, last_bot = credits_digit(total % 10) - # top half - rom.write_byte(gtbk_pc+0x1c, mid_top) - rom.write_byte(gtbk_pc+0x1d, last_top) - # bottom half - rom.write_byte(gtbk_pc+0x3a, mid_bot) - rom.write_byte(gtbk_pc+0x3b, last_bot) - # patch medallion requirements if world.required_medallions[player][0] == 'Bombos': rom.write_byte(0x180022, 0x00) # requirement @@ -1182,6 +1162,9 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_byte(0x18017E, 0x01) # Fairy fountains only trade in bottles # Starting equipment + if world.fakeboots[player]: + rom.write_byte(0x18008E, 0x01) + equip = [0] * (0x340 + 0x4F) equip[0x36C] = 0x18 equip[0x36D] = 0x18 diff --git a/data/base2current.bps b/data/base2current.bps index 94a1eedd..22b25506 100644 Binary files a/data/base2current.bps and b/data/base2current.bps differ diff --git a/resources/app/cli/args.json b/resources/app/cli/args.json index 00d1c9db..584593b4 100644 --- a/resources/app/cli/args.json +++ b/resources/app/cli/args.json @@ -310,6 +310,10 @@ "action": "store_true", "type": "bool" }, + "fakeboots": { + "action": "store_true", + "type": "bool" + }, "calc_playthrough": { "action": "store_false", "type": "bool" diff --git a/resources/app/cli/lang/en.json b/resources/app/cli/lang/en.json index fa7c355e..efc1f5ad 100644 --- a/resources/app/cli/lang/en.json +++ b/resources/app/cli/lang/en.json @@ -262,6 +262,7 @@ "Keys are universal, shooting arrows costs rupees,", "and a few other little things make this more like Zelda-1. (default: %(default)s)" ], + "fakeboots": [ " Players starts with fake boots that allow dashing but no item checks (default: %(default)s"], "startinventory": [ "Specifies a list of items that will be in your starting inventory (separated by commas). (default: %(default)s)" ], "usestartinventory": [ "Toggle usage of Starting Inventory." ], "custom": [ "Not supported." ], diff --git a/resources/app/gui/lang/en.json b/resources/app/gui/lang/en.json index 850bb788..f4b8ca12 100644 --- a/resources/app/gui/lang/en.json +++ b/resources/app/gui/lang/en.json @@ -189,6 +189,7 @@ "randomizer.item.hints": "Include Helpful Hints", "randomizer.item.retro": "Retro mode (universal keys)", + "randomizer.item.fakeboots": "Start with Fake Boots", "randomizer.item.worldstate": "World State", "randomizer.item.worldstate.standard": "Standard", diff --git a/resources/app/gui/randomize/item/widgets.json b/resources/app/gui/randomize/item/widgets.json index 1871dcaf..1f5eb19a 100644 --- a/resources/app/gui/randomize/item/widgets.json +++ b/resources/app/gui/randomize/item/widgets.json @@ -4,7 +4,8 @@ "shopsanity": { "type": "checkbox" }, "hints": { "type": "checkbox" - } + }, + "fakeboots": { "type": "checkbox" } }, "leftItemFrame": { "worldstate": { diff --git a/source/classes/constants.py b/source/classes/constants.py index 3e59af3c..14c70f79 100644 --- a/source/classes/constants.py +++ b/source/classes/constants.py @@ -58,6 +58,7 @@ SETTINGSTOPROCESS = { "hints": "hints", "retro": "retro", "shopsanity": "shopsanity", + "fakeboots": "fakeboots", "worldstate": "mode", "logiclevel": "logic", "goal": "goal", diff --git a/source/gui/randomize/item.py b/source/gui/randomize/item.py index b01892ab..81c957ce 100644 --- a/source/gui/randomize/item.py +++ b/source/gui/randomize/item.py @@ -1,4 +1,4 @@ -from tkinter import ttk, Frame, E, W, LEFT, RIGHT +from tkinter import ttk, Frame, E, W, LEFT, RIGHT, Label import source.gui.widgets as widgets import json import os @@ -17,6 +17,9 @@ def item_page(parent): self.frames["checkboxes"] = Frame(self) self.frames["checkboxes"].pack(anchor=W) + various_options = Label(self.frames["checkboxes"], text="") + various_options.pack(side=LEFT) + self.frames["leftItemFrame"] = Frame(self) self.frames["rightItemFrame"] = Frame(self) self.frames["leftItemFrame"].pack(side=LEFT) @@ -34,7 +37,7 @@ def item_page(parent): self.widgets[key] = dictWidgets[key] packAttrs = {"anchor":E} if self.widgets[key].type == "checkbox": - packAttrs["anchor"] = W + packAttrs["side"] = LEFT self.widgets[key].pack(packAttrs) return self