From 0c640bf9dd252fa98a7723d8359a9066208c81ce Mon Sep 17 00:00:00 2001 From: aerinon Date: Mon, 10 Jul 2023 10:35:18 -0600 Subject: [PATCH 1/5] Fix for pyrmaid hole logic --- Main.py | 2 +- RELEASENOTES.md | 3 +++ Rules.py | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Main.py b/Main.py index 107b0694..e3f3df67 100644 --- a/Main.py +++ b/Main.py @@ -34,7 +34,7 @@ from source.overworld.EntranceShuffle2 import link_entrances_new from source.tools.BPS import create_bps_from_data from source.classes.CustomSettings import CustomSettings -version_number = '1.2.0.17' +version_number = '1.2.0.18' version_branch = '-u' __version__ = f'{version_number}{version_branch}' diff --git a/RELEASENOTES.md b/RELEASENOTES.md index e3d09589..a1013f6c 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -109,6 +109,9 @@ These are now independent of retro mode and have three options: None, Random, an # Bug Fixes and Notes +* 1.2.0.18u + * Fixed an issue with pyramid hole being in logic when it is not opened. + * * 1.2.0.17u * Fixed logic bug that allowed Pearl to be behind Graveyard Cave or King's Tomb entrances with only Mirror and West Dark World access (cross world shuffles only) * Removed backup locations for Dungeon Only and Major Only algorithms. If item cannot be placed in the appropriate location, the seed will fail to generate instead diff --git a/Rules.py b/Rules.py index 80392396..26e70f5f 100644 --- a/Rules.py +++ b/Rules.py @@ -887,7 +887,7 @@ def ow_inverted_rules(world, player): set_rule(world.get_entrance('Hyrule Castle Main Gate', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Hyrule Castle Main Gate (North)', player), lambda state: state.has_Mirror(player)) set_rule(world.get_location('Frog', player), lambda state: state.can_lift_heavy_rocks(player) and state.has_Pearl(player)) - set_rule(world.get_entrance('Pyramid Hole', player), lambda state: world.open_pyramid[player] or world.goal[player] == 'trinity' or state.has('Beat Agahnim 2', player)) + set_rule(world.get_entrance('Pyramid Hole', player), lambda state: world.is_pyramid_open(player) or state.has('Beat Agahnim 2', player)) else: set_rule(world.get_entrance('East Dark Death Mountain Teleporter (Top)', player), lambda state: state.can_lift_heavy_rocks(player) and state.has('Hammer', player) and state.has_Pearl(player)) # bunny cannot use hammer set_rule(world.get_entrance('East Dark Death Mountain Teleporter (Bottom)', player), lambda state: state.can_lift_heavy_rocks(player)) From 5d2ceaf75c22522a9cb15b45760e907d4df582cf Mon Sep 17 00:00:00 2001 From: aerinon Date: Mon, 10 Jul 2023 13:56:05 -0600 Subject: [PATCH 2/5] Updated baserom for crystal custscene and hera music fix Updated a couple of error messages and when they are displayed Updated Ganonhunt goal text to be more consistent across randomizers --- ItemList.py | 3 ++- Main.py | 4 +++- README.md | 2 +- RELEASENOTES.md | 7 +++++-- Rom.py | 2 +- data/base2current.bps | Bin 94044 -> 94169 bytes resources/app/gui/lang/en.json | 2 +- 7 files changed, 13 insertions(+), 7 deletions(-) diff --git a/ItemList.py b/ItemList.py index b9e3f4c8..a44a3f6e 100644 --- a/ItemList.py +++ b/ItemList.py @@ -1287,7 +1287,8 @@ def make_customizer_pool(world, player): bow_found = next((i for i in pool if i in {'Bow', 'Progressive Bow'}), None) if not bow_found: missing_items.append('Progressive Bow') - logging.getLogger('').warning(f'The following items are not in the custom item pool {", ".join(missing_items)}') + if missing_items: + logging.getLogger('').warning(f'The following items are not in the custom item pool {", ".join(missing_items)}') g, t = set_default_triforce(world.goal[player], world.treasure_hunt_count[player], world.treasure_hunt_total[player]) diff --git a/Main.py b/Main.py index e3f3df67..2edf2c03 100644 --- a/Main.py +++ b/Main.py @@ -628,7 +628,9 @@ def create_playthrough(world): logging.getLogger('').debug(world.fish.translate("cli", "cli", "building.calculating.spheres"), len(collection_spheres), len(sphere), len(prog_locations)) if not sphere: - logging.getLogger('').error(world.fish.translate("cli", "cli", "cannot.reach.items"), [world.fish.translate("cli","cli","cannot.reach.item") % (location.item.name, location.item.player, location.name, location.player) for location in sphere_candidates]) + if world.accessibility[location.item.player] != 'none': + logging.getLogger('').error(world.fish.translate("cli", "cli", "cannot.reach.items"), + [world.fish.translate("cli","cli","cannot.reach.item") % (location.item.name, location.item.player, location.name, location.player) for location in sphere_candidates]) if any([location.name not in optional_locations and world.accessibility[location.item.player] != 'none' for location in sphere_candidates]): raise RuntimeError(world.fish.translate("cli", "cli", "cannot.reach.progression")) else: diff --git a/README.md b/README.md index fbe9eed5..21a444cc 100644 --- a/README.md +++ b/README.md @@ -404,7 +404,7 @@ CLI: `--logic owglitches` New supported goals: * Trinity: Find one of 3 triforces to win. One is at pedestal. One is with Ganon. One is with Murahdahla who wants you to find 8 of 10 triforce pieces to complete. -* Triforce Hunt + Ganon: Collect the requisite triforce pieces, then defeat Ganon. (Aga2 not required). Use `ganonhunt` on CLI +* Ganonhunt: Collect the requisite triforce pieces, then defeat Ganon. (Aga2 not required). Use `ganonhunt` on CLI * Completionist: All dungeons not enough for you? You have to obtain every item in the game too. This option turns on the collection rate counter and forces accessibility to be 100% locations. Finish by defeating Ganon. diff --git a/RELEASENOTES.md b/RELEASENOTES.md index a1013f6c..5dc0ee0a 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -57,7 +57,7 @@ Please see [Customizer documentation](docs/Customizer.md) on how to create custo ## New Goals -### Triforce Hunt + Ganon +### Ganonhunt Collect the requisite triforce pieces, then defeat Ganon. (Aga2 not required). Use `ganonhunt` on CLI ### Completionist @@ -111,7 +111,10 @@ These are now independent of retro mode and have three options: None, Random, an * 1.2.0.18u * Fixed an issue with pyramid hole being in logic when it is not opened. - * + * Crystal cutscene at GT use new symmetrical layouts (thanks Codemann) + * Fix for Hera Boss music (thanks Codemann) + * Fixed accessibility: none using a spoiling message + * Fixed warning message about custom item pool when it is fine * 1.2.0.17u * Fixed logic bug that allowed Pearl to be behind Graveyard Cave or King's Tomb entrances with only Mirror and West Dark World access (cross world shuffles only) * Removed backup locations for Dungeon Only and Major Only algorithms. If item cannot be placed in the appropriate location, the seed will fail to generate instead diff --git a/Rom.py b/Rom.py index ea0b9c68..482080b2 100644 --- a/Rom.py +++ b/Rom.py @@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '9903cdfc3fc69112919ec49fb63e09ab' +RANDOMIZERBASEHASH = '467681d6160233f7af2761c631e26985' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index e58c28ab1b469f73a96a04d2e5d5d50a2ca92b26..9b3d673a51005eba1d3d336d10206d582cb1852b 100644 GIT binary patch delta 8191 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 delta 8271 zcmW+)30xCL7vI^05blICBFeI$0)ob?C@LaSMMcG1F%|03qVcS>;!)TQL=CVcVGLuk z(gfHTgT-J`@v10Z#A;2e{c3Hi*3Yk1v~8^R5Zm$%{`NQX{xkDt-?2l~z;LP=Ov662YTp+^cgs*I!wxOnZB*%*hVG)>S_b5nbE;{^ z1InLbvo3yT)ik(wxhJ0*|bLlR#|QWZBtY z0YMV&z3r`RyJfS_f!rgkso2z@Dm6Rky=F(DES@pZr)nGwfQ>Q#GtxWtj_%AO99?X7 zB-U~Cvm*yf490GH8|PTE%S>B2M=L0dImgi#ERMt)6Mfs_=g3eoh_5)I^g$Ur1IWnL5gK`7=-Tbb!nKX_2Ywu2__?uMgm_&tx?t3Aavj6XxTSH zVx{id6*!3;6ubipV;@WDzpe;*tZoo|kE91YtagmmarC;w2XD8~r@pe$?|&Plx>+t{ z?&jzgc!Z?OE>;Wov1Ux;K8`Lk*%B&D^iN$_s-oPyq1s_T;+51DkNtH4qr1D?A=Yp- z%{el)cDh+B-0$^DnV7n=%qs~RowLFr#yj}q4dI-b{z@x&B;DDp?gy<1O}6elJxA|=mqnvM8SD{J zU@Pn|R>qFGEIifHTYEDYu|`M#(FK+YCdL0SZOJ{)#@U(Q3G!F_Ytl}y-%8wo$+NVT!_o|O|-yOE$T{oF*kBsyZD0D0L zYWEuuSwmpn5k{eCFGs(+Bz(-#E1}MhqJ8y_Te@Pc?V4`zE!zaVMQ@|x)7IANTqYYDJEj&U`ws%?FwcLA z|DV{$a?6eMeFLobp9AFZXa6Gl#!aF7ppmY|ws>fy!?Azwujg&5(^$!F=`K$7@*B7{ zV8F=uTS9jsUjLbELYK}{X}kUPf?+I2$8^~W+qCo|KDNlTgf*)kSM{wp9Q#}-{32jT zgt|u9&(Re%!UDlaFJf)oT}IV<7!){{JarQm2965PsD8agh6Q*dx_`0-mYY-o&=EKc z%!dC793Q*IBdDr4di9mQ*p^E9X=1}BmL1w^rdgvv&w|RJ$kZc7ArPzb%Nd~v2SBRc zvF~o#!b)xO1WQT4N0~b`x;iN2RMyj*%r?BeTY|Pp-<@mK-E!HE!skI_Mac`TZNq|H zpv;eR5WPnFk=Mqc{?D62xlFLTFLKufm+L<4ZCJObZApZlILh^zG{MAW5rpe6-Bc)) z;3Mkb89`Cbsz`bToNg4J>gcKao8*giqZwDwY(qFxPk(EDz1V#^nzZpm9Dm!W zO0o&vCs1n9u1$R*HwvzhEz0`zjKG9mnKN(qxt43h3~&`B6SW`|oG{YI_6pr+Oj)u= zkMOa=u$c$hiN$-^xjV~s%WOELI2unq!O^>6k8ILl{{~?+4uBu9gg!SrV-uDzMpa&| z&|R{Jqi@>;4@Y0MwH3&xlH{jd&=EE)+EgQCvMht0^nuG(c(FZMD`r^nMUGwye+^p( zK7cdBXW>I->BvUG;`ZYv?=h^2`z2b>vn2%M~}ycV@11;#}nncC3l2` zDmZ6Z?O5#o2fnw7@zer%KcZjSz;A^|E?d{>UvB^Uy{dv!b=?t4G}enIZLliuTOqNE zQ|-iatMx#Wz`-dRg3)JN`vO-P*#ZpkZlp?zkC(!O4fKk(tf-fRMLGR7Fe5_&ShzSN zmMr`pmSp6oe>8n1uYblq;Wg|lTwYU4@KN^Zp>et2-J3D%yI#ORIkQhckcD!#kHj)@ znqX#_0?H;SK{lK`DIH9KJ10#5HSpx53G!*!(f4RCyHP;oJw-i7Q*DyW;i8B)KNIxd z88>)*=?YY7+=%G~R0(HJ=>=_VGqaP(z}mubm4{ahsYTO5n%bDDQDpcZU4j#Ek4c)l zBDf%{^!m^ucqnH%*Z}>fQ{YUfCgcInAyfXV+ z?r?8EC((!L=0=;|e6Ezv;cfLyFn#optw^17Iy?IbOr1SSB$;vxuADs{3~#c|_6eSP zRbc#SEw07%#j9;C^EF~=?WoBJPR!c})0U)&($}18duPcffIJ1;qVrb+K(#T;7Ky}l z@{CG&XZdQ8Ec|bnRj@>~WY{%WUl1!r%Z9(?7p1<07YbI$oZ)tx+s^~kMMXt*5g*=b z8(sJ_2&vnaW91mB^EThF^hZ7yDpw2x!`lj0oE3usZ3Ew(FB&df5n3*aZ^SW5FTX>% z>xkRe+n+vuMNm6OX}i#b>$(7!8Wk_7FgtzKxWCP|HWx(9-17O!$@hX3YFFfoQa?(M z>!!jsu&z@EGTJWg^p%h&ufyw_735d{fg{QxnA~=${ARG>hzDBV--4Ow7OoPzC5lHJtaD27<5vN z!D_n5D$uv;+g6`e`j8L1+R(Xf5Sh^>*!z2jSP3cj-^%(8tWulXqk0RX&MReOs)fQ% z%EbpI>5o023YjxB?lBzCt*%D%(%8p0WM1V1%3x>gUNOD&hSas3QMw6_SasoZ6ur6H z2rz`$%hJ=ERbf1bhsb7i+B`f*Cl1>l!%Vp9VqI{*geB z)ChFqUI$%!LZAtzgFe6sbTh2#$|T3lhS$3WWE1N-9qE;zrIYk<`6Rs#c!!`jF)r<3 z`#Un$GnV(lYP1{6t;@w6oH^2$VI_6j25M?c%1{J@qc!A3sVWl=bH|EyE`AB~+_@ka z*1J<>E7n(==rj9luHC#^!F?48@3^x;KNx#;49I~Cua^4mxFXc`Usnz9Tpc{Wbl4OA z0BqwwfgSwWs?XqC6K=b66?=0>>`m$=Jd(y-9>er>lsECVRv93%EdI@hp<2AGGI~k?e%Oo~_ zXT8M^a5&hD)_trWzt=Qkud7;%AM(l0;+iZI%b7hG(Q7h0(R;Itr-Llx8mhpSgS$+<~O5vY6i|rAg$RdHa z+eLk9EU?%f%25D|vRM8eE7qSe=2~p3P*jP8s`ZRH5I5wmH(^bEW4OguD0fXoC5$=7 zVp}D5O+z*21dFXm?#jU^#bR40cTLA=w8i$F+%*HE2^QOZxvOj@hS^xK+%*d$6;?^^ znvKya{KimM9!Bf%3qxIVF)GF{40X-JXeWMQsB1p{Zk)9JCUdFqs@Ctdy(f3Qg>~hA zle?DloG#Q=0C#C!OW_o4)j94vi|sG{FFIy°`X4)5(K{T}vV8Q!2ldJX#&(odD~x(*$f+FJ%jrb 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 WZ`*gx12YFmOGf(@j^A=;)c*lzQAw!) diff --git a/resources/app/gui/lang/en.json b/resources/app/gui/lang/en.json index eb53f640..9d56137c 100644 --- a/resources/app/gui/lang/en.json +++ b/resources/app/gui/lang/en.json @@ -241,7 +241,7 @@ "randomizer.item.goal.triforcehunt": "Triforce Hunt", "randomizer.item.goal.trinity": "Trinity", "randomizer.item.goal.crystals": "Crystals", - "randomizer.item.goal.ganonhunt": "Triforce Hunt + Ganon", + "randomizer.item.goal.ganonhunt": "Ganonhunt", "randomizer.item.goal.completionist": "Completionist", "randomizer.item.crystals_gt": "Crystals to open GT", From d135405ed3bb76bd68d16e20ac1235eb65294129 Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 12 Jul 2023 09:16:00 -0600 Subject: [PATCH 3/5] Customizer: Exception raised for placements of items that are not in pool --- ItemList.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ItemList.py b/ItemList.py index a44a3f6e..5ffb5152 100644 --- a/ItemList.py +++ b/ItemList.py @@ -1397,6 +1397,8 @@ def fill_specific_items(world): track_dungeon_items(item_to_place, loc, world) loc.event = (event_flag or item_to_place.advancement or item_to_place.bigkey or item_to_place.smallkey) + else: + raise Exception(f'Did not find "{item}" in item pool to place at "{location}"') advanced_placements = world.customizer.get_advanced_placements() if advanced_placements: for player, placement_list in advanced_placements.items(): @@ -1406,7 +1408,7 @@ def fill_specific_items(world): item_to_place, event_flag = get_item_and_event_flag(item, world, player, dungeon_pool, prize_set, prize_pool) if not item_to_place: - continue + raise Exception(f'Did not find "{item}" in item pool to place for a LocationGroup"') locations = placement['locations'] handled = False while not handled: From 1b81151941eca3fb963e010b1bb023ead6ed262d Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 12 Jul 2023 09:50:53 -0600 Subject: [PATCH 4/5] Customizer: Fixed issue with Assured sword and start inventory --- ItemList.py | 31 +++++++++++++++++-------------- RELEASENOTES.md | 4 +++- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/ItemList.py b/ItemList.py index 5ffb5152..168d841d 100644 --- a/ItemList.py +++ b/ItemList.py @@ -1297,20 +1297,23 @@ def make_customizer_pool(world, player): if pieces < t: pool.extend(['Triforce Piece'] * (t - pieces)) - if not world.customizer.get_start_inventory(): - if world.logic[player] in ['owglitches', 'nologic']: - precollected_items.append('Pegasus Boots') - if 'Pegasus Boots' in pool: - pool.remove('Pegasus Boots') - pool.append('Rupees (20)') - if world.swords[player] == 'assured': - precollected_items.append('Progressive Sword') - if 'Progressive Sword' in pool: - pool.remove('Progressive Sword') - pool.append('Rupees (50)') - elif 'Fighter Sword' in pool: - pool.remove('Fighter Sword') - pool.append('Rupees (50)') + sphere_0 = world.customizer.get_start_inventory() + no_start_inventory = not sphere_0 or not sphere_0[player] + init_equip = [] if no_start_inventory else sphere_0[player] + if (world.logic[player] in ['owglitches', 'nologic'] + and (no_start_inventory or all(x != 'Pegasus Boots' for x in init_equip))): + precollected_items.append('Pegasus Boots') + if 'Pegasus Boots' in pool: + pool.remove('Pegasus Boots') + pool.append('Rupees (20)') + if world.swords[player] == 'assured' and (no_start_inventory or all(' Sword' not in x for x in init_equip)): + precollected_items.append('Progressive Sword') + if 'Progressive Sword' in pool: + pool.remove('Progressive Sword') + pool.append('Rupees (50)') + elif 'Fighter Sword' in pool: + pool.remove('Fighter Sword') + pool.append('Rupees (50)') return pool, placed_items, precollected_items, clock_mode, 1 diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 5dc0ee0a..5f11c963 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -113,7 +113,9 @@ These are now independent of retro mode and have three options: None, Random, an * Fixed an issue with pyramid hole being in logic when it is not opened. * Crystal cutscene at GT use new symmetrical layouts (thanks Codemann) * Fix for Hera Boss music (thanks Codemann) - * Fixed accessibility: none using a spoiling message + * Customizer: fixed an issue with assured sword and start_inventory + * Customizer: warns when trying to specifically place an item that's not in the item pool + * Fixed "accessibility: none" displaying a spoiling message * Fixed warning message about custom item pool when it is fine * 1.2.0.17u * Fixed logic bug that allowed Pearl to be behind Graveyard Cave or King's Tomb entrances with only Mirror and West Dark World access (cross world shuffles only) From 213d3d3aa0798722225e9c3707c2945b96c1d3b9 Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 19 Jul 2023 12:31:50 -0600 Subject: [PATCH 5/5] Fixed an issue where certain vanilla door types would not allow other types to be placed. Customizer: fixed an issue where last ditch placements would move customized items. Those are now locked and the generation will fail instead if no alternatives are found. --- DoorShuffle.py | 28 +++++++++++++++------------- ItemList.py | 2 ++ RELEASENOTES.md | 2 ++ 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index a0add44b..35cc7624 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -1962,7 +1962,7 @@ def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, all_cu if flex_map[dungeon] > 0: queue.append(dungeon) # time to re-assign - reassign_big_key_doors(bk_map, world, player) + reassign_big_key_doors(bk_map, used_doors, world, player) for name, big_list in bk_map.items(): used_doors.update(flatten_pair_list(big_list)) return used_doors @@ -2047,7 +2047,7 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, all_ else: builder.key_doors_num -= 1 # time to re-assign - reassign_key_doors(small_map, world, player) + reassign_key_doors(small_map, used_doors, world, player) for dungeon_name in pool: if world.keyshuffle[player] != 'universal': builder = world.dungeon_layouts[player][dungeon_name] @@ -2129,7 +2129,7 @@ def shuffle_bomb_dash_doors(door_type_pools, used_doors, start_regions_map, all_ suggestion_map[dungeon] = pair queue.append(dungeon) # time to re-assign - reassign_bd_doors(bd_map, world, player) + reassign_bd_doors(bd_map, used_doors, world, player) for name, pair in bd_map.items(): used_doors.update(flatten_pair_list(pair[0])) used_doors.update(flatten_pair_list(pair[1])) @@ -2539,7 +2539,7 @@ def find_current_bk_doors(builder): return current_doors -def reassign_big_key_doors(bk_map, world, player): +def reassign_big_key_doors(bk_map, used_doors, world, player): logger = logging.getLogger('') for name, big_doors in bk_map.items(): flat_proposal = flatten_pair_list(big_doors) @@ -2547,11 +2547,12 @@ def reassign_big_key_doors(bk_map, world, player): queue = deque(find_current_bk_doors(builder)) while len(queue) > 0: d = queue.pop() - if d.type is DoorType.Interior and d not in flat_proposal and d.dest not in flat_proposal: + if (d.type is DoorType.Interior and d not in flat_proposal and d.dest not in flat_proposal + and d not in used_doors and d.dest not in used_doors): if not d.entranceFlag: world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) d.bigKey = False - elif d.type is DoorType.Normal and d not in flat_proposal: + elif d.type is DoorType.Normal and d not in flat_proposal and d not in used_doors: if not d.entranceFlag: world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) d.bigKey = False @@ -2795,7 +2796,7 @@ def find_valid_bd_combination(builder, suggested, world, player): return bomb_proposal, dash_proposal, ttl_needed -def reassign_bd_doors(bd_map, world, player): +def reassign_bd_doors(bd_map, used_doors, world, player): for name, pair in bd_map.items(): flat_bomb_proposal = flatten_pair_list(pair[0]) flat_dash_proposal = flatten_pair_list(pair[1]) @@ -2808,10 +2809,10 @@ def reassign_bd_doors(bd_map, world, player): queue = deque(find_current_bd_doors(builder, world)) while len(queue) > 0: d = queue.pop() - if d.type is DoorType.Interior and not_in_proposal(d): + if d.type is DoorType.Interior and not_in_proposal(d) and d not in used_doors and d.dest not in used_doors: if not d.entranceFlag: world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) - elif d.type is DoorType.Normal and not_in_proposal(d): + elif d.type is DoorType.Normal and not_in_proposal(d) and d not in used_doors: if not d.entranceFlag: world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) do_bombable_dashable(pair[0], DoorKind.Bombable, world, player) @@ -3003,7 +3004,7 @@ def valid_key_door_pair(door1, door2): return len(door1.entrance.parent_region.exits) <= 1 or len(door2.entrance.parent_region.exits) <= 1 -def reassign_key_doors(small_map, world, player): +def reassign_key_doors(small_map, used_doors, world, player): logger = logging.getLogger('') for name, small_doors in small_map.items(): logger.debug(f'Key doors for {name}') @@ -3013,7 +3014,7 @@ def reassign_key_doors(small_map, world, player): queue = deque(find_current_key_doors(builder)) while len(queue) > 0: d = queue.pop() - if d.type is DoorType.SpiralStairs and d not in proposal: + if d.type is DoorType.SpiralStairs and d not in proposal and d not in used_doors: room = world.get_room(d.roomIndex, player) if room.doorList[d.doorListPos][1] == DoorKind.StairKeyLow: room.delete(d.doorListPos) @@ -3023,13 +3024,14 @@ def reassign_key_doors(small_map, world, player): else: room.delete(d.doorListPos) d.smallKey = False - elif d.type is DoorType.Interior and d not in flat_proposal and d.dest not in flat_proposal: + elif (d.type is DoorType.Interior and d not in flat_proposal and d.dest not in flat_proposal + and d not in used_doors and d.dest not in used_doors): if not d.entranceFlag: world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) d.smallKey = False d.dest.smallKey = False queue.remove(d.dest) - elif d.type is DoorType.Normal and d not in flat_proposal: + elif d.type is DoorType.Normal and d not in flat_proposal and d not in used_doors: if not d.entranceFlag: world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) d.smallKey = False diff --git a/ItemList.py b/ItemList.py index 168d841d..9ca15555 100644 --- a/ItemList.py +++ b/ItemList.py @@ -1396,6 +1396,7 @@ def fill_specific_items(world): dungeon_pool, prize_set, prize_pool) if item_to_place: world.push_item(loc, item_to_place, False) + loc.locked = True track_outside_keys(item_to_place, loc, world) track_dungeon_items(item_to_place, loc, world) loc.event = (event_flag or item_to_place.advancement @@ -1431,6 +1432,7 @@ def fill_specific_items(world): if loc.item: continue world.push_item(loc, item_to_place, False) + loc.locked = True track_outside_keys(item_to_place, loc, world) track_dungeon_items(item_to_place, loc, world) loc.event = (event_flag or item_to_place.advancement diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 5f11c963..7010ecb6 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -113,6 +113,8 @@ These are now independent of retro mode and have three options: None, Random, an * Fixed an issue with pyramid hole being in logic when it is not opened. * Crystal cutscene at GT use new symmetrical layouts (thanks Codemann) * Fix for Hera Boss music (thanks Codemann) + * Fixed an issue where certain vanilla door types would not allow other types to be placed. + * Customizer: fixed an issue where last ditch placements would move customized items. Those are now locked and the generation will fail instead is no alternative are found. * Customizer: fixed an issue with assured sword and start_inventory * Customizer: warns when trying to specifically place an item that's not in the item pool * Fixed "accessibility: none" displaying a spoiling message