From bce3bcf4fe8036c3a767c9d8cbbf98debbb68e07 Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 14 Sep 2021 16:02:31 -0600 Subject: [PATCH] Remove stonewall pre-opening code in favor of dynamic softlock prevention (Promoted from experimental) --- DoorShuffle.py | 6 ++---- DungeonGenerator.py | 44 ------------------------------------------ Main.py | 2 +- RELEASENOTES.md | 8 ++++++++ Rom.py | 9 +-------- asm/overrides.asm | 6 +----- data/base2current.bps | Bin 135945 -> 135928 bytes 7 files changed, 13 insertions(+), 62 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 9d22893c..ee9cbd01 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -1358,10 +1358,8 @@ def combine_layouts(recombinant_builders, dungeon_builders, entrances_map): if recombine.master_sector is None: recombine.master_sector = builder.master_sector recombine.master_sector.name = recombine.name - recombine.pre_open_stonewalls = builder.pre_open_stonewalls else: recombine.master_sector.regions.extend(builder.master_sector.regions) - recombine.pre_open_stonewalls.update(builder.pre_open_stonewalls) recombine.layout_starts = list(entrances_map[recombine.name]) dungeon_builders[recombine.name] = recombine @@ -2043,8 +2041,8 @@ class DROptions(Flag): Debug = 0x08 # Rails = 0x10 # Unused bit now OriginalPalettes = 0x20 - Open_PoD_Wall = 0x40 # If on, pre opens the PoD wall, no bow required - Open_Desert_Wall = 0x80 # If on, pre opens the desert wall, no fire required + # Open_PoD_Wall = 0x40 # No longer pre-opening pod wall - unused + # Open_Desert_Wall = 0x80 # No longer pre-opening desert wall - unused Hide_Total = 0x100 DarkWorld_Spawns = 0x200 diff --git a/DungeonGenerator.py b/DungeonGenerator.py index 19ab9a1d..12aaa1c9 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -56,23 +56,10 @@ def pre_validate(builder, entrance_region_names, split_dungeon, world, player): def generate_dungeon(builder, entrance_region_names, split_dungeon, world, player): - stonewalls = check_for_stonewalls(builder) sector = generate_dungeon_main(builder, entrance_region_names, split_dungeon, world, player) - for stonewall in stonewalls: - if not stonewall_valid(stonewall): - builder.pre_open_stonewalls.add(stonewall) return sector -def check_for_stonewalls(builder): - stonewalls = set() - for sector in builder.sectors: - for door in sector.outstanding_doors: - if door.stonewall: - stonewalls.add(door) - return stonewalls - - def generate_dungeon_main(builder, entrance_region_names, split_dungeon, world, player): if builder.valid_proposal: # we made this earlier in gen, just use it proposed_map = builder.valid_proposal @@ -612,35 +599,6 @@ def winnow_hangers(hangers, hooks): hangers[hanger].remove(door) -def stonewall_valid(stonewall): - bad_door = stonewall.dest - if bad_door.blocked: - return True # great we're done with this one - loop_region = stonewall.entrance.parent_region - start_regions = [bad_door.entrance.parent_region] - if bad_door.dependents: - for dep in bad_door.dependents: - start_regions.append(dep.entrance.parent_region) - queue = deque(start_regions) - visited = set(start_regions) - while len(queue) > 0: - region = queue.popleft() - if region == loop_region: - return False # guaranteed loop - possible_entrances = list(region.entrances) - for entrance in possible_entrances: - parent = entrance.parent_region - if parent.type != RegionType.Dungeon: - return False # you can get stuck from an entrance - else: - door = entrance.door - if (door is None or (door != stonewall and not door.blocked)) and parent not in visited: - visited.add(parent) - queue.append(parent) - # we didn't find anything bad - return True - - def create_graph_piece_from_state(door, o_state, b_state, proposed_map, exception): # todo: info about dungeon events - not sure about that graph_piece = GraphPiece() @@ -1198,8 +1156,6 @@ class DungeonBuilder(object): self.path_entrances = None # used for pathing/key doors, I think self.split_flag = False - self.pre_open_stonewalls = set() # used by stonewall system - self.candidates = None self.total_keys = None self.key_doors_num = None diff --git a/Main.py b/Main.py index 11bf51d3..0db8af04 100644 --- a/Main.py +++ b/Main.py @@ -29,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.5.1.1-u' +__version__ = '0.5.1.2-u' from source.classes.BabelFish import BabelFish diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 4d212275..55a34c3f 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -15,6 +15,14 @@ CLI: ```--bombbag``` # Bug Fixes and Notes. +* 0.5.1.2 + * Allowed Blind's Cell to be shuffled anywhere if Blind is not the boss of Thieves Town + * Remove unique annotation from a FastEnum that was causing problems + * Updated prevent mixed_travel setting to prevent more mixed travel + * Prevent key door loops on the same supertile where you could have spent 2 keys on one logical door + * Promoted dynamic soft-lock prevention on "stonewalls" from experimental to be the primary prevention (Stonewalls are now never pre-opened) + * Fix to money balancing algorithm with small item_pool, thanks Catobat + * Many fixes and refinements to key logic and generation * 0.5.1.1 * Shop hints in ER are now more generic instead of using "near X" because they aren't near that anymore * Added memory location for mutliworld scripts to read what item was just obtain (longer than one frame) diff --git a/Rom.py b/Rom.py index d6248488..22f017e3 100644 --- a/Rom.py +++ b/Rom.py @@ -32,7 +32,7 @@ from source.classes.SFX import randomize_sfx JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'ef6e3e1aa59838c01dbd5b1b2387e70c' +RANDOMIZERBASEHASH = '11f4f494e999a919aafd7d2624e67679' class JsonRom(object): @@ -754,13 +754,6 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_bytes(paired_door.address_a(world, player), paired_door.rom_data_a(world, player)) rom.write_bytes(paired_door.address_b(world, player), paired_door.rom_data_b(world, player)) if world.doorShuffle[player] != 'vanilla': - if not world.experimental[player]: - for builder in world.dungeon_layouts[player].values(): - for stonewall in builder.pre_open_stonewalls: - if stonewall.name == 'Desert Wall Slide NW': - dr_flags |= DROptions.Open_Desert_Wall - elif stonewall.name == 'PoD Bow Statue Down Ladder': - dr_flags |= DROptions.Open_PoD_Wall for name, pair in boss_indicator.items(): dungeon_id, boss_door = pair opposite_door = world.get_door(boss_door, player).dest diff --git a/asm/overrides.asm b/asm/overrides.asm index f9842866..a041ae30 100644 --- a/asm/overrides.asm +++ b/asm/overrides.asm @@ -35,11 +35,7 @@ rtl OnFileLoadOverride: jsl OnFileLoad ; what I wrote over - lda.l DRFlags : and #$80 : beq + ;flag is off - lda $7ef086 : ora #$80 : sta $7ef086 - + lda.l DRFlags : and #$40 : beq + ;flag is off - lda $7ef036 : ora #$80 : sta $7ef036 - + lda.l DRFlags : and #$02 : beq + + + lda.l DRFlags : and #$02 : beq + ; Mirror Scroll lda $7ef353 : bne + lda #$01 : sta $7ef353 + rtl diff --git a/data/base2current.bps b/data/base2current.bps index 17b3e4976a8e05b8f7e0a167166c55236e3a9806..46dee4bec02691a6036774e7670b7a070e81727c 100644 GIT binary patch delta 1022 zcmW-de@q)?7{~9uw)CK^6tJ!)W4shtsRIR>QbZOk$e0eoh76n&8?uQ8H+5pj62k5Z zx2-|iYhTJ)Dgt8%6gEn{kOE6Bn-Xw;xNaGn&N#P#Q6~vkp&%g+Z~pcDkK;8ZC6i9=tEdv(0eet7PJtAD6juZMaXXrk9K@GcULzfp zfF?984+1N)6Gw^pcHMWJcDbDo6Z-&g^Z8Nb0BCuuVnYg){CQQn9uWL^ZY2O}q{uq} z)O>XwcvgAEn10V<__Lt%Sk=#i6{zm`EnH&c^WLi~27P@0rQdTv9%@_E5jl2J#sPQ= zO)c&Ob?B$Xq{sk+TIo&3*2?3*rO3Ah7+ULDB^4sI$?(}rJf0fT)EnxxxsHooDXG)r zLbSJHr8yYk0X9+V-FssPQQbRy!g2vP^MRumCna#)@%@&d={o)I#`KmTgHd*|E4D+s z&0x}){;#MfRoEVA*zrZ5gAx4?44g#{CnuqMTO+>RJ>i$?$zUWWr2%}Qh1|wTd+>8k zsA3>a_mqtBg}&}5fJOvRbuTSM^~igjB-Fqhvk5JXl>6or8BPMnQ zuN;}A2%Gt`jFZ9u^M~IxLo3h)I@;u@x{s2kTw;zg`IAujWZMHuZfk8@XuB>BblDcf z2cyxD7UZCtAsslyZ-kT}s{)ZvP0MV%NXrpKI*5mtUl&gye=$vCn2=^;sbtpN-iXL& z*z>N>5g7w(kzwVHG!J4wae4?$sP`tXHbW=7e*B=tJ%Ci@78eGBI`7_<5f%GuHX2!> zVh^#l3#{=3dG+FKvp-XShfw}16JOJbnkY_=1tkY+Iz6#z-kK=%U^Nlm>CkD;{N14& z3YY|)tLW*uIZrr6)c(djLLUJ$P+~YW?&FsPcWH|yCeYMb^5LcS2zU$~4jbdYbh_hJ zU3PJ$o<&BIie{B)B%BU{=*RF*(1q5+Wq73@?OWT0m%WQVT1!{HC3Dl)GON0aPf~2w zcHXo0@{Y*<#>~0GvnlX8yA%hKC9$c<7Z(rS&meM-`lzB=jlpLw09JKk;iunN8xqKy z*lPsrzM$u&<*E6jeub#cjWL zx`n;(1wAsfe;|Wm&10Yx-~X5I))>eJlGyC8e8ks4qg4$nrPnOOTUSPQm%FUBeJ(cZ ZHh_|>va7y|+hBAr@maM$aAWG>`hTN1v+e)@ delta 1039 zcmW-be^8Tk9LJyUvtJJk$AI8wh5Isuu^L5!H+~3BFoX zkV)*0&3=3!F~V=kho|U zC}3)fz!Q={dCj+`{3R`=Q-3p5kB%Jv3UA)d6uo++9Lz8Smlidk9(64!i8>o8paFEE zz``cbh3+h*5n(H8*UOQC;r+T|LYDm<&Cm@CO`Ox_<1t{Im#=%7}QmG!qkX0coQ?BUue64Q9$?|L!QEs)Pak69?rXv6ZhIe2^57l&r%_hc z^Y%ZHV3ZZWr)(U1-3G5&@^v!Z|A>BwHeN4GJ$Kpn1l=cH#9CV-tK8 z8H%C#MgX_8ksD}!FMh@W^Q;gz_DZiZ;<57&3o@>NYWs|AY_F)#LCWM%W6+_nS2i}k z!%FjDU55_twbBqCw5qfi97Oln)U6F;=G^;Eez9Yjol!-xVH$%O$cWP-E^uyy7O3K} z;c@r2@$)!*4jC~zj(Q0dFK2911oVW(a9Kd}Vc7cnglonqM*YS(oxSD037c-VomR$j>Z0#U~u9s*+n<;*( z#kup1OWi`)iOM6TNkNCZPTFJRPF7N=l+?#j2ar3W2CHZ;vI$J0#mI|z>Lk*vW#TD1 zRKKQ{qzT=|PjV{WFF&TIj;1iKwZg|^`eS#G?SBdPBaK{_w{ts8zk3A~m~9Ix~1 z%Vw)I{zfe@C(BPYPMVui$uF@HVNOfizu0XoiZ#DHH4nhPxieI?Uw#180ExYjf7Tvz zBB)Ou$bBs6Z?6GmwL*7w#bR*>b<+oW1-vM?qZ&s+C9fp+H~;h~$OSy+rR28Gx}m)-(bN{HFKva|0P@cI7$0bslV