From e2b9735600b34fa6d6ccf7c7e1616c4dcfee07fb Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 7 Sep 2022 16:50:44 -0600 Subject: [PATCH] Rain prevention fix for keydoors (plus test case) Couple fixes for standard throne --- DungeonGenerator.py | 19 +++++++++++-------- Rom.py | 2 +- data/base2current.bps | Bin 93432 -> 93438 bytes source/dungeon/DungeonStitcher.py | 12 ++++++++++-- test/customizer/rainprevent_keydoor.yaml | 13 +++++++++++++ 5 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 test/customizer/rainprevent_keydoor.yaml diff --git a/DungeonGenerator.py b/DungeonGenerator.py index 445ed9b3..f982cb6f 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -16,6 +16,7 @@ from Dungeons import dungeon_regions, split_region_starts from RoomData import DoorKind from source.dungeon.DungeonStitcher import generate_dungeon_find_proposal +from source.dungeon.DungeonStitcher import GenerationException as OtherGenException class GraphPiece: @@ -1505,6 +1506,8 @@ def calc_allowance_and_dead_ends(builder, connections_tuple, world, player): builder.branches -= 1 if entrance not in drop_entrances_allowance: needed_connections.append(entrance) + if builder.sewers_access: + starting_allowance += 1 builder.allowance = starting_allowance for entrance in needed_connections: sector = find_sector(entrance, builder.sectors) @@ -3051,7 +3054,7 @@ def split_dungeon_builder(builder, split_list, builder_info): comb_w_replace = len(dungeon_map) ** len(candidate_sectors) return balance_split(candidate_sectors, dungeon_map, global_pole, builder_info) except (GenerationException, NeutralizingException): - if comb_w_replace and comb_w_replace <= 10000: + if comb_w_replace and comb_w_replace <= 10000 and not builder.throne_door: attempts += 5 # all the combinations were tried already, no use repeating else: attempts += 1 @@ -3535,7 +3538,7 @@ def check_for_valid_layout(builder, sector_list, builder_info): split_list['Sewers'].remove(temp_builder.throne_door.entrance.parent_region.name) builder.exception_list = list(sector_list) return True, {}, package - except (GenerationException, NeutralizingException): + except (GenerationException, NeutralizingException, OtherGenException): builder.split_dungeon_map = None builder.valid_proposal = None if temp_builder.name == 'Hyrule Castle' and temp_builder.throne_door: @@ -3948,20 +3951,20 @@ def find_free_equation(equations): def copy_door_equations(builder, sector_list): equations = {} for sector in builder.sectors + sector_list: - sector.equations = calc_sector_equations(sector) + sector.equations = calc_sector_equations(sector, builder.sewers_access) curr_list = equations[sector] = [] for equation in sector.equations: curr_list.append(equation.copy()) return equations -def calc_sector_equations(sector): +def calc_sector_equations(sector, sewers_flag=False): equations = [] - is_entrance = sector.is_entrance_sector() and not sector.destination_entrance + is_entrance = (sector.is_entrance_sector() and not sector.destination_entrance) or sewers_flag if is_entrance: flagged_equations = [] for door in sector.outstanding_doors: - equation, flag = calc_door_equation(door, sector, True) + equation, flag = calc_door_equation(door, sector, True, sewers_flag) if flag: flagged_equations.append(equation) equations.append(equation) @@ -3977,9 +3980,9 @@ def calc_sector_equations(sector): return equations -def calc_door_equation(door, sector, look_for_entrance): +def calc_door_equation(door, sector, look_for_entrance, sewers_flag=None): if look_for_entrance and not door.blocked: - flag = sector.is_entrance_sector() + flag = sector.is_entrance_sector() or sewers_flag if flag: eq = DoorEquation(door) eq.benefit[hook_from_door(door)].append(door) diff --git a/Rom.py b/Rom.py index 544f2c5b..18677375 100644 --- a/Rom.py +++ b/Rom.py @@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '0be31dc5cb338e7e85d1ce65e839c99e' +RANDOMIZERBASEHASH = '61c296effe6180274721d570d2471e1c' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index 9740c94d9fb0f54c63443282dd8a82eff36b7240..03d6471ed59fbc3a0aa2fcb13383c31d53c06f20 100644 GIT binary patch delta 950 zcmW-dZ%i9?7{~AFwX~y!7HC;JVEiZ5+|)Re`KM}NXu(BYvZ=s+ zS3E*-3wJ%r16&qL<(xoB7n-Gk1=(?X5jcC@~6{$f1vW^xOcESU!V4=iNhe570d6EU6 z(NZV!?um73)}+qlL?&Ek-)gfSXuSAaII5#8sgzdIs&nL|HN1HprnV`19!O<3%~JHE9X$~e7RU~Mw04sb^;Ij0p-$KIrk2Yl1?^oZzixh+f1gD-<0n zn&S-espjynlk@75_JS`IhIC83PBChOmL?TLSPxV_R3cr`k*gBVC>C_#mKAmtzIcN( z^#`X7ik{SoYxBcPyjhA}w)nkP`5+#(L1~7ibUWocvDF4{n8ix^d`F`8 zn}+@}8u|fObHJ6gDNz^p4rdQgEBOWg$bsXwih;m=o76ZcS!*10KQ&`hE;Ll@UJgw| z>U6y3&#sj+yT&z#9(mz+?Ec19oSbjWWNu?>XtfI~=wri}Jy@jcqzIgKfo7#jGl60K>a#tooBslPHFN6# delta 973 zcmW+xe@q)?7{0gHqb)03+qFO)KR&3?R-6GhCqjm}O`H`Ii9d)gagECyShi%ifHMkT z%MLA*wbvVbz`0Num(UW@>1n#nU>S<6e_2g18OfFmGlTyuXSNZXk$Us5_j#Z9$@9F= z)(vL!26O3M&>9YJM1}WYCrry>D5k+B&uM?uKuGS=kdtILWvw-e!2mYn$lnWDg+T+nN-pv!FI?v>^8Qc#`-nOjNxe~8fc^QQ znIR94_6rlk63s==b%yCGX_b^0eZF{=SkX$PX>n37h&`mH?ikyx%$e5M}i_% zAQ&e(C3oVP=r9SfV6fL+SrNk$jXoUkqIg(B=$o*+i9%ap@)Zjud(2n;jM#QGawk5o zEUCq3Bno{ha2iRcE-H#kOhgMqph1%YM@dGKN3@6i3XlnJf-1P1yles%YJV26b%6<0;oxrqj_7aC zdDLip)4M=XiYr9?4iXr;Cty4Id`y2Hv*;GtG{Y;V%JaT8ldyM0U>j|?7Bl2^3p5vY zw*}`Qb12bxuQ$C;ho71)=KZ^gfn2hH-B9lhiqIJpJISvW^^Y?0zyin2=SD+Q#B~B+ zn_ljnuTjuBa(p{PEX_nP1tcAnp<9|s%x8UAW(ijKpk%QhR{7K7Qz1O}R&%arE}63I{#HlL4WS z9JGNO_LD9fG@1{Tj0X!`-cXva82D*=RV{tZ22Lm?f7)PYUSE#LE!G?pc7Na}r<0BX zXfe>$r~64)8C21p-u|Rm2KfL@B#vMo%ThtUz1|m%ChWVyVpsAX1R8)hlUwDm>CtbV L-S-)h+rIn{?#hFv diff --git a/source/dungeon/DungeonStitcher.py b/source/dungeon/DungeonStitcher.py index aa74dee0..b5e7515e 100644 --- a/source/dungeon/DungeonStitcher.py +++ b/source/dungeon/DungeonStitcher.py @@ -56,6 +56,8 @@ def generate_dungeon_find_proposal(builder, entrance_region_names, split_dungeon if (access_region.name in world.inaccessible_regions[player] and region.name not in world.enabled_entrances[player]): excluded[region] = None + elif split_dungeon and builder.sewers_access and builder.sewers_access.entrance.parent_region == region: + continue elif len(region.entrances) == 1: # for holes access_region = next(x.parent_region for x in region.entrances if x.parent_region.type in [RegionType.LightWorld, RegionType.DarkWorld] @@ -182,11 +184,17 @@ def modify_proposal(proposed_map, explored_state, doors_to_connect, hash_code_se return proposed_map, hash_code attempt, opp_hook = None, None - opp_hook_len = 0 + opp_hook_len, possible_swaps = 0, list(visited_choices) while opp_hook_len == 0: - attempt = random.choice(visited_choices) + if len(possible_swaps) == 0: + break + attempt = random.choice(possible_swaps) + possible_swaps.remove(attempt) opp_hook = type_map[hook_from_door(attempt)] opp_hook_len = len(unvisted_bucket[opp_hook]) + if opp_hook_len == 0: + itr += 1 + continue unvisted_bucket[opp_hook].sort(key=lambda d: d.name) new_door = random.choice(unvisted_bucket[opp_hook]) old_target = proposed_map[attempt] diff --git a/test/customizer/rainprevent_keydoor.yaml b/test/customizer/rainprevent_keydoor.yaml new file mode 100644 index 00000000..31930dce --- /dev/null +++ b/test/customizer/rainprevent_keydoor.yaml @@ -0,0 +1,13 @@ +meta: + players: 1 +settings: + 1: + door_shuffle: crossed + mode: standard + shuffle: crossed +doors: + 1: + doors: + Hyrule Castle East Lobby N: + dest: Sewers Secret Room Key Door S + type: Key Door