mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-03-29 15:23:21 -07:00
Merge remote-tracking branch 'refs/remotes/origin/main' into tunc-portal-direction-pairing
# Conflicts: # worlds/tunic/__init__.py # worlds/tunic/er_rules.py # worlds/tunic/rules.py
This commit is contained in:
@@ -863,19 +863,15 @@ class CollectionState():
|
||||
)
|
||||
|
||||
# Item related
|
||||
def collect(self, item: Item, event: bool = False, location: Optional[Location] = None) -> bool:
|
||||
def collect(self, item: Item, prevent_sweep: bool = False, location: Optional[Location] = None) -> bool:
|
||||
if location:
|
||||
self.locations_checked.add(location)
|
||||
|
||||
changed = self.multiworld.worlds[item.player].collect(self, item)
|
||||
|
||||
if not changed and event:
|
||||
self.prog_items[item.player][item.name] += 1
|
||||
changed = True
|
||||
|
||||
self.stale[item.player] = True
|
||||
|
||||
if changed and not event:
|
||||
if changed and not prevent_sweep:
|
||||
self.sweep_for_events()
|
||||
|
||||
return changed
|
||||
@@ -1427,7 +1423,7 @@ class Spoiler:
|
||||
# Maybe move the big bomb over to the Event system instead?
|
||||
if any(exit_path == 'Pyramid Fairy' for path in self.paths.values()
|
||||
for (_, exit_path) in path):
|
||||
if multiworld.mode[player] != 'inverted':
|
||||
if multiworld.worlds[player].options.mode != 'inverted':
|
||||
self.paths[str(multiworld.get_region('Big Bomb Shop', player))] = \
|
||||
get_path(state, multiworld.get_region('Big Bomb Shop', player))
|
||||
else:
|
||||
|
||||
19
Fill.py
19
Fill.py
@@ -12,7 +12,12 @@ from worlds.generic.Rules import add_item_rule
|
||||
|
||||
|
||||
class FillError(RuntimeError):
|
||||
pass
|
||||
def __init__(self, *args: typing.Union[str, typing.Any], **kwargs) -> None:
|
||||
if "multiworld" in kwargs and isinstance(args[0], str):
|
||||
placements = (args[0] + f"\nAll Placements:\n" +
|
||||
f"{[(loc, loc.item) for loc in kwargs['multiworld'].get_filled_locations()]}")
|
||||
args = (placements, *args[1:])
|
||||
super().__init__(*args)
|
||||
|
||||
|
||||
def _log_fill_progress(name: str, placed: int, total_items: int) -> None:
|
||||
@@ -212,7 +217,7 @@ def fill_restrictive(multiworld: MultiWorld, base_state: CollectionState, locati
|
||||
f"Unfilled locations:\n"
|
||||
f"{', '.join(str(location) for location in locations)}\n"
|
||||
f"Already placed {len(placements)}:\n"
|
||||
f"{', '.join(str(place) for place in placements)}")
|
||||
f"{', '.join(str(place) for place in placements)}", multiworld=multiworld)
|
||||
|
||||
item_pool.extend(unplaced_items)
|
||||
|
||||
@@ -299,7 +304,7 @@ def remaining_fill(multiworld: MultiWorld,
|
||||
f"Unfilled locations:\n"
|
||||
f"{', '.join(str(location) for location in locations)}\n"
|
||||
f"Already placed {len(placements)}:\n"
|
||||
f"{', '.join(str(place) for place in placements)}")
|
||||
f"{', '.join(str(place) for place in placements)}", multiworld=multiworld)
|
||||
|
||||
itempool.extend(unplaced_items)
|
||||
|
||||
@@ -506,7 +511,8 @@ def distribute_items_restrictive(multiworld: MultiWorld,
|
||||
if progitempool:
|
||||
raise FillError(
|
||||
f"Not enough locations for progression items. "
|
||||
f"There are {len(progitempool)} more progression items than there are available locations."
|
||||
f"There are {len(progitempool)} more progression items than there are available locations.",
|
||||
multiworld=multiworld,
|
||||
)
|
||||
accessibility_corrections(multiworld, multiworld.state, defaultlocations)
|
||||
|
||||
@@ -523,7 +529,8 @@ def distribute_items_restrictive(multiworld: MultiWorld,
|
||||
if excludedlocations:
|
||||
raise FillError(
|
||||
f"Not enough filler items for excluded locations. "
|
||||
f"There are {len(excludedlocations)} more excluded locations than filler or trap items."
|
||||
f"There are {len(excludedlocations)} more excluded locations than filler or trap items.",
|
||||
multiworld=multiworld,
|
||||
)
|
||||
|
||||
restitempool = filleritempool + usefulitempool
|
||||
@@ -589,7 +596,7 @@ def flood_items(multiworld: MultiWorld) -> None:
|
||||
if candidate_item_to_place is not None:
|
||||
item_to_place = candidate_item_to_place
|
||||
else:
|
||||
raise FillError('No more progress items left to place.')
|
||||
raise FillError('No more progress items left to place.', multiworld=multiworld)
|
||||
|
||||
# find item to replace with progress item
|
||||
location_list = multiworld.get_reachable_locations()
|
||||
|
||||
@@ -266,7 +266,7 @@ def run_gui():
|
||||
if file and component:
|
||||
run_component(component, file)
|
||||
else:
|
||||
logging.warning(f"unable to identify component for {filename}")
|
||||
logging.warning(f"unable to identify component for {file}")
|
||||
|
||||
def _stop(self, *largs):
|
||||
# ran into what appears to be https://groups.google.com/g/kivy-users/c/saWDLoYCSZ4 with PyCharm.
|
||||
|
||||
20
Main.py
20
Main.py
@@ -11,7 +11,8 @@ from typing import Dict, List, Optional, Set, Tuple, Union
|
||||
|
||||
import worlds
|
||||
from BaseClasses import CollectionState, Item, Location, LocationProgressType, MultiWorld, Region
|
||||
from Fill import balance_multiworld_progression, distribute_items_restrictive, distribute_planned, flood_items
|
||||
from Fill import FillError, balance_multiworld_progression, distribute_items_restrictive, distribute_planned, \
|
||||
flood_items
|
||||
from Options import StartInventoryPool
|
||||
from Utils import __version__, output_path, version_tuple, get_settings
|
||||
from settings import get_settings
|
||||
@@ -151,6 +152,7 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No
|
||||
# Because some worlds don't actually create items during create_items this has to be as late as possible.
|
||||
if any(getattr(multiworld.worlds[player].options, "start_inventory_from_pool", None) for player in multiworld.player_ids):
|
||||
new_items: List[Item] = []
|
||||
old_items: List[Item] = []
|
||||
depletion_pool: Dict[int, Dict[str, int]] = {
|
||||
player: getattr(multiworld.worlds[player].options,
|
||||
"start_inventory_from_pool",
|
||||
@@ -169,20 +171,24 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No
|
||||
depletion_pool[item.player][item.name] -= 1
|
||||
# quick abort if we have found all items
|
||||
if not target:
|
||||
new_items.extend(multiworld.itempool[i+1:])
|
||||
old_items.extend(multiworld.itempool[i+1:])
|
||||
break
|
||||
else:
|
||||
new_items.append(item)
|
||||
old_items.append(item)
|
||||
|
||||
# leftovers?
|
||||
if target:
|
||||
for player, remaining_items in depletion_pool.items():
|
||||
remaining_items = {name: count for name, count in remaining_items.items() if count}
|
||||
if remaining_items:
|
||||
raise Exception(f"{multiworld.get_player_name(player)}"
|
||||
logger.warning(f"{multiworld.get_player_name(player)}"
|
||||
f" is trying to remove items from their pool that don't exist: {remaining_items}")
|
||||
assert len(multiworld.itempool) == len(new_items), "Item Pool amounts should not change."
|
||||
multiworld.itempool[:] = new_items
|
||||
# find all filler we generated for the current player and remove until it matches
|
||||
removables = [item for item in new_items if item.player == player]
|
||||
for _ in range(sum(remaining_items.values())):
|
||||
new_items.remove(removables.pop())
|
||||
assert len(multiworld.itempool) == len(new_items + old_items), "Item Pool amounts should not change."
|
||||
multiworld.itempool[:] = new_items + old_items
|
||||
|
||||
multiworld.link_items()
|
||||
|
||||
@@ -341,7 +347,7 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No
|
||||
output_file_futures.append(pool.submit(write_multidata))
|
||||
if not check_accessibility_task.result():
|
||||
if not multiworld.can_beat_game():
|
||||
raise Exception("Game appears as unbeatable. Aborting.")
|
||||
raise FillError("Game appears as unbeatable. Aborting.", multiworld=multiworld)
|
||||
else:
|
||||
logger.warning("Location Accessibility requirements not fulfilled.")
|
||||
|
||||
|
||||
29
Options.py
29
Options.py
@@ -1236,6 +1236,7 @@ class CommonOptions(metaclass=OptionsMetaProperty):
|
||||
:param option_names: names of the options to return
|
||||
:param casing: case of the keys to return. Supports `snake`, `camel`, `pascal`, `kebab`
|
||||
"""
|
||||
assert option_names, "options.as_dict() was used without any option names."
|
||||
option_results = {}
|
||||
for option_name in option_names:
|
||||
if option_name in type(self).type_hints:
|
||||
@@ -1517,31 +1518,3 @@ def generate_yaml_templates(target_folder: typing.Union[str, "pathlib.Path"], ge
|
||||
|
||||
with open(os.path.join(target_folder, game_name + ".yaml"), "w", encoding="utf-8-sig") as f:
|
||||
f.write(res)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
from worlds.alttp.Options import Logic
|
||||
import argparse
|
||||
|
||||
map_shuffle = Toggle
|
||||
compass_shuffle = Toggle
|
||||
key_shuffle = Toggle
|
||||
big_key_shuffle = Toggle
|
||||
hints = Toggle
|
||||
test = argparse.Namespace()
|
||||
test.logic = Logic.from_text("no_logic")
|
||||
test.map_shuffle = map_shuffle.from_text("ON")
|
||||
test.hints = hints.from_text('OFF')
|
||||
try:
|
||||
test.logic = Logic.from_text("overworld_glitches_typo")
|
||||
except KeyError as e:
|
||||
print(e)
|
||||
try:
|
||||
test.logic_owg = Logic.from_text("owg")
|
||||
except KeyError as e:
|
||||
print(e)
|
||||
if test.map_shuffle:
|
||||
print("map_shuffle is on")
|
||||
print(f"Hints are {bool(test.hints)}")
|
||||
print(test)
|
||||
|
||||
@@ -23,7 +23,7 @@ class TestBase(unittest.TestCase):
|
||||
state = CollectionState(self.multiworld)
|
||||
for item in items:
|
||||
item.classification = ItemClassification.progression
|
||||
state.collect(item, event=True)
|
||||
state.collect(item, prevent_sweep=True)
|
||||
state.sweep_for_events()
|
||||
state.update_reachable_regions(1)
|
||||
self._state_cache[self.multiworld, tuple(items)] = state
|
||||
|
||||
@@ -55,7 +55,7 @@ class TestAllGamesMultiworld(MultiworldTestBase):
|
||||
all_worlds = list(AutoWorldRegister.world_types.values())
|
||||
self.multiworld = setup_multiworld(all_worlds, ())
|
||||
for world in self.multiworld.worlds.values():
|
||||
world.options.accessibility.value = Accessibility.option_locations
|
||||
world.options.accessibility.value = Accessibility.option_full
|
||||
self.assertSteps(gen_steps)
|
||||
with self.subTest("filling multiworld", seed=self.multiworld.seed):
|
||||
distribute_items_restrictive(self.multiworld)
|
||||
@@ -66,8 +66,8 @@ class TestAllGamesMultiworld(MultiworldTestBase):
|
||||
class TestTwoPlayerMulti(MultiworldTestBase):
|
||||
def test_two_player_single_game_fills(self) -> None:
|
||||
"""Tests that a multiworld of two players for each registered game world can generate."""
|
||||
for world in AutoWorldRegister.world_types.values():
|
||||
self.multiworld = setup_multiworld([world, world], ())
|
||||
for world_type in AutoWorldRegister.world_types.values():
|
||||
self.multiworld = setup_multiworld([world_type, world_type], ())
|
||||
for world in self.multiworld.worlds.values():
|
||||
world.options.accessibility.value = Accessibility.option_full
|
||||
self.assertSteps(gen_steps)
|
||||
|
||||
@@ -54,7 +54,7 @@ class TestDungeon(LTTPTestBase):
|
||||
|
||||
for item in items:
|
||||
item.classification = ItemClassification.progression
|
||||
state.collect(item, event=True) # event=True prevents running sweep_for_events() and picking up
|
||||
state.collect(item, prevent_sweep=True) # prevent_sweep=True prevents running sweep_for_events() and picking up
|
||||
state.sweep_for_events() # key drop keys repeatedly
|
||||
|
||||
self.assertEqual(self.multiworld.get_location(location, 1).can_reach(state), access, f"failed {self.multiworld.get_location(location, 1)} with: {item_pool}")
|
||||
self.assertEqual(self.multiworld.get_location(location, 1).can_reach(state), access, f"failed {self.multiworld.get_location(location, 1)} with: {item_pool}")
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
from typing import Callable, Dict, NamedTuple, Optional
|
||||
from typing import Callable, Dict, NamedTuple, Optional, TYPE_CHECKING
|
||||
|
||||
from BaseClasses import Item, ItemClassification, MultiWorld
|
||||
from BaseClasses import Item, ItemClassification
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from . import CliqueWorld
|
||||
|
||||
|
||||
class CliqueItem(Item):
|
||||
@@ -10,7 +13,7 @@ class CliqueItem(Item):
|
||||
class CliqueItemData(NamedTuple):
|
||||
code: Optional[int] = None
|
||||
type: ItemClassification = ItemClassification.filler
|
||||
can_create: Callable[[MultiWorld, int], bool] = lambda multiworld, player: True
|
||||
can_create: Callable[["CliqueWorld"], bool] = lambda world: True
|
||||
|
||||
|
||||
item_data_table: Dict[str, CliqueItemData] = {
|
||||
@@ -21,11 +24,11 @@ item_data_table: Dict[str, CliqueItemData] = {
|
||||
"Button Activation": CliqueItemData(
|
||||
code=69696968,
|
||||
type=ItemClassification.progression,
|
||||
can_create=lambda multiworld, player: bool(getattr(multiworld, "hard_mode")[player]),
|
||||
can_create=lambda world: world.options.hard_mode,
|
||||
),
|
||||
"A Cool Filler Item (No Satisfaction Guaranteed)": CliqueItemData(
|
||||
code=69696967,
|
||||
can_create=lambda multiworld, player: False # Only created from `get_filler_item_name`.
|
||||
can_create=lambda world: False # Only created from `get_filler_item_name`.
|
||||
),
|
||||
"The Urge to Push": CliqueItemData(
|
||||
type=ItemClassification.progression,
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
from typing import Callable, Dict, NamedTuple, Optional
|
||||
from typing import Callable, Dict, NamedTuple, Optional, TYPE_CHECKING
|
||||
|
||||
from BaseClasses import Location, MultiWorld
|
||||
from BaseClasses import Location
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from . import CliqueWorld
|
||||
|
||||
|
||||
class CliqueLocation(Location):
|
||||
@@ -10,7 +13,7 @@ class CliqueLocation(Location):
|
||||
class CliqueLocationData(NamedTuple):
|
||||
region: str
|
||||
address: Optional[int] = None
|
||||
can_create: Callable[[MultiWorld, int], bool] = lambda multiworld, player: True
|
||||
can_create: Callable[["CliqueWorld"], bool] = lambda world: True
|
||||
locked_item: Optional[str] = None
|
||||
|
||||
|
||||
@@ -22,7 +25,7 @@ location_data_table: Dict[str, CliqueLocationData] = {
|
||||
"The Item on the Desk": CliqueLocationData(
|
||||
region="The Button Realm",
|
||||
address=69696968,
|
||||
can_create=lambda multiworld, player: bool(getattr(multiworld, "hard_mode")[player]),
|
||||
can_create=lambda world: world.options.hard_mode,
|
||||
),
|
||||
"In the Player's Mind": CliqueLocationData(
|
||||
region="The Button Realm",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from typing import Dict
|
||||
|
||||
from Options import Choice, Option, Toggle
|
||||
from dataclasses import dataclass
|
||||
from Options import Choice, Toggle, PerGameCommonOptions, StartInventoryPool
|
||||
|
||||
|
||||
class HardMode(Toggle):
|
||||
@@ -25,10 +24,11 @@ class ButtonColor(Choice):
|
||||
option_black = 11
|
||||
|
||||
|
||||
clique_options: Dict[str, type(Option)] = {
|
||||
"color": ButtonColor,
|
||||
"hard_mode": HardMode,
|
||||
@dataclass
|
||||
class CliqueOptions(PerGameCommonOptions):
|
||||
color: ButtonColor
|
||||
hard_mode: HardMode
|
||||
start_inventory_from_pool: StartInventoryPool
|
||||
|
||||
# DeathLink is always on. Always.
|
||||
# "death_link": DeathLink,
|
||||
}
|
||||
# death_link: DeathLink
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
from typing import Callable
|
||||
from typing import Callable, TYPE_CHECKING
|
||||
|
||||
from BaseClasses import CollectionState, MultiWorld
|
||||
from BaseClasses import CollectionState
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from . import CliqueWorld
|
||||
|
||||
|
||||
def get_button_rule(multiworld: MultiWorld, player: int) -> Callable[[CollectionState], bool]:
|
||||
if getattr(multiworld, "hard_mode")[player]:
|
||||
return lambda state: state.has("Button Activation", player)
|
||||
def get_button_rule(world: "CliqueWorld") -> Callable[[CollectionState], bool]:
|
||||
if world.options.hard_mode:
|
||||
return lambda state: state.has("Button Activation", world.player)
|
||||
|
||||
return lambda state: True
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
from typing import List
|
||||
from typing import List, Dict, Any
|
||||
|
||||
from BaseClasses import Region, Tutorial
|
||||
from worlds.AutoWorld import WebWorld, World
|
||||
from .Items import CliqueItem, item_data_table, item_table
|
||||
from .Locations import CliqueLocation, location_data_table, location_table, locked_locations
|
||||
from .Options import clique_options
|
||||
from .Options import CliqueOptions
|
||||
from .Regions import region_data_table
|
||||
from .Rules import get_button_rule
|
||||
|
||||
@@ -38,7 +38,8 @@ class CliqueWorld(World):
|
||||
|
||||
game = "Clique"
|
||||
web = CliqueWebWorld()
|
||||
option_definitions = clique_options
|
||||
options: CliqueOptions
|
||||
options_dataclass = CliqueOptions
|
||||
location_name_to_id = location_table
|
||||
item_name_to_id = item_table
|
||||
|
||||
@@ -48,7 +49,7 @@ class CliqueWorld(World):
|
||||
def create_items(self) -> None:
|
||||
item_pool: List[CliqueItem] = []
|
||||
for name, item in item_data_table.items():
|
||||
if item.code and item.can_create(self.multiworld, self.player):
|
||||
if item.code and item.can_create(self):
|
||||
item_pool.append(self.create_item(name))
|
||||
|
||||
self.multiworld.itempool += item_pool
|
||||
@@ -61,41 +62,40 @@ class CliqueWorld(World):
|
||||
|
||||
# Create locations.
|
||||
for region_name, region_data in region_data_table.items():
|
||||
region = self.multiworld.get_region(region_name, self.player)
|
||||
region = self.get_region(region_name)
|
||||
region.add_locations({
|
||||
location_name: location_data.address for location_name, location_data in location_data_table.items()
|
||||
if location_data.region == region_name and location_data.can_create(self.multiworld, self.player)
|
||||
if location_data.region == region_name and location_data.can_create(self)
|
||||
}, CliqueLocation)
|
||||
region.add_exits(region_data_table[region_name].connecting_regions)
|
||||
|
||||
# Place locked locations.
|
||||
for location_name, location_data in locked_locations.items():
|
||||
# Ignore locations we never created.
|
||||
if not location_data.can_create(self.multiworld, self.player):
|
||||
if not location_data.can_create(self):
|
||||
continue
|
||||
|
||||
locked_item = self.create_item(location_data_table[location_name].locked_item)
|
||||
self.multiworld.get_location(location_name, self.player).place_locked_item(locked_item)
|
||||
self.get_location(location_name).place_locked_item(locked_item)
|
||||
|
||||
# Set priority location for the Big Red Button!
|
||||
self.multiworld.priority_locations[self.player].value.add("The Big Red Button")
|
||||
self.options.priority_locations.value.add("The Big Red Button")
|
||||
|
||||
def get_filler_item_name(self) -> str:
|
||||
return "A Cool Filler Item (No Satisfaction Guaranteed)"
|
||||
|
||||
def set_rules(self) -> None:
|
||||
button_rule = get_button_rule(self.multiworld, self.player)
|
||||
self.multiworld.get_location("The Big Red Button", self.player).access_rule = button_rule
|
||||
self.multiworld.get_location("In the Player's Mind", self.player).access_rule = button_rule
|
||||
button_rule = get_button_rule(self)
|
||||
self.get_location("The Big Red Button").access_rule = button_rule
|
||||
self.get_location("In the Player's Mind").access_rule = button_rule
|
||||
|
||||
# Do not allow button activations on buttons.
|
||||
self.multiworld.get_location("The Big Red Button", self.player).item_rule =\
|
||||
lambda item: item.name != "Button Activation"
|
||||
self.get_location("The Big Red Button").item_rule = lambda item: item.name != "Button Activation"
|
||||
|
||||
# Completion condition.
|
||||
self.multiworld.completion_condition[self.player] = lambda state: state.has("The Urge to Push", self.player)
|
||||
|
||||
def fill_slot_data(self):
|
||||
def fill_slot_data(self) -> Dict[str, Any]:
|
||||
return {
|
||||
"color": getattr(self.multiworld, "color")[self.player].current_key
|
||||
"color": self.options.color.current_key
|
||||
}
|
||||
|
||||
@@ -796,7 +796,7 @@ def validate_world(ootworld, entrance_placed, locations_to_ensure_reachable, all
|
||||
|
||||
if ootworld.shuffle_interior_entrances or ootworld.shuffle_overworld_entrances or ootworld.spawn_positions:
|
||||
time_travel_state = none_state.copy()
|
||||
time_travel_state.collect(ootworld.create_item('Time Travel'), event=True)
|
||||
time_travel_state.collect(ootworld.create_item('Time Travel'), prevent_sweep=True)
|
||||
time_travel_state._oot_update_age_reachable_regions(player)
|
||||
|
||||
# Unless entrances are decoupled, we don't want the player to end up through certain entrances as the wrong age
|
||||
|
||||
@@ -1388,7 +1388,7 @@ class OOTWorld(World):
|
||||
self.multiworld.worlds[item.player].collect(all_state, item)
|
||||
# If free_scarecrow give Scarecrow Song
|
||||
if self.free_scarecrow:
|
||||
all_state.collect(self.create_item("Scarecrow Song"), event=True)
|
||||
all_state.collect(self.create_item("Scarecrow Song"), prevent_sweep=True)
|
||||
all_state.stale[self.player] = True
|
||||
|
||||
return all_state
|
||||
|
||||
@@ -11,10 +11,10 @@ class TestCropsanityRules(SVTestBase):
|
||||
harvest_cactus = self.world.logic.region.can_reach_location("Harvest Cactus Fruit")
|
||||
self.assert_rule_false(harvest_cactus, self.multiworld.state)
|
||||
|
||||
self.multiworld.state.collect(self.world.create_item("Cactus Seeds"), event=False)
|
||||
self.multiworld.state.collect(self.world.create_item("Shipping Bin"), event=False)
|
||||
self.multiworld.state.collect(self.world.create_item("Desert Obelisk"), event=False)
|
||||
self.multiworld.state.collect(self.world.create_item("Cactus Seeds"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.world.create_item("Shipping Bin"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.world.create_item("Desert Obelisk"), prevent_sweep=False)
|
||||
self.assert_rule_false(harvest_cactus, self.multiworld.state)
|
||||
|
||||
self.multiworld.state.collect(self.world.create_item("Greenhouse"), event=False)
|
||||
self.multiworld.state.collect(self.world.create_item("Greenhouse"), prevent_sweep=False)
|
||||
self.assert_rule_true(harvest_cactus, self.multiworld.state)
|
||||
|
||||
@@ -12,29 +12,29 @@ from ..strings.wallet_item_names import Wallet
|
||||
|
||||
def collect_fishing_abilities(tester: SVTestBase):
|
||||
for i in range(4):
|
||||
tester.multiworld.state.collect(tester.world.create_item(APTool.fishing_rod), event=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item(APTool.pickaxe), event=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item(APTool.axe), event=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item(APWeapon.weapon), event=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item(APTool.fishing_rod), prevent_sweep=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item(APTool.pickaxe), prevent_sweep=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item(APTool.axe), prevent_sweep=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item(APWeapon.weapon), prevent_sweep=False)
|
||||
for i in range(10):
|
||||
tester.multiworld.state.collect(tester.world.create_item("Fishing Level"), event=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Combat Level"), event=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Mining Level"), event=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Fishing Level"), prevent_sweep=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Combat Level"), prevent_sweep=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Mining Level"), prevent_sweep=False)
|
||||
for i in range(17):
|
||||
tester.multiworld.state.collect(tester.world.create_item("Progressive Mine Elevator"), event=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Spring"), event=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Summer"), event=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Fall"), event=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Winter"), event=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item(Transportation.desert_obelisk), event=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Railroad Boulder Removed"), event=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Island North Turtle"), event=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Island West Turtle"), event=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Progressive Mine Elevator"), prevent_sweep=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Spring"), prevent_sweep=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Summer"), prevent_sweep=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Fall"), prevent_sweep=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Winter"), prevent_sweep=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item(Transportation.desert_obelisk), prevent_sweep=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Railroad Boulder Removed"), prevent_sweep=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Island North Turtle"), prevent_sweep=False)
|
||||
tester.multiworld.state.collect(tester.world.create_item("Island West Turtle"), prevent_sweep=False)
|
||||
|
||||
|
||||
def create_and_collect(tester: SVTestBase, item_name: str) -> StardewItem:
|
||||
item = tester.world.create_item(item_name)
|
||||
tester.multiworld.state.collect(item, event=False)
|
||||
tester.multiworld.state.collect(item, prevent_sweep=False)
|
||||
return item
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ from ..options import BundleRandomization
|
||||
|
||||
def collect_all(mw):
|
||||
for item in mw.get_items():
|
||||
mw.state.collect(item, event=True)
|
||||
mw.state.collect(item, prevent_sweep=True)
|
||||
|
||||
|
||||
class LogicTestBase(RuleAssertMixin, TestCase):
|
||||
|
||||
@@ -257,16 +257,16 @@ class SVTestBase(RuleAssertMixin, WorldTestBase, SVTestCase):
|
||||
return super().run_default_tests
|
||||
|
||||
def collect_lots_of_money(self):
|
||||
self.multiworld.state.collect(self.world.create_item("Shipping Bin"), event=False)
|
||||
self.multiworld.state.collect(self.world.create_item("Shipping Bin"), prevent_sweep=False)
|
||||
required_prog_items = int(round(self.multiworld.worlds[self.player].total_progression_items * 0.25))
|
||||
for i in range(required_prog_items):
|
||||
self.multiworld.state.collect(self.world.create_item("Stardrop"), event=False)
|
||||
self.multiworld.state.collect(self.world.create_item("Stardrop"), prevent_sweep=False)
|
||||
|
||||
def collect_all_the_money(self):
|
||||
self.multiworld.state.collect(self.world.create_item("Shipping Bin"), event=False)
|
||||
self.multiworld.state.collect(self.world.create_item("Shipping Bin"), prevent_sweep=False)
|
||||
required_prog_items = int(round(self.multiworld.worlds[self.player].total_progression_items * 0.95))
|
||||
for i in range(required_prog_items):
|
||||
self.multiworld.state.collect(self.world.create_item("Stardrop"), event=False)
|
||||
self.multiworld.state.collect(self.world.create_item("Stardrop"), prevent_sweep=False)
|
||||
|
||||
def collect_everything(self):
|
||||
non_event_items = [item for item in self.multiworld.get_items() if item.code]
|
||||
|
||||
@@ -33,14 +33,14 @@ class WorldAssertMixin(RuleAssertMixin, TestCase):
|
||||
self.assert_can_reach_victory(multiworld)
|
||||
multiworld.state.remove(item)
|
||||
self.assert_cannot_reach_victory(multiworld)
|
||||
multiworld.state.collect(item, event=False)
|
||||
multiworld.state.collect(item, prevent_sweep=False)
|
||||
self.assert_can_reach_victory(multiworld)
|
||||
|
||||
def assert_item_was_not_necessary_for_victory(self, item: StardewItem, multiworld: MultiWorld):
|
||||
self.assert_can_reach_victory(multiworld)
|
||||
multiworld.state.remove(item)
|
||||
self.assert_can_reach_victory(multiworld)
|
||||
multiworld.state.collect(item, event=False)
|
||||
multiworld.state.collect(item, prevent_sweep=False)
|
||||
self.assert_can_reach_victory(multiworld)
|
||||
|
||||
def assert_can_win(self, multiworld: MultiWorld):
|
||||
|
||||
@@ -19,8 +19,8 @@ class TestArcadeMachinesLogic(SVTestBase):
|
||||
life = self.create_item("JotPK: Extra Life")
|
||||
drop = self.create_item("JotPK: Increased Drop Rate")
|
||||
|
||||
self.multiworld.state.collect(boots, event=True)
|
||||
self.multiworld.state.collect(gun, event=True)
|
||||
self.multiworld.state.collect(boots, prevent_sweep=True)
|
||||
self.multiworld.state.collect(gun, prevent_sweep=True)
|
||||
self.assertTrue(self.world.logic.region.can_reach("JotPK World 1")(self.multiworld.state))
|
||||
self.assertFalse(self.world.logic.region.can_reach("JotPK World 2")(self.multiworld.state))
|
||||
self.assertFalse(self.world.logic.region.can_reach("JotPK World 3")(self.multiworld.state))
|
||||
@@ -28,8 +28,8 @@ class TestArcadeMachinesLogic(SVTestBase):
|
||||
self.remove(boots)
|
||||
self.remove(gun)
|
||||
|
||||
self.multiworld.state.collect(boots, event=True)
|
||||
self.multiworld.state.collect(boots, event=True)
|
||||
self.multiworld.state.collect(boots, prevent_sweep=True)
|
||||
self.multiworld.state.collect(boots, prevent_sweep=True)
|
||||
self.assertTrue(self.world.logic.region.can_reach("JotPK World 1")(self.multiworld.state))
|
||||
self.assertFalse(self.world.logic.region.can_reach("JotPK World 2")(self.multiworld.state))
|
||||
self.assertFalse(self.world.logic.region.can_reach("JotPK World 3")(self.multiworld.state))
|
||||
@@ -37,10 +37,10 @@ class TestArcadeMachinesLogic(SVTestBase):
|
||||
self.remove(boots)
|
||||
self.remove(boots)
|
||||
|
||||
self.multiworld.state.collect(boots, event=True)
|
||||
self.multiworld.state.collect(gun, event=True)
|
||||
self.multiworld.state.collect(ammo, event=True)
|
||||
self.multiworld.state.collect(life, event=True)
|
||||
self.multiworld.state.collect(boots, prevent_sweep=True)
|
||||
self.multiworld.state.collect(gun, prevent_sweep=True)
|
||||
self.multiworld.state.collect(ammo, prevent_sweep=True)
|
||||
self.multiworld.state.collect(life, prevent_sweep=True)
|
||||
self.assertTrue(self.world.logic.region.can_reach("JotPK World 1")(self.multiworld.state))
|
||||
self.assertTrue(self.world.logic.region.can_reach("JotPK World 2")(self.multiworld.state))
|
||||
self.assertFalse(self.world.logic.region.can_reach("JotPK World 3")(self.multiworld.state))
|
||||
@@ -50,13 +50,13 @@ class TestArcadeMachinesLogic(SVTestBase):
|
||||
self.remove(ammo)
|
||||
self.remove(life)
|
||||
|
||||
self.multiworld.state.collect(boots, event=True)
|
||||
self.multiworld.state.collect(gun, event=True)
|
||||
self.multiworld.state.collect(gun, event=True)
|
||||
self.multiworld.state.collect(ammo, event=True)
|
||||
self.multiworld.state.collect(ammo, event=True)
|
||||
self.multiworld.state.collect(life, event=True)
|
||||
self.multiworld.state.collect(drop, event=True)
|
||||
self.multiworld.state.collect(boots, prevent_sweep=True)
|
||||
self.multiworld.state.collect(gun, prevent_sweep=True)
|
||||
self.multiworld.state.collect(gun, prevent_sweep=True)
|
||||
self.multiworld.state.collect(ammo, prevent_sweep=True)
|
||||
self.multiworld.state.collect(ammo, prevent_sweep=True)
|
||||
self.multiworld.state.collect(life, prevent_sweep=True)
|
||||
self.multiworld.state.collect(drop, prevent_sweep=True)
|
||||
self.assertTrue(self.world.logic.region.can_reach("JotPK World 1")(self.multiworld.state))
|
||||
self.assertTrue(self.world.logic.region.can_reach("JotPK World 2")(self.multiworld.state))
|
||||
self.assertTrue(self.world.logic.region.can_reach("JotPK World 3")(self.multiworld.state))
|
||||
@@ -69,17 +69,17 @@ class TestArcadeMachinesLogic(SVTestBase):
|
||||
self.remove(life)
|
||||
self.remove(drop)
|
||||
|
||||
self.multiworld.state.collect(boots, event=True)
|
||||
self.multiworld.state.collect(boots, event=True)
|
||||
self.multiworld.state.collect(gun, event=True)
|
||||
self.multiworld.state.collect(gun, event=True)
|
||||
self.multiworld.state.collect(gun, event=True)
|
||||
self.multiworld.state.collect(gun, event=True)
|
||||
self.multiworld.state.collect(ammo, event=True)
|
||||
self.multiworld.state.collect(ammo, event=True)
|
||||
self.multiworld.state.collect(ammo, event=True)
|
||||
self.multiworld.state.collect(life, event=True)
|
||||
self.multiworld.state.collect(drop, event=True)
|
||||
self.multiworld.state.collect(boots, prevent_sweep=True)
|
||||
self.multiworld.state.collect(boots, prevent_sweep=True)
|
||||
self.multiworld.state.collect(gun, prevent_sweep=True)
|
||||
self.multiworld.state.collect(gun, prevent_sweep=True)
|
||||
self.multiworld.state.collect(gun, prevent_sweep=True)
|
||||
self.multiworld.state.collect(gun, prevent_sweep=True)
|
||||
self.multiworld.state.collect(ammo, prevent_sweep=True)
|
||||
self.multiworld.state.collect(ammo, prevent_sweep=True)
|
||||
self.multiworld.state.collect(ammo, prevent_sweep=True)
|
||||
self.multiworld.state.collect(life, prevent_sweep=True)
|
||||
self.multiworld.state.collect(drop, prevent_sweep=True)
|
||||
self.assertTrue(self.world.logic.region.can_reach("JotPK World 1")(self.multiworld.state))
|
||||
self.assertTrue(self.world.logic.region.can_reach("JotPK World 2")(self.multiworld.state))
|
||||
self.assertTrue(self.world.logic.region.can_reach("JotPK World 3")(self.multiworld.state))
|
||||
|
||||
@@ -23,11 +23,11 @@ class TestBuildingLogic(SVTestBase):
|
||||
self.assertFalse(big_coop_blueprint_rule(self.multiworld.state),
|
||||
f"Rule is {repr(self.multiworld.get_location('Big Coop Blueprint', self.player).access_rule)}")
|
||||
|
||||
self.multiworld.state.collect(self.create_item("Can Construct Buildings"), event=True)
|
||||
self.multiworld.state.collect(self.create_item("Can Construct Buildings"), prevent_sweep=True)
|
||||
self.assertFalse(big_coop_blueprint_rule(self.multiworld.state),
|
||||
f"Rule is {repr(self.multiworld.get_location('Big Coop Blueprint', self.player).access_rule)}")
|
||||
|
||||
self.multiworld.state.collect(self.create_item("Progressive Coop"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Coop"), prevent_sweep=False)
|
||||
self.assertTrue(big_coop_blueprint_rule(self.multiworld.state),
|
||||
f"Rule is {repr(self.multiworld.get_location('Big Coop Blueprint', self.player).access_rule)}")
|
||||
|
||||
@@ -35,13 +35,13 @@ class TestBuildingLogic(SVTestBase):
|
||||
self.assertFalse(self.world.logic.region.can_reach_location("Deluxe Coop Blueprint")(self.multiworld.state))
|
||||
|
||||
self.collect_lots_of_money()
|
||||
self.multiworld.state.collect(self.create_item("Can Construct Buildings"), event=True)
|
||||
self.multiworld.state.collect(self.create_item("Can Construct Buildings"), prevent_sweep=True)
|
||||
self.assertFalse(self.world.logic.region.can_reach_location("Deluxe Coop Blueprint")(self.multiworld.state))
|
||||
|
||||
self.multiworld.state.collect(self.create_item("Progressive Coop"), event=True)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Coop"), prevent_sweep=True)
|
||||
self.assertFalse(self.world.logic.region.can_reach_location("Deluxe Coop Blueprint")(self.multiworld.state))
|
||||
|
||||
self.multiworld.state.collect(self.create_item("Progressive Coop"), event=True)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Coop"), prevent_sweep=True)
|
||||
self.assertTrue(self.world.logic.region.can_reach_location("Deluxe Coop Blueprint")(self.multiworld.state))
|
||||
|
||||
def test_big_shed_blueprint(self):
|
||||
@@ -53,10 +53,10 @@ class TestBuildingLogic(SVTestBase):
|
||||
self.assertFalse(big_shed_rule(self.multiworld.state),
|
||||
f"Rule is {repr(self.multiworld.get_location('Big Shed Blueprint', self.player).access_rule)}")
|
||||
|
||||
self.multiworld.state.collect(self.create_item("Can Construct Buildings"), event=True)
|
||||
self.multiworld.state.collect(self.create_item("Can Construct Buildings"), prevent_sweep=True)
|
||||
self.assertFalse(big_shed_rule(self.multiworld.state),
|
||||
f"Rule is {repr(self.multiworld.get_location('Big Shed Blueprint', self.player).access_rule)}")
|
||||
|
||||
self.multiworld.state.collect(self.create_item("Progressive Shed"), event=True)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Shed"), prevent_sweep=True)
|
||||
self.assertTrue(big_shed_rule(self.multiworld.state),
|
||||
f"Rule is {repr(self.multiworld.get_location('Big Shed Blueprint', self.player).access_rule)}")
|
||||
|
||||
@@ -17,14 +17,14 @@ class TestRecipeLearnLogic(SVTestBase):
|
||||
rule = self.world.logic.region.can_reach_location(location)
|
||||
self.assert_rule_false(rule, self.multiworld.state)
|
||||
|
||||
self.multiworld.state.collect(self.create_item("Progressive House"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Radish Seeds"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Spring"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Summer"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive House"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Radish Seeds"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Spring"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Summer"), prevent_sweep=False)
|
||||
self.collect_lots_of_money()
|
||||
self.assert_rule_false(rule, self.multiworld.state)
|
||||
|
||||
self.multiworld.state.collect(self.create_item("The Queen of Sauce"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("The Queen of Sauce"), prevent_sweep=False)
|
||||
self.assert_rule_true(rule, self.multiworld.state)
|
||||
|
||||
|
||||
@@ -42,21 +42,21 @@ class TestRecipeReceiveLogic(SVTestBase):
|
||||
rule = self.world.logic.region.can_reach_location(location)
|
||||
self.assert_rule_false(rule, self.multiworld.state)
|
||||
|
||||
self.multiworld.state.collect(self.create_item("Progressive House"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Radish Seeds"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Summer"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive House"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Radish Seeds"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Summer"), prevent_sweep=False)
|
||||
self.collect_lots_of_money()
|
||||
self.assert_rule_false(rule, self.multiworld.state)
|
||||
|
||||
spring = self.create_item("Spring")
|
||||
qos = self.create_item("The Queen of Sauce")
|
||||
self.multiworld.state.collect(spring, event=False)
|
||||
self.multiworld.state.collect(qos, event=False)
|
||||
self.multiworld.state.collect(spring, prevent_sweep=False)
|
||||
self.multiworld.state.collect(qos, prevent_sweep=False)
|
||||
self.assert_rule_false(rule, self.multiworld.state)
|
||||
self.multiworld.state.remove(spring)
|
||||
self.multiworld.state.remove(qos)
|
||||
|
||||
self.multiworld.state.collect(self.create_item("Radish Salad Recipe"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Radish Salad Recipe"), prevent_sweep=False)
|
||||
self.assert_rule_true(rule, self.multiworld.state)
|
||||
|
||||
def test_get_chefsanity_check_recipe(self):
|
||||
@@ -64,20 +64,20 @@ class TestRecipeReceiveLogic(SVTestBase):
|
||||
rule = self.world.logic.region.can_reach_location(location)
|
||||
self.assert_rule_false(rule, self.multiworld.state)
|
||||
|
||||
self.multiworld.state.collect(self.create_item("Spring"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Spring"), prevent_sweep=False)
|
||||
self.collect_lots_of_money()
|
||||
self.assert_rule_false(rule, self.multiworld.state)
|
||||
|
||||
seeds = self.create_item("Radish Seeds")
|
||||
summer = self.create_item("Summer")
|
||||
house = self.create_item("Progressive House")
|
||||
self.multiworld.state.collect(seeds, event=False)
|
||||
self.multiworld.state.collect(summer, event=False)
|
||||
self.multiworld.state.collect(house, event=False)
|
||||
self.multiworld.state.collect(seeds, prevent_sweep=False)
|
||||
self.multiworld.state.collect(summer, prevent_sweep=False)
|
||||
self.multiworld.state.collect(house, prevent_sweep=False)
|
||||
self.assert_rule_false(rule, self.multiworld.state)
|
||||
self.multiworld.state.remove(seeds)
|
||||
self.multiworld.state.remove(summer)
|
||||
self.multiworld.state.remove(house)
|
||||
|
||||
self.multiworld.state.collect(self.create_item("The Queen of Sauce"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("The Queen of Sauce"), prevent_sweep=False)
|
||||
self.assert_rule_true(rule, self.multiworld.state)
|
||||
|
||||
@@ -25,7 +25,7 @@ class TestCraftsanityLogic(SVTestBase):
|
||||
self.collect_all_the_money()
|
||||
self.assert_rule_false(rule, self.multiworld.state)
|
||||
|
||||
self.multiworld.state.collect(self.create_item("Marble Brazier Recipe"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Marble Brazier Recipe"), prevent_sweep=False)
|
||||
self.assert_rule_true(rule, self.multiworld.state)
|
||||
|
||||
def test_can_learn_crafting_recipe(self):
|
||||
@@ -38,16 +38,16 @@ class TestCraftsanityLogic(SVTestBase):
|
||||
|
||||
def test_can_craft_festival_recipe(self):
|
||||
recipe = all_crafting_recipes_by_name["Jack-O-Lantern"]
|
||||
self.multiworld.state.collect(self.create_item("Pumpkin Seeds"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Torch Recipe"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Pumpkin Seeds"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Torch Recipe"), prevent_sweep=False)
|
||||
self.collect_lots_of_money()
|
||||
rule = self.world.logic.crafting.can_craft(recipe)
|
||||
self.assert_rule_false(rule, self.multiworld.state)
|
||||
|
||||
self.multiworld.state.collect(self.create_item("Fall"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Fall"), prevent_sweep=False)
|
||||
self.assert_rule_false(rule, self.multiworld.state)
|
||||
|
||||
self.multiworld.state.collect(self.create_item("Jack-O-Lantern Recipe"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Jack-O-Lantern Recipe"), prevent_sweep=False)
|
||||
self.assert_rule_true(rule, self.multiworld.state)
|
||||
|
||||
|
||||
@@ -62,16 +62,16 @@ class TestCraftsanityWithFestivalsLogic(SVTestBase):
|
||||
|
||||
def test_can_craft_festival_recipe(self):
|
||||
recipe = all_crafting_recipes_by_name["Jack-O-Lantern"]
|
||||
self.multiworld.state.collect(self.create_item("Pumpkin Seeds"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Fall"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Pumpkin Seeds"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Fall"), prevent_sweep=False)
|
||||
self.collect_lots_of_money()
|
||||
rule = self.world.logic.crafting.can_craft(recipe)
|
||||
self.assert_rule_false(rule, self.multiworld.state)
|
||||
|
||||
self.multiworld.state.collect(self.create_item("Jack-O-Lantern Recipe"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Jack-O-Lantern Recipe"), prevent_sweep=False)
|
||||
self.assert_rule_false(rule, self.multiworld.state)
|
||||
|
||||
self.multiworld.state.collect(self.create_item("Torch Recipe"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Torch Recipe"), prevent_sweep=False)
|
||||
self.assert_rule_true(rule, self.multiworld.state)
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ class TestNoCraftsanityLogic(SVTestBase):
|
||||
|
||||
def test_can_craft_festival_recipe(self):
|
||||
recipe = all_crafting_recipes_by_name["Jack-O-Lantern"]
|
||||
self.multiworld.state.collect(self.create_item("Pumpkin Seeds"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Pumpkin Seeds"), prevent_sweep=False)
|
||||
self.collect_lots_of_money()
|
||||
rule = self.world.logic.crafting.can_craft(recipe)
|
||||
result = rule(self.multiworld.state)
|
||||
@@ -113,11 +113,11 @@ class TestNoCraftsanityWithFestivalsLogic(SVTestBase):
|
||||
|
||||
def test_can_craft_festival_recipe(self):
|
||||
recipe = all_crafting_recipes_by_name["Jack-O-Lantern"]
|
||||
self.multiworld.state.collect(self.create_item("Pumpkin Seeds"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Fall"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Pumpkin Seeds"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Fall"), prevent_sweep=False)
|
||||
self.collect_lots_of_money()
|
||||
rule = self.world.logic.crafting.can_craft(recipe)
|
||||
self.assert_rule_false(rule, self.multiworld.state)
|
||||
|
||||
self.multiworld.state.collect(self.create_item("Jack-O-Lantern Recipe"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Jack-O-Lantern Recipe"), prevent_sweep=False)
|
||||
self.assert_rule_true(rule, self.multiworld.state)
|
||||
|
||||
@@ -18,7 +18,7 @@ class TestDonationLogicAll(SVTestBase):
|
||||
for donation in locations_by_tag[LocationTags.MUSEUM_DONATIONS]:
|
||||
self.assertFalse(self.world.logic.region.can_reach_location(donation.name)(self.multiworld.state))
|
||||
|
||||
self.multiworld.state.collect(self.create_item(railroad_item), event=False)
|
||||
self.multiworld.state.collect(self.create_item(railroad_item), prevent_sweep=False)
|
||||
|
||||
for donation in locations_by_tag[LocationTags.MUSEUM_DONATIONS]:
|
||||
self.assertTrue(self.world.logic.region.can_reach_location(donation.name)(self.multiworld.state))
|
||||
@@ -39,7 +39,7 @@ class TestDonationLogicRandomized(SVTestBase):
|
||||
for donation in donation_locations:
|
||||
self.assertFalse(self.world.logic.region.can_reach_location(donation.name)(self.multiworld.state))
|
||||
|
||||
self.multiworld.state.collect(self.create_item(railroad_item), event=False)
|
||||
self.multiworld.state.collect(self.create_item(railroad_item), prevent_sweep=False)
|
||||
|
||||
for donation in donation_locations:
|
||||
self.assertTrue(self.world.logic.region.can_reach_location(donation.name)(self.multiworld.state))
|
||||
@@ -58,7 +58,7 @@ class TestDonationLogicMilestones(SVTestBase):
|
||||
for donation in locations_by_tag[LocationTags.MUSEUM_MILESTONES]:
|
||||
self.assertFalse(self.world.logic.region.can_reach_location(donation.name)(self.multiworld.state))
|
||||
|
||||
self.multiworld.state.collect(self.create_item(railroad_item), event=False)
|
||||
self.multiworld.state.collect(self.create_item(railroad_item), prevent_sweep=False)
|
||||
|
||||
for donation in locations_by_tag[LocationTags.MUSEUM_MILESTONES]:
|
||||
self.assertTrue(self.world.logic.region.can_reach_location(donation.name)(self.multiworld.state))
|
||||
|
||||
@@ -11,34 +11,34 @@ class TestFriendsanityDatingRules(SVTestBase):
|
||||
|
||||
def test_earning_dating_heart_requires_dating(self):
|
||||
self.collect_all_the_money()
|
||||
self.multiworld.state.collect(self.create_item("Fall"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Beach Bridge"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive House"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Fall"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Beach Bridge"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive House"), prevent_sweep=False)
|
||||
for i in range(3):
|
||||
self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Weapon"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Axe"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Barn"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Weapon"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Axe"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Barn"), prevent_sweep=False)
|
||||
for i in range(10):
|
||||
self.multiworld.state.collect(self.create_item("Foraging Level"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Farming Level"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Mining Level"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Combat Level"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Mine Elevator"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Mine Elevator"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Foraging Level"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Farming Level"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Mining Level"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Combat Level"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Mine Elevator"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Mine Elevator"), prevent_sweep=False)
|
||||
|
||||
npc = "Abigail"
|
||||
heart_name = f"{npc} <3"
|
||||
step = 3
|
||||
|
||||
self.assert_can_reach_heart_up_to(npc, 3, step)
|
||||
self.multiworld.state.collect(self.create_item(heart_name), event=False)
|
||||
self.multiworld.state.collect(self.create_item(heart_name), prevent_sweep=False)
|
||||
self.assert_can_reach_heart_up_to(npc, 6, step)
|
||||
self.multiworld.state.collect(self.create_item(heart_name), event=False)
|
||||
self.multiworld.state.collect(self.create_item(heart_name), prevent_sweep=False)
|
||||
self.assert_can_reach_heart_up_to(npc, 8, step)
|
||||
self.multiworld.state.collect(self.create_item(heart_name), event=False)
|
||||
self.multiworld.state.collect(self.create_item(heart_name), prevent_sweep=False)
|
||||
self.assert_can_reach_heart_up_to(npc, 10, step)
|
||||
self.multiworld.state.collect(self.create_item(heart_name), event=False)
|
||||
self.multiworld.state.collect(self.create_item(heart_name), prevent_sweep=False)
|
||||
self.assert_can_reach_heart_up_to(npc, 14, step)
|
||||
|
||||
def assert_can_reach_heart_up_to(self, npc: str, max_reachable: int, step: int):
|
||||
|
||||
@@ -76,7 +76,7 @@ class TestShipsanityEverything(SVTestBase):
|
||||
with self.subTest(location.name):
|
||||
self.remove(bin_item)
|
||||
self.assertFalse(self.world.logic.region.can_reach_location(location.name)(self.multiworld.state))
|
||||
self.multiworld.state.collect(bin_item, event=False)
|
||||
self.multiworld.state.collect(bin_item, prevent_sweep=False)
|
||||
shipsanity_rule = self.world.logic.region.can_reach_location(location.name)
|
||||
self.assert_rule_true(shipsanity_rule, self.multiworld.state)
|
||||
self.remove(bin_item)
|
||||
|
||||
@@ -21,30 +21,30 @@ class TestProgressiveToolsLogic(SVTestBase):
|
||||
self.assert_rule_false(sturgeon_rule, self.multiworld.state)
|
||||
|
||||
summer = self.create_item("Summer")
|
||||
self.multiworld.state.collect(summer, event=False)
|
||||
self.multiworld.state.collect(summer, prevent_sweep=False)
|
||||
self.assert_rule_false(sturgeon_rule, self.multiworld.state)
|
||||
|
||||
fishing_rod = self.create_item("Progressive Fishing Rod")
|
||||
self.multiworld.state.collect(fishing_rod, event=False)
|
||||
self.multiworld.state.collect(fishing_rod, event=False)
|
||||
self.multiworld.state.collect(fishing_rod, prevent_sweep=False)
|
||||
self.multiworld.state.collect(fishing_rod, prevent_sweep=False)
|
||||
self.assert_rule_false(sturgeon_rule, self.multiworld.state)
|
||||
|
||||
fishing_level = self.create_item("Fishing Level")
|
||||
self.multiworld.state.collect(fishing_level, event=False)
|
||||
self.multiworld.state.collect(fishing_level, prevent_sweep=False)
|
||||
self.assert_rule_false(sturgeon_rule, self.multiworld.state)
|
||||
|
||||
self.multiworld.state.collect(fishing_level, event=False)
|
||||
self.multiworld.state.collect(fishing_level, event=False)
|
||||
self.multiworld.state.collect(fishing_level, event=False)
|
||||
self.multiworld.state.collect(fishing_level, event=False)
|
||||
self.multiworld.state.collect(fishing_level, event=False)
|
||||
self.multiworld.state.collect(fishing_level, prevent_sweep=False)
|
||||
self.multiworld.state.collect(fishing_level, prevent_sweep=False)
|
||||
self.multiworld.state.collect(fishing_level, prevent_sweep=False)
|
||||
self.multiworld.state.collect(fishing_level, prevent_sweep=False)
|
||||
self.multiworld.state.collect(fishing_level, prevent_sweep=False)
|
||||
self.assert_rule_true(sturgeon_rule, self.multiworld.state)
|
||||
|
||||
self.remove(summer)
|
||||
self.assert_rule_false(sturgeon_rule, self.multiworld.state)
|
||||
|
||||
winter = self.create_item("Winter")
|
||||
self.multiworld.state.collect(winter, event=False)
|
||||
self.multiworld.state.collect(winter, prevent_sweep=False)
|
||||
self.assert_rule_true(sturgeon_rule, self.multiworld.state)
|
||||
|
||||
self.remove(fishing_rod)
|
||||
@@ -53,24 +53,24 @@ class TestProgressiveToolsLogic(SVTestBase):
|
||||
def test_old_master_cannoli(self):
|
||||
self.multiworld.state.prog_items = {1: Counter()}
|
||||
|
||||
self.multiworld.state.collect(self.create_item("Progressive Axe"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Axe"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Summer"), event=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Axe"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Axe"), prevent_sweep=False)
|
||||
self.multiworld.state.collect(self.create_item("Summer"), prevent_sweep=False)
|
||||
self.collect_lots_of_money()
|
||||
|
||||
rule = self.world.logic.region.can_reach_location("Old Master Cannoli")
|
||||
self.assert_rule_false(rule, self.multiworld.state)
|
||||
|
||||
fall = self.create_item("Fall")
|
||||
self.multiworld.state.collect(fall, event=False)
|
||||
self.multiworld.state.collect(fall, prevent_sweep=False)
|
||||
self.assert_rule_false(rule, self.multiworld.state)
|
||||
|
||||
tuesday = self.create_item("Traveling Merchant: Tuesday")
|
||||
self.multiworld.state.collect(tuesday, event=False)
|
||||
self.multiworld.state.collect(tuesday, prevent_sweep=False)
|
||||
self.assert_rule_false(rule, self.multiworld.state)
|
||||
|
||||
rare_seed = self.create_item("Rare Seed")
|
||||
self.multiworld.state.collect(rare_seed, event=False)
|
||||
self.multiworld.state.collect(rare_seed, prevent_sweep=False)
|
||||
self.assert_rule_true(rule, self.multiworld.state)
|
||||
|
||||
self.remove(fall)
|
||||
@@ -80,11 +80,11 @@ class TestProgressiveToolsLogic(SVTestBase):
|
||||
|
||||
green_house = self.create_item("Greenhouse")
|
||||
self.collect(self.create_item(Event.fall_farming))
|
||||
self.multiworld.state.collect(green_house, event=False)
|
||||
self.multiworld.state.collect(green_house, prevent_sweep=False)
|
||||
self.assert_rule_false(rule, self.multiworld.state)
|
||||
|
||||
friday = self.create_item("Traveling Merchant: Friday")
|
||||
self.multiworld.state.collect(friday, event=False)
|
||||
self.multiworld.state.collect(friday, prevent_sweep=False)
|
||||
self.assertTrue(self.multiworld.get_location("Old Master Cannoli", 1).access_rule(self.multiworld.state))
|
||||
|
||||
self.remove(green_house)
|
||||
@@ -111,7 +111,7 @@ class TestToolVanillaRequiresBlacksmith(SVTestBase):
|
||||
for material in [ToolMaterial.copper, ToolMaterial.iron, ToolMaterial.gold, ToolMaterial.iridium]:
|
||||
self.assert_rule_false(self.world.logic.tool.has_tool(tool, material), self.multiworld.state)
|
||||
|
||||
self.multiworld.state.collect(self.create_item(railroad_item), event=False)
|
||||
self.multiworld.state.collect(self.create_item(railroad_item), prevent_sweep=False)
|
||||
|
||||
for tool in [Tool.pickaxe, Tool.axe, Tool.hoe, Tool.trash_can, Tool.watering_can]:
|
||||
for material in [ToolMaterial.copper, ToolMaterial.iron, ToolMaterial.gold, ToolMaterial.iridium]:
|
||||
@@ -125,7 +125,7 @@ class TestToolVanillaRequiresBlacksmith(SVTestBase):
|
||||
for fishing_rod_level in [3, 4]:
|
||||
self.assert_rule_false(self.world.logic.tool.has_fishing_rod(fishing_rod_level), self.multiworld.state)
|
||||
|
||||
self.multiworld.state.collect(self.create_item(railroad_item), event=False)
|
||||
self.multiworld.state.collect(self.create_item(railroad_item), prevent_sweep=False)
|
||||
|
||||
for fishing_rod_level in [3, 4]:
|
||||
self.assert_rule_true(self.world.logic.tool.has_fishing_rod(fishing_rod_level), self.multiworld.state)
|
||||
|
||||
@@ -10,16 +10,16 @@ class TestWeaponsLogic(SVTestBase):
|
||||
}
|
||||
|
||||
def test_mine(self):
|
||||
self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), event=True)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), event=True)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), event=True)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), event=True)
|
||||
self.multiworld.state.collect(self.create_item("Progressive House"), event=True)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), prevent_sweep=True)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), prevent_sweep=True)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), prevent_sweep=True)
|
||||
self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), prevent_sweep=True)
|
||||
self.multiworld.state.collect(self.create_item("Progressive House"), prevent_sweep=True)
|
||||
self.collect([self.create_item("Combat Level")] * 10)
|
||||
self.collect([self.create_item("Mining Level")] * 10)
|
||||
self.collect([self.create_item("Progressive Mine Elevator")] * 24)
|
||||
self.multiworld.state.collect(self.create_item("Bus Repair"), event=True)
|
||||
self.multiworld.state.collect(self.create_item("Skull Key"), event=True)
|
||||
self.multiworld.state.collect(self.create_item("Bus Repair"), prevent_sweep=True)
|
||||
self.multiworld.state.collect(self.create_item("Skull Key"), prevent_sweep=True)
|
||||
|
||||
self.GiveItemAndCheckReachableMine("Progressive Sword", 1)
|
||||
self.GiveItemAndCheckReachableMine("Progressive Dagger", 1)
|
||||
@@ -43,7 +43,7 @@ class TestWeaponsLogic(SVTestBase):
|
||||
|
||||
def GiveItemAndCheckReachableMine(self, item_name: str, reachable_level: int):
|
||||
item = self.multiworld.create_item(item_name, self.player)
|
||||
self.multiworld.state.collect(item, event=True)
|
||||
self.multiworld.state.collect(item, prevent_sweep=True)
|
||||
rule = self.world.logic.mine.can_mine_in_the_mines_floor_1_40()
|
||||
if reachable_level > 0:
|
||||
self.assert_rule_true(rule, self.multiworld.state)
|
||||
|
||||
@@ -135,11 +135,11 @@ def get_location_datas(player: Optional[int], options: Optional[TimespinnerOptio
|
||||
LocationData('Upper Lake Serene', 'Lake Serene: Pyramid keys room', 1337104),
|
||||
LocationData('Upper Lake Serene', 'Lake Serene (Upper): Chicken ledge', 1337174),
|
||||
LocationData('Lower Lake Serene', 'Lake Serene (Lower): Deep dive', 1337105),
|
||||
LocationData('Lower Lake Serene', 'Lake Serene (Lower): Under the eels', 1337106),
|
||||
LocationData('Left Side forest Caves', 'Lake Serene (Lower): Under the eels', 1337106, lambda state: state.has('Water Mask', player)),
|
||||
LocationData('Lower Lake Serene', 'Lake Serene (Lower): Water spikes room', 1337107),
|
||||
LocationData('Lower Lake Serene', 'Lake Serene (Lower): Underwater secret', 1337108, logic.can_break_walls),
|
||||
LocationData('Lower Lake Serene', 'Lake Serene (Lower): T chest', 1337109, lambda state: flooded.flood_lake_serene or logic.has_doublejump_of_npc(state)),
|
||||
LocationData('Lower Lake Serene', 'Lake Serene (Lower): Past the eels', 1337110),
|
||||
LocationData('Left Side forest Caves', 'Lake Serene (Lower): Past the eels', 1337110, lambda state: state.has('Water Mask', player)),
|
||||
LocationData('Lower Lake Serene', 'Lake Serene (Lower): Underwater pedestal', 1337111, lambda state: flooded.flood_lake_serene or logic.has_doublejump(state)),
|
||||
LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Shroom jump room', 1337112, lambda state: flooded.flood_maw or logic.has_doublejump(state)),
|
||||
LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Secret room', 1337113, lambda state: logic.can_break_walls(state) and (not flooded.flood_maw or state.has('Water Mask', player))),
|
||||
|
||||
@@ -220,8 +220,8 @@ class TunicWorld(World):
|
||||
player_dir = "<->" if player_cxn.direction == "both" else "-->"
|
||||
raise OptionError(f"TUNIC: Conflict between seed group {group}'s plando "
|
||||
f"connection {group_cxn.entrance} {group_dir} {group_cxn.exit} and "
|
||||
f"{tunic.multiworld.get_player_name(tunic.player)}'s plando "
|
||||
f"connection {player_cxn.entrance} {player_dir} {player_cxn.exit}")
|
||||
f"{tunic.player_name}'s plando connection "
|
||||
f"{player_cxn.entrance} {player_dir} {player_cxn.exit}")
|
||||
if new_cxn:
|
||||
cls.seed_groups[group]["plando"].append(player_cxn)
|
||||
|
||||
@@ -254,17 +254,17 @@ class TunicWorld(World):
|
||||
if self.options.laurels_location:
|
||||
laurels = self.create_item("Hero's Laurels")
|
||||
if self.options.laurels_location == "6_coins":
|
||||
self.multiworld.get_location("Coins in the Well - 6 Coins", self.player).place_locked_item(laurels)
|
||||
self.get_location("Coins in the Well - 6 Coins").place_locked_item(laurels)
|
||||
elif self.options.laurels_location == "10_coins":
|
||||
self.multiworld.get_location("Coins in the Well - 10 Coins", self.player).place_locked_item(laurels)
|
||||
self.get_location("Coins in the Well - 10 Coins").place_locked_item(laurels)
|
||||
elif self.options.laurels_location == "10_fairies":
|
||||
self.multiworld.get_location("Secret Gathering Place - 10 Fairy Reward", self.player).place_locked_item(laurels)
|
||||
self.get_location("Secret Gathering Place - 10 Fairy Reward").place_locked_item(laurels)
|
||||
items_to_create["Hero's Laurels"] = 0
|
||||
|
||||
if self.options.keys_behind_bosses:
|
||||
for rgb_hexagon, location in hexagon_locations.items():
|
||||
hex_item = self.create_item(gold_hexagon if self.options.hexagon_quest else rgb_hexagon)
|
||||
self.multiworld.get_location(location, self.player).place_locked_item(hex_item)
|
||||
self.get_location(location).place_locked_item(hex_item)
|
||||
items_to_create[rgb_hexagon] = 0
|
||||
items_to_create[gold_hexagon] -= 3
|
||||
|
||||
@@ -364,15 +364,15 @@ class TunicWorld(World):
|
||||
self.multiworld.regions.append(region)
|
||||
|
||||
for region_name, exits in tunic_regions.items():
|
||||
region = self.multiworld.get_region(region_name, self.player)
|
||||
region = self.get_region(region_name)
|
||||
region.add_exits(exits)
|
||||
|
||||
for location_name, location_id in self.location_name_to_id.items():
|
||||
region = self.multiworld.get_region(location_table[location_name].region, self.player)
|
||||
region = self.get_region(location_table[location_name].region)
|
||||
location = TunicLocation(self.player, location_name, location_id, region)
|
||||
region.locations.append(location)
|
||||
|
||||
victory_region = self.multiworld.get_region("Spirit Arena", self.player)
|
||||
victory_region = self.get_region("Spirit Arena")
|
||||
victory_location = TunicLocation(self.player, "The Heir", None, victory_region)
|
||||
victory_location.place_locked_item(TunicItem("Victory", ItemClassification.progression, None, self.player))
|
||||
self.multiworld.completion_condition[self.player] = lambda state: state.has("Victory", self.player)
|
||||
@@ -420,10 +420,8 @@ class TunicWorld(World):
|
||||
name, connection = paths[location.parent_region]
|
||||
except KeyError:
|
||||
# logic bug, proceed with warning since it takes a long time to update AP
|
||||
warning(f"{location.name} is not logically accessible for "
|
||||
f"{self.multiworld.get_file_safe_player_name(self.player)}. "
|
||||
"Creating entrance hint Inaccessible. "
|
||||
"Please report this to the TUNIC rando devs.")
|
||||
warning(f"{location.name} is not logically accessible for {self.player_name}. "
|
||||
"Creating entrance hint Inaccessible. Please report this to the TUNIC rando devs.")
|
||||
hint_text = "Inaccessible"
|
||||
else:
|
||||
while connection != ("Menu", None):
|
||||
@@ -496,7 +494,9 @@ class TunicWorld(World):
|
||||
return slot_data
|
||||
|
||||
# for the universal tracker, doesn't get called in standard gen
|
||||
# docs: https://github.com/FarisTheAncient/Archipelago/blob/tracker/worlds/tracker/docs/re-gen-passthrough.md
|
||||
@staticmethod
|
||||
def interpret_slot_data(slot_data: Dict[str, Any]) -> Dict[str, Any]:
|
||||
# returning slot_data so it regens, giving it back in multiworld.re_gen_passthrough
|
||||
# we are using re_gen_passthrough over modifying the world here due to complexities with ER
|
||||
return slot_data
|
||||
|
||||
@@ -183,7 +183,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal
|
||||
portal_pairs: Dict[Portal, Portal] = {}
|
||||
dead_ends: List[Portal] = []
|
||||
two_plus: List[Portal] = []
|
||||
player_name = world.multiworld.get_player_name(world.player)
|
||||
player_name = world.player_name
|
||||
portal_map = portal_mapping.copy()
|
||||
laurels_zips = world.options.laurels_zips.value
|
||||
ice_grappling = world.options.ice_grappling.value
|
||||
|
||||
@@ -67,12 +67,15 @@ class UndertaleWorld(World):
|
||||
"only_flakes": bool(self.options.only_flakes.value),
|
||||
"no_equips": bool(self.options.no_equips.value),
|
||||
"key_hunt": bool(self.options.key_hunt.value),
|
||||
"key_pieces": self.options.key_pieces.value,
|
||||
"rando_love": bool(self.options.rando_love.value),
|
||||
"rando_stats": bool(self.options.rando_stats.value),
|
||||
"key_pieces": int(self.options.key_pieces.value),
|
||||
"rando_love": bool(self.options.rando_love and (self.options.route_required == "genocide" or self.options.route_required == "all_routes")),
|
||||
"rando_stats": bool(self.options.rando_stats and (self.options.route_required == "genocide" or self.options.route_required == "all_routes")),
|
||||
"prog_armor": bool(self.options.prog_armor.value),
|
||||
"prog_weapons": bool(self.options.prog_weapons.value),
|
||||
"rando_item_button": bool(self.options.rando_item_button.value)
|
||||
"rando_item_button": bool(self.options.rando_item_button.value),
|
||||
"route_required": int(self.options.route_required.value),
|
||||
"temy_include": int(self.options.temy_include.value)
|
||||
|
||||
}
|
||||
|
||||
def get_filler_item_name(self):
|
||||
@@ -220,16 +223,7 @@ class UndertaleWorld(World):
|
||||
link_undertale_areas(self.multiworld, self.player)
|
||||
|
||||
def fill_slot_data(self):
|
||||
slot_data = self._get_undertale_data()
|
||||
for option_name in self.options.as_dict():
|
||||
option = getattr(self.multiworld, option_name)[self.player]
|
||||
if (option_name == "rando_love" or option_name == "rando_stats") and \
|
||||
self.options.route_required != "genocide" and \
|
||||
self.options.route_required != "all_routes":
|
||||
option.value = False
|
||||
if slot_data.get(option_name, None) is None and type(option.value) in {str, int}:
|
||||
slot_data[option_name] = int(option.value)
|
||||
return slot_data
|
||||
return self._get_undertale_data()
|
||||
|
||||
def create_item(self, name: str) -> Item:
|
||||
item_data = item_table[name]
|
||||
|
||||
Reference in New Issue
Block a user