diff --git a/Bosses.py b/Bosses.py index ebf8b4dd..253717bd 100644 --- a/Bosses.py +++ b/Bosses.py @@ -1,5 +1,5 @@ import logging -import random +import RaceRandom as random from BaseClasses import Boss from Fill import FillError diff --git a/DoorShuffle.py b/DoorShuffle.py index a2d7a9e6..8ad99965 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -1,4 +1,4 @@ -import random +import RaceRandom as random from collections import defaultdict, deque import logging import operator as op @@ -1843,7 +1843,7 @@ def find_accessible_entrances(world, player, builder): elif world.mode[player] != 'inverted': start_regions = ['Links House', 'Sanctuary'] else: - start_regions = ['Links House', 'Dark Sanctuary Hint'] + start_regions = ['Links House', 'Dark Sanctuary Hint', 'Hyrule Castle Ledge'] regs = convert_regions(start_regions, world, player) visited_regions = set() visited_entrances = [] diff --git a/DungeonGenerator.py b/DungeonGenerator.py index c8599748..1c49cba0 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -1,4 +1,4 @@ -import random +import RaceRandom as random import collections import itertools from collections import defaultdict, deque diff --git a/DungeonRandomizer.py b/DungeonRandomizer.py index b1c02c81..d24e81d6 100755 --- a/DungeonRandomizer.py +++ b/DungeonRandomizer.py @@ -3,7 +3,7 @@ import argparse import copy import os import logging -import random +import RaceRandom as random import textwrap import shlex import sys diff --git a/Dungeons.py b/Dungeons.py index d5297400..596da920 100644 --- a/Dungeons.py +++ b/Dungeons.py @@ -1,4 +1,4 @@ -import random +import RaceRandom as random from BaseClasses import Dungeon from Bosses import BossFactory diff --git a/EntranceShuffle.py b/EntranceShuffle.py index d4449cd8..0cccb347 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -1,4 +1,4 @@ -import random +import RaceRandom as random # ToDo: With shuffle_ganon option, prevent gtower from linking to an exit only location through a 2 entrance cave. from collections import defaultdict @@ -493,7 +493,7 @@ def link_entrances(world, player): if invFlag: # shuffle aga door first. if it's on hc ledge, then one other hc ledge door has to be must_exit all_entrances_aga = lw_entrances + dw_entrances - aga_doors = [i for i in all_entrances_aga] + aga_doors = [i for i in all_entrances_aga if world.shufflelinks[player]] random.shuffle(aga_doors) aga_door = aga_doors.pop() @@ -687,7 +687,8 @@ def link_entrances(world, player): if invFlag: # shuffle aga door. if it's on hc ledge, then one other hc ledge door has to be must_exit - aga_door = random.choice(entrances) + aga_choices = [x for x in entrances if world.shufflelinks[player]] + aga_door = random.choice(aga_choices) if aga_door in hc_ledge_entrances: hc_ledge_entrances.remove(aga_door) diff --git a/Fill.py b/Fill.py index 5e1176a3..de59a2b5 100644 --- a/Fill.py +++ b/Fill.py @@ -1,4 +1,4 @@ -import random +import RaceRandom as random import logging from BaseClasses import CollectionState diff --git a/ItemList.py b/ItemList.py index e37162d6..ac2d5995 100644 --- a/ItemList.py +++ b/ItemList.py @@ -1,7 +1,7 @@ from collections import namedtuple import logging import math -import random +import RaceRandom as random from BaseClasses import Region, RegionType, Shop, ShopType, Location, CollectionState from Bosses import place_bosses diff --git a/Main.py b/Main.py index e92bf010..462bd1e5 100644 --- a/Main.py +++ b/Main.py @@ -4,7 +4,8 @@ from itertools import zip_longest import json import logging import os -import random +import RaceRandom as random +import string import time import zlib @@ -28,7 +29,7 @@ from Fill import sell_potions, sell_keys, balance_multiworld_progression, balanc from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops from Utils import output_path, parse_player_names -__version__ = '0.4.0.11u' +__version__ = '0.4.0.12u' class EnemizerError(RuntimeError): @@ -42,8 +43,8 @@ def main(args, seed=None, fish=None): start = time.perf_counter() - # if args.securerandom: - # random.use_secure() + if args.securerandom: + random.use_secure() # initialize the world if args.code: @@ -62,7 +63,7 @@ def main(args, seed=None, fish=None): random.seed(world.seed) if args.securerandom: - world.seed = None + world.seed = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(9)) world.remote_items = args.remote_items.copy() world.mapshuffle = args.mapshuffle.copy() @@ -341,7 +342,7 @@ def main(args, seed=None, fish=None): logger.info(world.fish.translate("cli","cli","made.playthrough") % (YES if (args.calc_playthrough) else NO)) logger.info(world.fish.translate("cli","cli","made.spoiler") % (YES if (not args.jsonout and args.create_spoiler) else NO)) logger.info(world.fish.translate("cli","cli","used.enemizer") % (YES if enemized else NO)) - logger.info(world.fish.translate("cli","cli","seed") + ": %d", world.seed) + logger.info(world.fish.translate("cli","cli","seed") + ": %s", world.seed) logger.info(world.fish.translate("cli","cli","total.time"), time.perf_counter() - start) # print_wiki_doors_by_room(dungeon_regions,world,1) diff --git a/Mystery.py b/Mystery.py index 575ab90d..a3b0b509 100644 --- a/Mystery.py +++ b/Mystery.py @@ -1,6 +1,6 @@ import argparse import logging -import random +import RaceRandom as random import urllib.request import urllib.parse import yaml diff --git a/Plando.py b/Plando.py index 254a92b6..2a4b911d 100755 --- a/Plando.py +++ b/Plando.py @@ -3,7 +3,7 @@ import argparse import hashlib import logging import os -import random +import RaceRandom as random import time import sys diff --git a/PotShuffle.py b/PotShuffle.py index e8e6d3ce..d62f52eb 100644 --- a/PotShuffle.py +++ b/PotShuffle.py @@ -275,7 +275,7 @@ vanilla_pots = { def shuffle_pots(world, player): - import random + import RaceRandom as random new_pot_contents = {} diff --git a/RELEASENOTES.md b/RELEASENOTES.md index cafdb92f..0ccceb80 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -22,6 +22,11 @@ For accessibility, you now get a C or P indicator to the left of the magic bar o # Bug Fixes and Notes. +* 0.4.0.12 + * ER Inverted fix for HC Ledge, and Aga Tower choosing Links House incorrectly + * Credits again - hopefully for good + * Incorporated music fixes for now (may revisit later) + * Secure random re-incorporated * 0.4.0.11 * Some minor base rom fixes * Improved distribution of bombable/dashable doors diff --git a/Rom.py b/Rom.py index ae6b4114..bf4275ea 100644 --- a/Rom.py +++ b/Rom.py @@ -5,7 +5,7 @@ import json import hashlib import logging import os -import random +import RaceRandom as random import struct import sys import subprocess @@ -31,7 +31,7 @@ from OverworldShuffle import default_flute_connections, flute_data JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '487a04cf965bb89636f9b1621dd606d1' +RANDOMIZERBASEHASH = 'abcc9ca7e5ec6eac56a70e8b248a5883' class JsonRom(object): @@ -893,17 +893,17 @@ 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 = 0x2391C2 + # collection rate address (hi): + cr_address = 0x238057 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) # top half - rom.write_byte(cr_pc+0x1c, mid_top) - rom.write_byte(cr_pc+0x1d, last_top) + rom.write_byte(cr_pc+0x1, mid_top) + rom.write_byte(cr_pc+0x2, last_top) # bottom half - rom.write_byte(cr_pc+0x3a, mid_bot) - rom.write_byte(cr_pc+0x3b, last_bot) + rom.write_byte(cr_pc+0x1f, mid_bot) + rom.write_byte(cr_pc+0x20, last_bot) # patch medallion requirements if world.required_medallions[player][0] == 'Bombos': @@ -1615,8 +1615,9 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): # set rom name # 21 bytes from Main import __version__ + seedstring = f'{world.seed:09}' if isinstance(world.seed, int) else world.seed # todo: change to DR when Enemizer is okay with DR - rom.name = bytearray(f'ER{__version__.split("-")[0].replace(".","")[0:3]}_{team+1}_{player}_{world.seed:09}\0', 'utf8')[:21] + rom.name = bytearray(f'ER{__version__.split("-")[0].replace(".","")[0:3]}_{team+1}_{player}_{seedstring}\0', 'utf8')[:21] rom.name.extend([0] * (21 - len(rom.name))) rom.write_bytes(0x7FC0, rom.name) diff --git a/asm/drhooks.asm b/asm/drhooks.asm index 2824771e..86ae1ff1 100644 --- a/asm/drhooks.asm +++ b/asm/drhooks.asm @@ -179,6 +179,17 @@ JSL BlindsAtticHint : NOP #2 org $1cfd69 Main_ShowTextMessage: +; Conditionally disable UW music changes in Door Rando +org $028ADB ; <- Bank02.asm:2088-2095 (LDX.b #$14 : LDA $A0 ...) +JSL.l Underworld_DoorDown_Entry : CPX #$10 +db $B0, $21 ; BCS $028B04 +BRA + : NOP #6 : + + +org $02C3F2 ; <- Bank02.asm:10521 Unused call +Underworld_DoorDown_Call: +org $02C3F3 +dw $8AD9 ; address of Bank02.asm:2085 + ; These two, if enabled together, have implications for vanilla BK doors in IP/Hera/Mire ; IPBJ is common enough to consider not doing this. Mire is not a concern for vanilla - maybe glitched modes ; Hera BK door back can be seen with Pot clipping - likely useful for no logic seeds diff --git a/asm/normal.asm b/asm/normal.asm index a8ab9597..aabb24de 100644 --- a/asm/normal.asm +++ b/asm/normal.asm @@ -398,7 +398,7 @@ StraightStairsTrapDoor: .animateTraps lda #$05 : sta $11 inc $0468 : stz $068e : stz $0690 - ++ rtl + ++ JSL Underworld_DoorDown_Call : rtl + JML Dungeon_ApproachFixedColor ; what we wrote over } diff --git a/asm/owrando.asm b/asm/owrando.asm index e0d986f5..8cd7bcf1 100644 --- a/asm/owrando.asm +++ b/asm/owrando.asm @@ -353,7 +353,7 @@ OWNewDestination: ; turn into bunny lda $5d : cmp #$17 : beq .return lda #$17 : sta $5d - lda #$01 : sta $02e0 + lda #$01 : sta $2e0 bra .return .nobunny lda $5d : cmp #$17 : bne .return diff --git a/data/base2current.bps b/data/base2current.bps index 044a244c..f66931c0 100644 Binary files a/data/base2current.bps and b/data/base2current.bps differ diff --git a/resources/app/cli/lang/de.json b/resources/app/cli/lang/de.json index d2c5d523..6a72d688 100644 --- a/resources/app/cli/lang/de.json +++ b/resources/app/cli/lang/de.json @@ -1,6 +1,6 @@ { "cli": { - "app.title": "ALttP Tür Randomisier Version %s - Nummer: %d, Code: %s", + "app.title": "ALttP Tür Randomisier Version %s - Nummer: %s, Code: %s", "shuffling.world": "Welt wird durchmischt.", "generating.itempool": "Generier Gegenstandsbasis.", "calc.access.rules": "Berechne Zugriffsregeln.", diff --git a/resources/app/cli/lang/en.json b/resources/app/cli/lang/en.json index b69287ea..70d7eeda 100644 --- a/resources/app/cli/lang/en.json +++ b/resources/app/cli/lang/en.json @@ -2,7 +2,7 @@ "cli": { "yes": "Yes", "no": "No", - "app.title": "ALttP Door Randomizer Version %s - Seed: %d, Code: %s", + "app.title": "ALttP Door Randomizer Version %s - Seed: %s, Code: %s", "version": "Version", "seed": "Seed", "player": "Player", diff --git a/resources/app/cli/lang/es.json b/resources/app/cli/lang/es.json index def18849..8bff9dd0 100644 --- a/resources/app/cli/lang/es.json +++ b/resources/app/cli/lang/es.json @@ -1,6 +1,6 @@ { "cli": { - "app.title": "ALttP Puerta Aleatorizador Versión %s - Número: %d, Código: %s", + "app.title": "ALttP Puerta Aleatorizador Versión %s - Número: %s, Código: %s", "player": "Jugador", "shuffling.world": "Barajando el Mundo", "shuffling.dungeons": "Barajando Mazmorras",