Zillion: Priority Dead Ends Feature (#4220)

This commit is contained in:
Doug Hoskisson 2025-01-19 15:31:09 -08:00 committed by GitHub
parent 563794ab83
commit ca8ffe583d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 46 additions and 2 deletions

View File

@ -24,6 +24,7 @@ from .patch import ZillionPatch
from zilliandomizer.system import System
from zilliandomizer.logic_components.items import RESCUE, items as zz_items, Item as ZzItem
from zilliandomizer.logic_components.locations import Location as ZzLocation, Req
from zilliandomizer.map_gen.region_maker import DEAD_END_SUFFIX
from zilliandomizer.options import Chars
from worlds.AutoWorld import World, WebWorld
@ -172,6 +173,7 @@ class ZillionWorld(World):
self.logic_cache = logic_cache
w = self.multiworld
self.my_locations = []
dead_end_locations: list[ZillionLocation] = []
self.zz_system.randomizer.place_canister_gun_reqs()
# low probability that place_canister_gun_reqs() results in empty 1st sphere
@ -224,6 +226,16 @@ class ZillionWorld(World):
here.locations.append(loc)
self.my_locations.append(loc)
if ((
zz_here.name.endswith(DEAD_END_SUFFIX)
) or (
(self.options.map_gen.value != self.options.map_gen.option_full) and
(loc.name in self.options.priority_dead_ends.vanilla_dead_ends)
) or (
loc.name in self.options.priority_dead_ends.always_dead_ends
)):
dead_end_locations.append(loc)
for zz_dest in zz_here.connections.keys():
dest_name = "Menu" if zz_dest.name == "start" else zz_reg_name_to_reg_name(zz_dest.name)
dest = all_regions[dest_name]
@ -233,6 +245,8 @@ class ZillionWorld(World):
queue.append(zz_dest)
done.add(here.name)
if self.options.priority_dead_ends.value:
self.options.priority_locations.value |= {loc.name for loc in dead_end_locations}
@override
def create_items(self) -> None:

View File

@ -272,6 +272,20 @@ class ZillionMapGen(Choice):
return "full"
class ZillionPriorityDeadEnds(DefaultOnToggle):
"""
Single locations that are in a dead end behind a door
(example: vanilla Apple location)
are prioritized for progression items.
"""
display_name = "priority dead ends"
vanilla_dead_ends: ClassVar = frozenset(("E-5 top far right", "J-4 top left"))
""" dead ends when not generating these rooms """
always_dead_ends: ClassVar = frozenset(("A-6 top right",))
""" dead ends in rooms that never get generated """
@dataclass
class ZillionOptions(PerGameCommonOptions):
continues: ZillionContinues
@ -293,6 +307,7 @@ class ZillionOptions(PerGameCommonOptions):
skill: ZillionSkill
starting_cards: ZillionStartingCards
map_gen: ZillionMapGen
priority_dead_ends: ZillionPriorityDeadEnds
room_gen: Removed

View File

@ -1,2 +1,2 @@
zilliandomizer @ git+https://github.com/beauxq/zilliandomizer@33045067f626266850f91c8045b9d3a9f52d02b0#0.9.0
zilliandomizer @ git+https://github.com/beauxq/zilliandomizer@96d9a20f8278cee64bb4db859fbd874e0f332d36#0.9.1
typing-extensions>=4.7, <5

View File

@ -1,6 +1,7 @@
from . import ZillionTestBase
from ..options import ZillionJumpLevels, ZillionGunLevels, ZillionOptions, validate
from .. import ZillionWorld
from ..options import ZillionJumpLevels, ZillionGunLevels, ZillionOptions, ZillionPriorityDeadEnds, validate
from zilliandomizer.options import VBLR_CHOICES
@ -28,3 +29,17 @@ class OptionsTest(ZillionTestBase):
assert getattr(zz_options, option_name) in VBLR_CHOICES
# TODO: test validate with invalid combinations of options
class DeadEndsTest(ZillionTestBase):
def test_vanilla_dead_end_names(self) -> None:
z_world = self.multiworld.worlds[1]
assert isinstance(z_world, ZillionWorld)
for loc_name in ZillionPriorityDeadEnds.vanilla_dead_ends:
assert any(loc.name == loc_name for loc in z_world.my_locations), f"{loc_name=} {z_world.my_locations=}"
def test_always_dead_end_names(self) -> None:
z_world = self.multiworld.worlds[1]
assert isinstance(z_world, ZillionWorld)
for loc_name in ZillionPriorityDeadEnds.always_dead_ends:
assert any(loc.name == loc_name for loc in z_world.my_locations), f"{loc_name=} {z_world.my_locations=}"