Core: make early_items internal only (#1177)
Co-authored-by: beauxq <beauxq@yahoo.com>
This commit is contained in:
parent
4d79920fa6
commit
edd1fff4b7
|
@ -48,7 +48,8 @@ class MultiWorld():
|
||||||
state: CollectionState
|
state: CollectionState
|
||||||
|
|
||||||
accessibility: Dict[int, Options.Accessibility]
|
accessibility: Dict[int, Options.Accessibility]
|
||||||
early_items: Dict[int, Options.EarlyItems]
|
early_items: Dict[int, Dict[str, int]]
|
||||||
|
local_early_items: Dict[int, Dict[str, int]]
|
||||||
local_items: Dict[int, Options.LocalItems]
|
local_items: Dict[int, Options.LocalItems]
|
||||||
non_local_items: Dict[int, Options.NonLocalItems]
|
non_local_items: Dict[int, Options.NonLocalItems]
|
||||||
progression_balancing: Dict[int, Options.ProgressionBalancing]
|
progression_balancing: Dict[int, Options.ProgressionBalancing]
|
||||||
|
@ -94,6 +95,8 @@ class MultiWorld():
|
||||||
self.customitemarray = []
|
self.customitemarray = []
|
||||||
self.shuffle_ganon = True
|
self.shuffle_ganon = True
|
||||||
self.spoiler = Spoiler(self)
|
self.spoiler = Spoiler(self)
|
||||||
|
self.early_items = {player: {} for player in self.player_ids}
|
||||||
|
self.local_early_items = {player: {} for player in self.player_ids}
|
||||||
self.indirect_connections = {}
|
self.indirect_connections = {}
|
||||||
self.fix_trock_doors = self.AttributeProxy(
|
self.fix_trock_doors = self.AttributeProxy(
|
||||||
lambda player: self.shuffle[player] != 'vanilla' or self.mode[player] == 'inverted')
|
lambda player: self.shuffle[player] != 'vanilla' or self.mode[player] == 'inverted')
|
||||||
|
|
42
Fill.py
42
Fill.py
|
@ -254,14 +254,17 @@ def distribute_early_items(world: MultiWorld,
|
||||||
""" returns new fill_locations and itempool """
|
""" returns new fill_locations and itempool """
|
||||||
early_items_count: typing.Dict[typing.Tuple[str, int], int] = {}
|
early_items_count: typing.Dict[typing.Tuple[str, int], int] = {}
|
||||||
for player in world.player_ids:
|
for player in world.player_ids:
|
||||||
for item, count in world.early_items[player].value.items():
|
items = itertools.chain(world.early_items[player], world.local_early_items[player])
|
||||||
early_items_count[(item, player)] = count
|
for item in items:
|
||||||
|
early_items_count[(item, player)] = [world.early_items[player].get(item, 0), world.local_early_items[player].get(item, 0)]
|
||||||
if early_items_count:
|
if early_items_count:
|
||||||
early_locations: typing.List[Location] = []
|
early_locations: typing.List[Location] = []
|
||||||
early_priority_locations: typing.List[Location] = []
|
early_priority_locations: typing.List[Location] = []
|
||||||
loc_indexes_to_remove: typing.Set[int] = set()
|
loc_indexes_to_remove: typing.Set[int] = set()
|
||||||
|
base_state = world.state.copy()
|
||||||
|
base_state.sweep_for_events(locations=(loc for loc in world.get_filled_locations() if loc.address is None))
|
||||||
for i, loc in enumerate(fill_locations):
|
for i, loc in enumerate(fill_locations):
|
||||||
if loc.can_reach(world.state):
|
if loc.can_reach(base_state):
|
||||||
if loc.progress_type == LocationProgressType.PRIORITY:
|
if loc.progress_type == LocationProgressType.PRIORITY:
|
||||||
early_priority_locations.append(loc)
|
early_priority_locations.append(loc)
|
||||||
else:
|
else:
|
||||||
|
@ -271,27 +274,48 @@ def distribute_early_items(world: MultiWorld,
|
||||||
|
|
||||||
early_prog_items: typing.List[Item] = []
|
early_prog_items: typing.List[Item] = []
|
||||||
early_rest_items: typing.List[Item] = []
|
early_rest_items: typing.List[Item] = []
|
||||||
|
early_local_prog_items: typing.Dict[int, typing.List[Item]] = {player: [] for player in world.player_ids}
|
||||||
|
early_local_rest_items: typing.Dict[int, typing.List[Item]] = {player: [] for player in world.player_ids}
|
||||||
item_indexes_to_remove: typing.Set[int] = set()
|
item_indexes_to_remove: typing.Set[int] = set()
|
||||||
for i, item in enumerate(itempool):
|
for i, item in enumerate(itempool):
|
||||||
if (item.name, item.player) in early_items_count:
|
if (item.name, item.player) in early_items_count:
|
||||||
if item.advancement:
|
if item.advancement:
|
||||||
|
if early_items_count[(item.name, item.player)][1]:
|
||||||
|
early_local_prog_items[item.player].append(item)
|
||||||
|
early_items_count[(item.name, item.player)][1] -= 1
|
||||||
|
else:
|
||||||
early_prog_items.append(item)
|
early_prog_items.append(item)
|
||||||
|
early_items_count[(item.name, item.player)][0] -= 1
|
||||||
|
else:
|
||||||
|
if early_items_count[(item.name, item.player)][1]:
|
||||||
|
early_local_rest_items[item.player].append(item)
|
||||||
|
early_items_count[(item.name, item.player)][1] -= 1
|
||||||
else:
|
else:
|
||||||
early_rest_items.append(item)
|
early_rest_items.append(item)
|
||||||
|
early_items_count[(item.name, item.player)][0] -= 1
|
||||||
item_indexes_to_remove.add(i)
|
item_indexes_to_remove.add(i)
|
||||||
early_items_count[(item.name, item.player)] -= 1
|
if early_items_count[(item.name, item.player)] == [0, 0]:
|
||||||
if early_items_count[(item.name, item.player)] == 0:
|
|
||||||
del early_items_count[(item.name, item.player)]
|
del early_items_count[(item.name, item.player)]
|
||||||
if len(early_items_count) == 0:
|
if len(early_items_count) == 0:
|
||||||
break
|
break
|
||||||
itempool = [item for i, item in enumerate(itempool) if i not in item_indexes_to_remove]
|
itempool = [item for i, item in enumerate(itempool) if i not in item_indexes_to_remove]
|
||||||
fill_restrictive(world, world.state, early_locations, early_rest_items, lock=True)
|
for player in world.player_ids:
|
||||||
|
fill_restrictive(world, base_state,
|
||||||
|
[loc for loc in early_locations if loc.player == player],
|
||||||
|
early_local_rest_items[player], lock=True)
|
||||||
|
early_locations = [loc for loc in early_locations if not loc.item]
|
||||||
|
fill_restrictive(world, base_state, early_locations, early_rest_items, lock=True)
|
||||||
early_locations += early_priority_locations
|
early_locations += early_priority_locations
|
||||||
fill_restrictive(world, world.state, early_locations, early_prog_items, lock=True)
|
for player in world.player_ids:
|
||||||
|
fill_restrictive(world, base_state,
|
||||||
|
[loc for loc in early_locations if loc.player == player],
|
||||||
|
early_local_prog_items[player], lock=True)
|
||||||
|
early_locations = [loc for loc in early_locations if not loc.item]
|
||||||
|
fill_restrictive(world, base_state, early_locations, early_prog_items, lock=True)
|
||||||
unplaced_early_items = early_rest_items + early_prog_items
|
unplaced_early_items = early_rest_items + early_prog_items
|
||||||
if unplaced_early_items:
|
if unplaced_early_items:
|
||||||
logging.warning(f"Ran out of early locations for early items. Failed to place \
|
logging.warning("Ran out of early locations for early items. Failed to place "
|
||||||
{len(unplaced_early_items)} items early.")
|
f"{len(unplaced_early_items)} items early.")
|
||||||
itempool += unplaced_early_items
|
itempool += unplaced_early_items
|
||||||
|
|
||||||
fill_locations.extend(early_locations)
|
fill_locations.extend(early_locations)
|
||||||
|
|
|
@ -883,11 +883,6 @@ class NonLocalItems(ItemSet):
|
||||||
display_name = "Not Local Items"
|
display_name = "Not Local Items"
|
||||||
|
|
||||||
|
|
||||||
class EarlyItems(ItemDict):
|
|
||||||
"""Force the specified items to be in locations that are reachable from the start."""
|
|
||||||
display_name = "Early Items"
|
|
||||||
|
|
||||||
|
|
||||||
class StartInventory(ItemDict):
|
class StartInventory(ItemDict):
|
||||||
"""Start with these items."""
|
"""Start with these items."""
|
||||||
verify_item_name = True
|
verify_item_name = True
|
||||||
|
@ -986,7 +981,6 @@ per_game_common_options = {
|
||||||
**common_options, # can be overwritten per-game
|
**common_options, # can be overwritten per-game
|
||||||
"local_items": LocalItems,
|
"local_items": LocalItems,
|
||||||
"non_local_items": NonLocalItems,
|
"non_local_items": NonLocalItems,
|
||||||
"early_items": EarlyItems,
|
|
||||||
"start_inventory": StartInventory,
|
"start_inventory": StartInventory,
|
||||||
"start_hints": StartHints,
|
"start_hints": StartHints,
|
||||||
"start_location_hints": StartLocationHints,
|
"start_location_hints": StartLocationHints,
|
||||||
|
|
|
@ -628,9 +628,9 @@ class TestDistributeItemsRestrictive(unittest.TestCase):
|
||||||
mw = generate_multi_world(2)
|
mw = generate_multi_world(2)
|
||||||
player1 = generate_player_data(mw, 1, location_count=5, basic_item_count=5)
|
player1 = generate_player_data(mw, 1, location_count=5, basic_item_count=5)
|
||||||
player2 = generate_player_data(mw, 2, location_count=5, basic_item_count=5)
|
player2 = generate_player_data(mw, 2, location_count=5, basic_item_count=5)
|
||||||
mw.early_items[1].value[player1.basic_items[0].name] = 1
|
mw.early_items[1][player1.basic_items[0].name] = 1
|
||||||
mw.early_items[2].value[player2.basic_items[2].name] = 1
|
mw.early_items[2][player2.basic_items[2].name] = 1
|
||||||
mw.early_items[2].value[player2.basic_items[3].name] = 1
|
mw.early_items[2][player2.basic_items[3].name] = 1
|
||||||
|
|
||||||
early_items = [
|
early_items = [
|
||||||
player1.basic_items[0],
|
player1.basic_items[0],
|
||||||
|
|
|
@ -106,7 +106,7 @@ settings. If a game can be rolled it **must** have a settings section even if it
|
||||||
|
|
||||||
Some options in Archipelago can be used by every game but must still be placed within the relevant game's section.
|
Some options in Archipelago can be used by every game but must still be placed within the relevant game's section.
|
||||||
|
|
||||||
Currently, these options are `start_inventory`, `early_items`, `start_hints`, `local_items`, `non_local_items`, `start_location_hints`
|
Currently, these options are `start_inventory`, `start_hints`, `local_items`, `non_local_items`, `start_location_hints`
|
||||||
, `exclude_locations`, and various plando options.
|
, `exclude_locations`, and various plando options.
|
||||||
|
|
||||||
See the plando guide for more info on plando options. Plando
|
See the plando guide for more info on plando options. Plando
|
||||||
|
@ -115,8 +115,6 @@ guide: [Archipelago Plando Guide](/tutorial/Archipelago/plando/en)
|
||||||
* `start_inventory` will give any items defined here to you at the beginning of your game. The format for this must be
|
* `start_inventory` will give any items defined here to you at the beginning of your game. The format for this must be
|
||||||
the name as it appears in the game files and the amount you would like to start with. For example `Rupees(5): 6` which
|
the name as it appears in the game files and the amount you would like to start with. For example `Rupees(5): 6` which
|
||||||
will give you 30 rupees.
|
will give you 30 rupees.
|
||||||
* `early_items` is formatted in the same way as `start_inventory` and will force the number of each item specified to be
|
|
||||||
forced into locations that are reachable from the start, before obtaining any items.
|
|
||||||
* `start_hints` gives you free server hints for the defined item/s at the beginning of the game allowing you to hint for
|
* `start_hints` gives you free server hints for the defined item/s at the beginning of the game allowing you to hint for
|
||||||
the location without using any hint points.
|
the location without using any hint points.
|
||||||
* `local_items` will force any items you want to be in your world instead of being in another world.
|
* `local_items` will force any items you want to be in your world instead of being in another world.
|
||||||
|
@ -174,8 +172,6 @@ A Link to the Past:
|
||||||
- Quake
|
- Quake
|
||||||
non_local_items:
|
non_local_items:
|
||||||
- Moon Pearl
|
- Moon Pearl
|
||||||
early_items:
|
|
||||||
Flute: 1
|
|
||||||
start_location_hints:
|
start_location_hints:
|
||||||
- Spike Cave
|
- Spike Cave
|
||||||
priority_locations:
|
priority_locations:
|
||||||
|
@ -239,9 +235,6 @@ Timespinner:
|
||||||
* `local_items` forces the `Bombos`, `Ether`, and `Quake` medallions to all be placed within our own world, meaning we
|
* `local_items` forces the `Bombos`, `Ether`, and `Quake` medallions to all be placed within our own world, meaning we
|
||||||
have to find it ourselves.
|
have to find it ourselves.
|
||||||
* `non_local_items` forces the `Moon Pearl` to be placed in someone else's world, meaning we won't be able to find it.
|
* `non_local_items` forces the `Moon Pearl` to be placed in someone else's world, meaning we won't be able to find it.
|
||||||
* `early_items` forces the `Flute` to be placed in a location that is available from the beginning of the game ("Sphere
|
|
||||||
1"). Since it is not specified in `local_items` or `non_local_items`, it can be placed one of these locations in any
|
|
||||||
world.
|
|
||||||
* `start_location_hints` gives us a starting hint for the `Spike Cave` location available at the beginning of the
|
* `start_location_hints` gives us a starting hint for the `Spike Cave` location available at the beginning of the
|
||||||
multiworld that can be used for no cost.
|
multiworld that can be used for no cost.
|
||||||
* `priority_locations` forces a progression item to be placed on the `Link's House` location.
|
* `priority_locations` forces a progression item to be placed on the `Link's House` location.
|
||||||
|
|
|
@ -41,7 +41,6 @@ class RLWorld(World):
|
||||||
location_name_to_id = {name: data.code for name, data in location_table.items()}
|
location_name_to_id = {name: data.code for name, data in location_table.items()}
|
||||||
|
|
||||||
item_pool: List[RLItem] = []
|
item_pool: List[RLItem] = []
|
||||||
prefill_items: List[RLItem] = []
|
|
||||||
|
|
||||||
def setting(self, name: str):
|
def setting(self, name: str):
|
||||||
return getattr(self.multiworld, name)[self.player]
|
return getattr(self.multiworld, name)[self.player]
|
||||||
|
@ -50,8 +49,6 @@ class RLWorld(World):
|
||||||
return {option_name: self.setting(option_name).value for option_name in rl_options}
|
return {option_name: self.setting(option_name).value for option_name in rl_options}
|
||||||
|
|
||||||
def generate_early(self):
|
def generate_early(self):
|
||||||
self.prefill_items = []
|
|
||||||
|
|
||||||
# Check validation of names.
|
# Check validation of names.
|
||||||
additional_lady_names = len(self.setting("additional_lady_names").value)
|
additional_lady_names = len(self.setting("additional_lady_names").value)
|
||||||
additional_sir_names = len(self.setting("additional_sir_names").value)
|
additional_sir_names = len(self.setting("additional_sir_names").value)
|
||||||
|
@ -68,10 +65,11 @@ class RLWorld(World):
|
||||||
f"Expected {int(self.setting('number_of_children'))}, Got {additional_sir_names}")
|
f"Expected {int(self.setting('number_of_children'))}, Got {additional_sir_names}")
|
||||||
|
|
||||||
if self.setting("vendors") == "early":
|
if self.setting("vendors") == "early":
|
||||||
self.prefill_items += [self.create_item("Blacksmith"), self.create_item("Enchantress")]
|
self.multiworld.local_early_items[self.player]["Blacksmith"] = 1
|
||||||
|
self.multiworld.local_early_items[self.player]["Enchantress"] = 1
|
||||||
|
|
||||||
if self.setting("architect") == "early":
|
if self.setting("architect") == "early":
|
||||||
self.prefill_items += [self.create_item("Architect")]
|
self.multiworld.local_early_items[self.player]["Architect"] = 1
|
||||||
|
|
||||||
def generate_basic(self):
|
def generate_basic(self):
|
||||||
self.item_pool = []
|
self.item_pool = []
|
||||||
|
@ -83,7 +81,7 @@ class RLWorld(World):
|
||||||
|
|
||||||
# Architect
|
# Architect
|
||||||
if name == "Architect":
|
if name == "Architect":
|
||||||
if self.setting("architect") == "disabled" or self.setting("architect") == "early":
|
if self.setting("architect") == "disabled":
|
||||||
continue
|
continue
|
||||||
if self.setting("architect") == "start_unlocked":
|
if self.setting("architect") == "start_unlocked":
|
||||||
self.multiworld.push_precollected(self.create_item(name))
|
self.multiworld.push_precollected(self.create_item(name))
|
||||||
|
@ -94,8 +92,6 @@ class RLWorld(World):
|
||||||
if self.setting("vendors") == "start_unlocked":
|
if self.setting("vendors") == "start_unlocked":
|
||||||
self.multiworld.push_precollected(self.create_item(name))
|
self.multiworld.push_precollected(self.create_item(name))
|
||||||
continue
|
continue
|
||||||
if self.setting("vendors") == "early":
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Haggling
|
# Haggling
|
||||||
if name == "Haggling" and self.setting("disable_charon"):
|
if name == "Haggling" and self.setting("disable_charon"):
|
||||||
|
@ -192,21 +188,11 @@ class RLWorld(World):
|
||||||
self.item_pool += [self.create_item(name) for _ in range(0, quantity)]
|
self.item_pool += [self.create_item(name) for _ in range(0, quantity)]
|
||||||
|
|
||||||
# Fill any empty locations with filler items.
|
# Fill any empty locations with filler items.
|
||||||
while len(self.item_pool) + len(self.prefill_items) < total_locations:
|
while len(self.item_pool) < total_locations:
|
||||||
self.item_pool.append(self.create_item(self.get_filler_item_name()))
|
self.item_pool.append(self.create_item(self.get_filler_item_name()))
|
||||||
|
|
||||||
self.multiworld.itempool += self.item_pool
|
self.multiworld.itempool += self.item_pool
|
||||||
|
|
||||||
def pre_fill(self) -> None:
|
|
||||||
reachable = [loc for loc in self.multiworld.get_reachable_locations(player=self.player) if not loc.item]
|
|
||||||
self.multiworld.random.shuffle(reachable)
|
|
||||||
items = self.prefill_items.copy()
|
|
||||||
for item in items:
|
|
||||||
reachable.pop().place_locked_item(item)
|
|
||||||
|
|
||||||
def get_pre_fill_items(self) -> List[RLItem]:
|
|
||||||
return self.prefill_items
|
|
||||||
|
|
||||||
def get_filler_item_name(self) -> str:
|
def get_filler_item_name(self) -> str:
|
||||||
fillers = get_items_by_category("Filler")
|
fillers = get_items_by_category("Filler")
|
||||||
weights = [data.weight for data in fillers.values()]
|
weights = [data.weight for data in fillers.values()]
|
||||||
|
|
|
@ -127,7 +127,7 @@ class SMWorld(World):
|
||||||
self.multiworld.local_items[self.player].value.add('No Energy')
|
self.multiworld.local_items[self.player].value.add('No Energy')
|
||||||
|
|
||||||
if (self.variaRando.args.morphPlacement == "early"):
|
if (self.variaRando.args.morphPlacement == "early"):
|
||||||
self.multiworld.local_items[self.player].value.add('Morph')
|
self.multiworld.local_early_items[self.player]['Morph Ball'] = 1
|
||||||
|
|
||||||
self.remote_items = self.multiworld.remote_items[self.player]
|
self.remote_items = self.multiworld.remote_items[self.player]
|
||||||
|
|
||||||
|
@ -658,21 +658,6 @@ class SMWorld(World):
|
||||||
return "Nothing"
|
return "Nothing"
|
||||||
|
|
||||||
def pre_fill(self):
|
def pre_fill(self):
|
||||||
if (self.variaRando.args.morphPlacement == "early") and next((item for item in self.multiworld.itempool if item.player == self.player and item.name == "Morph Ball"), False):
|
|
||||||
viable = []
|
|
||||||
for location in self.multiworld.get_locations():
|
|
||||||
if location.player == self.player \
|
|
||||||
and location.item is None \
|
|
||||||
and location.can_reach(self.multiworld.state):
|
|
||||||
viable.append(location)
|
|
||||||
self.multiworld.random.shuffle(viable)
|
|
||||||
key = self.multiworld.create_item("Morph Ball", self.player)
|
|
||||||
loc = viable.pop()
|
|
||||||
loc.place_locked_item(key)
|
|
||||||
self.multiworld.itempool[:] = [item for item in self.multiworld.itempool if
|
|
||||||
item.player != self.player or
|
|
||||||
item.name != "Morph Ball"]
|
|
||||||
|
|
||||||
if len(self.NothingPool) > 0:
|
if len(self.NothingPool) > 0:
|
||||||
nonChozoLoc = []
|
nonChozoLoc = []
|
||||||
chozoLoc = []
|
chozoLoc = []
|
||||||
|
|
|
@ -47,8 +47,7 @@ class SubnauticaWorld(World):
|
||||||
creatures_to_scan: List[str]
|
creatures_to_scan: List[str]
|
||||||
|
|
||||||
def generate_early(self) -> None:
|
def generate_early(self) -> None:
|
||||||
if "Seaglide Fragment" not in self.multiworld.early_items[self.player]:
|
self.multiworld.local_early_items[self.player]["Seaglide Fragment"] = 2
|
||||||
self.multiworld.early_items[self.player].value["Seaglide Fragment"] = 2
|
|
||||||
|
|
||||||
scan_option: Options.AggressiveScanLogic = self.multiworld.creature_scan_logic[self.player]
|
scan_option: Options.AggressiveScanLogic = self.multiworld.creature_scan_logic[self.player]
|
||||||
creature_pool = scan_option.get_pool()
|
creature_pool = scan_option.get_pool()
|
||||||
|
|
|
@ -49,15 +49,6 @@ guide: [Basic Multiworld Setup Guide](/tutorial/Archipelago/setup/en)
|
||||||
The [player settings page](/games/Zillion/player-settings) on the website allows you to configure your personal settings and export a config file from
|
The [player settings page](/games/Zillion/player-settings) on the website allows you to configure your personal settings and export a config file from
|
||||||
them.
|
them.
|
||||||
|
|
||||||
### Advanced settings
|
|
||||||
|
|
||||||
The [advanced settings page](/tutorial/Archipelago/advanced_settings/en) describes more options you can put in your configuration file.
|
|
||||||
- A recommended setting for Zillion is:
|
|
||||||
```
|
|
||||||
early_items:
|
|
||||||
Scope: 1
|
|
||||||
```
|
|
||||||
|
|
||||||
### Verifying your config file
|
### Verifying your config file
|
||||||
|
|
||||||
If you would like to validate your config file to make sure it works, you may do so on the [YAML Validator page](/mysterycheck).
|
If you would like to validate your config file to make sure it works, you may do so on the [YAML Validator page](/mysterycheck).
|
||||||
|
|
|
@ -192,6 +192,11 @@ class ZillionRedIDCardCount(Range):
|
||||||
display_name = "Red ID Card count"
|
display_name = "Red ID Card count"
|
||||||
|
|
||||||
|
|
||||||
|
class ZillionEarlyScope(Toggle):
|
||||||
|
""" make sure Scope is available early """
|
||||||
|
display_name = "early scope"
|
||||||
|
|
||||||
|
|
||||||
class ZillionSkill(Range):
|
class ZillionSkill(Range):
|
||||||
""" the difficulty level of the game """
|
""" the difficulty level of the game """
|
||||||
range_start = 0
|
range_start = 0
|
||||||
|
@ -236,6 +241,7 @@ zillion_options: Dict[str, AssembleOptions] = {
|
||||||
"floppy_disk_count": ZillionFloppyDiskCount,
|
"floppy_disk_count": ZillionFloppyDiskCount,
|
||||||
"scope_count": ZillionScopeCount,
|
"scope_count": ZillionScopeCount,
|
||||||
"red_id_card_count": ZillionRedIDCardCount,
|
"red_id_card_count": ZillionRedIDCardCount,
|
||||||
|
"early_scope": ZillionEarlyScope,
|
||||||
"skill": ZillionSkill,
|
"skill": ZillionSkill,
|
||||||
"starting_cards": ZillionStartingCards,
|
"starting_cards": ZillionStartingCards,
|
||||||
"room_gen": ZillionRoomGen,
|
"room_gen": ZillionRoomGen,
|
||||||
|
@ -352,6 +358,10 @@ def validate(world: "MultiWorld", p: int) -> "Tuple[ZzOptions, Counter[str]]":
|
||||||
|
|
||||||
room_gen = cast(ZillionRoomGen, wo.room_gen[p])
|
room_gen = cast(ZillionRoomGen, wo.room_gen[p])
|
||||||
|
|
||||||
|
early_scope = cast(ZillionEarlyScope, wo.early_scope[p])
|
||||||
|
if early_scope:
|
||||||
|
world.early_items[p]["Scope"] = 1
|
||||||
|
|
||||||
zz_item_counts = convert_item_counts(item_counts)
|
zz_item_counts = convert_item_counts(item_counts)
|
||||||
zz_op = ZzOptions(
|
zz_op = ZzOptions(
|
||||||
zz_item_counts,
|
zz_item_counts,
|
||||||
|
@ -365,7 +375,7 @@ def validate(world: "MultiWorld", p: int) -> "Tuple[ZzOptions, Counter[str]]":
|
||||||
floppy_req.value,
|
floppy_req.value,
|
||||||
wo.continues[p].value,
|
wo.continues[p].value,
|
||||||
wo.randomize_alarms[p].value,
|
wo.randomize_alarms[p].value,
|
||||||
False, # early scope can be done with AP early_items
|
False, # early scope is done with AP early_items API
|
||||||
True, # balance defense
|
True, # balance defense
|
||||||
starting_cards.value,
|
starting_cards.value,
|
||||||
bool(room_gen.value)
|
bool(room_gen.value)
|
||||||
|
|
Loading…
Reference in New Issue