Compare commits

..

2 Commits

Author SHA1 Message Date
Exempt-Medic
86a6939f02 Also fix max count 2025-06-12 13:05:00 -04:00
Exempt-Medic
51254948aa Fix plando count value 2025-06-12 12:57:32 -04:00
13 changed files with 72 additions and 69 deletions

View File

@@ -890,7 +890,7 @@ def parse_planned_blocks(multiworld: MultiWorld) -> dict[int, list[PlandoItemBlo
worlds = set()
for listed_world in target_world:
if listed_world not in world_name_lookup:
failed(f"Cannot place item to {listed_world}'s world as that world does not exist.",
failed(f"Cannot place item to {target_world}'s world as that world does not exist.",
block.force)
continue
worlds.add(world_name_lookup[listed_world])

View File

@@ -548,12 +548,10 @@ def set_up_take_anys(multiworld, world, player):
old_man_take_any.shop = TakeAny(old_man_take_any, 0x0112, 0xE2, True, True, total_shop_slots)
multiworld.shops.append(old_man_take_any.shop)
sword_indices = [
index for index, item in enumerate(multiworld.itempool) if item.player == player and item.type == 'Sword'
]
if sword_indices:
sword_index = multiworld.random.choice(sword_indices)
sword = multiworld.itempool.pop(sword_index)
swords = [item for item in multiworld.itempool if item.player == player and item.type == 'Sword']
if swords:
sword = multiworld.random.choice(swords)
multiworld.itempool.remove(sword)
multiworld.itempool.append(item_factory('Rupees (20)', world))
old_man_take_any.shop.add_inventory(0, sword.name, 0, 0)
loc_name = "Old Man Sword Cave"

View File

@@ -38,7 +38,7 @@ class DungeonFillTestBase(TestCase):
def test_original_dungeons(self):
self.generate_with_options(DungeonItem.option_original_dungeon)
for location in self.multiworld.get_filled_locations():
with (self.subTest(location_name=location.name)):
with (self.subTest(location=location)):
if location.parent_region.dungeon is None:
self.assertIs(location.item.dungeon, None)
else:
@@ -52,7 +52,7 @@ class DungeonFillTestBase(TestCase):
def test_own_dungeons(self):
self.generate_with_options(DungeonItem.option_own_dungeons)
for location in self.multiworld.get_filled_locations():
with self.subTest(location_name=location.name):
with self.subTest(location=location):
if location.parent_region.dungeon is None:
self.assertIs(location.item.dungeon, None)
else:

View File

@@ -4,7 +4,7 @@ Date: Fri, 15 Mar 2024 18:41:40 +0000
Description: Used to manage Regions in the Aquaria game multiworld randomizer
"""
from typing import Dict, Optional, Iterable
from typing import Dict, Optional
from BaseClasses import MultiWorld, Region, Entrance, Item, ItemClassification, CollectionState
from .Items import AquariaItem, ItemNames
from .Locations import AquariaLocations, AquariaLocation, AquariaLocationNames
@@ -34,15 +34,10 @@ def _has_li(state: CollectionState, player: int) -> bool:
return state.has(ItemNames.LI_AND_LI_SONG, player)
DAMAGING_ITEMS:Iterable[str] = [
ItemNames.ENERGY_FORM, ItemNames.NATURE_FORM, ItemNames.BEAST_FORM,
ItemNames.LI_AND_LI_SONG, ItemNames.BABY_NAUTILUS, ItemNames.BABY_PIRANHA,
ItemNames.BABY_BLASTER
]
def _has_damaging_item(state: CollectionState, player: int, damaging_items:Iterable[str] = DAMAGING_ITEMS) -> bool:
"""`player` in `state` has the an item that do damage other than the ones in `to_remove`"""
return state.has_any(damaging_items, player)
def _has_damaging_item(state: CollectionState, player: int) -> bool:
"""`player` in `state` has the shield song item"""
return state.has_any({ItemNames.ENERGY_FORM, ItemNames.NATURE_FORM, ItemNames.BEAST_FORM, ItemNames.LI_AND_LI_SONG,
ItemNames.BABY_NAUTILUS, ItemNames.BABY_PIRANHA, ItemNames.BABY_BLASTER}, player)
def _has_energy_attack_item(state: CollectionState, player: int) -> bool:
@@ -571,11 +566,9 @@ class AquariaRegions:
self.__connect_one_way_regions(self.openwater_tr, self.openwater_tr_turtle,
lambda state: _has_beast_form_or_arnassi_armor(state, self.player))
self.__connect_one_way_regions(self.openwater_tr_turtle, self.openwater_tr)
damaging_items_minus_nature_form = [item for item in DAMAGING_ITEMS if item != ItemNames.NATURE_FORM]
self.__connect_one_way_regions(self.openwater_tr, self.openwater_tr_urns,
lambda state: _has_bind_song(state, self.player) or
_has_damaging_item(state, self.player,
damaging_items_minus_nature_form))
_has_damaging_item(state, self.player))
self.__connect_regions(self.openwater_tr, self.openwater_br)
self.__connect_regions(self.openwater_tr, self.mithalas_city)
self.__connect_regions(self.openwater_tr, self.veil_b)

View File

@@ -1,7 +1,6 @@
import typing
from BaseClasses import MultiWorld
from Options import OptionError
from worlds.AutoWorld import World
from .Names import LocationName
@@ -100,9 +99,8 @@ def get_gate_bosses(world: World):
pass
if boss in plando_bosses:
raise OptionError(f"Invalid input for option `plando_bosses`: "
f"No Duplicate Bosses permitted ({boss}) - for "
f"{world.player_name}")
# TODO: Raise error here. Duplicates not allowed
pass
plando_bosses[boss_num] = boss
@@ -110,14 +108,13 @@ def get_gate_bosses(world: World):
available_bosses.remove(boss)
for x in range(world.options.number_of_level_gates):
if (10 not in selected_bosses) and (king_boom_boo not in available_bosses) and ((x + 1) / world.options.number_of_level_gates) > 0.5:
available_bosses.extend(gate_bosses_with_requirements_table.keys())
if ("king boom boo" not in selected_bosses) and ("king boom boo" not in available_bosses) and ((x + 1) / world.options.number_of_level_gates) > 0.5:
available_bosses.extend(gate_bosses_with_requirements_table)
world.random.shuffle(available_bosses)
chosen_boss = available_bosses[0]
if plando_bosses[x] != "None":
if plando_bosses[x] not in available_bosses:
available_bosses.append(plando_bosses[x])
available_bosses.append(plando_bosses[x])
chosen_boss = plando_bosses[x]
selected_bosses.append(all_gate_bosses_table[chosen_boss])

View File

@@ -324,8 +324,7 @@ def set_mission_upgrade_rules_standard(multiworld: MultiWorld, world: World, pla
add_rule_safe(multiworld, LocationName.iron_gate_5, player,
lambda state: state.has(ItemName.eggman_large_cannon, player))
add_rule_safe(multiworld, LocationName.dry_lagoon_5, player,
lambda state: state.has(ItemName.rouge_pick_nails, player) and
state.has(ItemName.rouge_treasure_scope, player))
lambda state: state.has(ItemName.rouge_treasure_scope, player))
add_rule_safe(multiworld, LocationName.sand_ocean_5, player,
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule_safe(multiworld, LocationName.egg_quarters_5, player,
@@ -408,7 +407,8 @@ def set_mission_upgrade_rules_standard(multiworld: MultiWorld, world: World, pla
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(multiworld.get_location(LocationName.cosmic_wall_chao_1, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
lambda state: state.has(ItemName.eggman_mystic_melody, player) and
state.has(ItemName.eggman_jet_engine, player))
add_rule(multiworld.get_location(LocationName.cannon_core_chao_1, player),
lambda state: state.has(ItemName.tails_booster, player) and
@@ -1402,6 +1402,8 @@ def set_mission_upgrade_rules_standard(multiworld: MultiWorld, world: World, pla
state.has(ItemName.eggman_large_cannon, player)))
add_rule(multiworld.get_location(LocationName.dry_lagoon_lifebox_2, player),
lambda state: state.has(ItemName.rouge_treasure_scope, player))
add_rule(multiworld.get_location(LocationName.sand_ocean_lifebox_2, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(multiworld.get_location(LocationName.egg_quarters_lifebox_2, player),
lambda state: (state.has(ItemName.rouge_mystic_melody, player) and
state.has(ItemName.rouge_treasure_scope, player)))
@@ -1722,9 +1724,6 @@ def set_mission_upgrade_rules_standard(multiworld: MultiWorld, world: World, pla
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(multiworld.get_location(LocationName.white_jungle_itembox_8, player),
lambda state: state.has(ItemName.shadow_air_shoes, player))
add_rule(multiworld.get_location(LocationName.sky_rail_itembox_8, player),
lambda state: (state.has(ItemName.shadow_air_shoes, player) and
state.has(ItemName.shadow_mystic_melody, player)))
add_rule(multiworld.get_location(LocationName.mad_space_itembox_8, player),
lambda state: state.has(ItemName.rouge_iron_boots, player))
add_rule(multiworld.get_location(LocationName.cosmic_wall_itembox_8, player),
@@ -2309,7 +2308,8 @@ def set_mission_upgrade_rules_hard(multiworld: MultiWorld, world: World, player:
lambda state: state.has(ItemName.tails_booster, player))
add_rule(multiworld.get_location(LocationName.cosmic_wall_chao_1, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
lambda state: state.has(ItemName.eggman_mystic_melody, player) and
state.has(ItemName.eggman_jet_engine, player))
add_rule(multiworld.get_location(LocationName.cannon_core_chao_1, player),
lambda state: state.has(ItemName.tails_booster, player) and
@@ -2980,6 +2980,8 @@ def set_mission_upgrade_rules_hard(multiworld: MultiWorld, world: World, player:
state.has(ItemName.eggman_jet_engine, player)))
add_rule(multiworld.get_location(LocationName.dry_lagoon_lifebox_2, player),
lambda state: state.has(ItemName.rouge_treasure_scope, player))
add_rule(multiworld.get_location(LocationName.sand_ocean_lifebox_2, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(multiworld.get_location(LocationName.egg_quarters_lifebox_2, player),
lambda state: (state.has(ItemName.rouge_mystic_melody, player) and
state.has(ItemName.rouge_treasure_scope, player)))
@@ -3591,7 +3593,8 @@ def set_mission_upgrade_rules_expert(multiworld: MultiWorld, world: World, playe
lambda state: state.has(ItemName.tails_booster, player))
add_rule(multiworld.get_location(LocationName.cosmic_wall_chao_1, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
lambda state: state.has(ItemName.eggman_mystic_melody, player) and
state.has(ItemName.eggman_jet_engine, player))
add_rule(multiworld.get_location(LocationName.cannon_core_chao_1, player),
lambda state: state.has(ItemName.eggman_jet_engine, player) and
@@ -3640,6 +3643,9 @@ def set_mission_upgrade_rules_expert(multiworld: MultiWorld, world: World, playe
add_rule(multiworld.get_location(LocationName.cosmic_wall_pipe_2, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(multiworld.get_location(LocationName.cannon_core_pipe_2, player),
lambda state: state.has(ItemName.tails_booster, player))
add_rule(multiworld.get_location(LocationName.prison_lane_pipe_3, player),
lambda state: state.has(ItemName.tails_bazooka, player))
add_rule(multiworld.get_location(LocationName.mission_street_pipe_3, player),
@@ -3765,6 +3771,10 @@ def set_mission_upgrade_rules_expert(multiworld: MultiWorld, world: World, playe
add_rule(multiworld.get_location(LocationName.cosmic_wall_beetle, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(multiworld.get_location(LocationName.cannon_core_beetle, player),
lambda state: state.has(ItemName.tails_booster, player) and
state.has(ItemName.knuckles_hammer_gloves, player))
# Animal Upgrade Requirements
if world.options.animalsanity:
add_rule(multiworld.get_location(LocationName.hidden_base_animal_2, player),
@@ -3829,7 +3839,8 @@ def set_mission_upgrade_rules_expert(multiworld: MultiWorld, world: World, playe
add_rule(multiworld.get_location(LocationName.weapons_bed_animal_8, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(multiworld.get_location(LocationName.security_hall_animal_8, player),
lambda state: state.has(ItemName.rouge_iron_boots, player))
lambda state: state.has(ItemName.rouge_pick_nails, player) and
state.has(ItemName.rouge_iron_boots, player))
add_rule(multiworld.get_location(LocationName.cosmic_wall_animal_8, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
@@ -3965,6 +3976,8 @@ def set_mission_upgrade_rules_expert(multiworld: MultiWorld, world: World, playe
state.has(ItemName.tails_bazooka, player))
add_rule(multiworld.get_location(LocationName.crazy_gadget_animal_16, player),
lambda state: state.has(ItemName.sonic_flame_ring, player))
add_rule(multiworld.get_location(LocationName.final_rush_animal_16, player),
lambda state: state.has(ItemName.sonic_bounce_bracelet, player))
add_rule(multiworld.get_location(LocationName.final_chase_animal_17, player),
lambda state: state.has(ItemName.shadow_flame_ring, player))
@@ -4022,6 +4035,8 @@ def set_mission_upgrade_rules_expert(multiworld: MultiWorld, world: World, playe
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(multiworld.get_location(LocationName.dry_lagoon_lifebox_2, player),
lambda state: state.has(ItemName.rouge_treasure_scope, player))
add_rule(multiworld.get_location(LocationName.sand_ocean_lifebox_2, player),
lambda state: state.has(ItemName.eggman_jet_engine, player))
add_rule(multiworld.get_location(LocationName.egg_quarters_lifebox_2, player),
lambda state: state.has(ItemName.rouge_treasure_scope, player))

View File

@@ -12,7 +12,7 @@ from .Constants import *
def launch_client(*args: str):
from .Client import launch
launch_subprocess(launch, name=CLIENT_NAME, args=args)
launch_subprocess(launch(*args), name=CLIENT_NAME)
components.append(

View File

@@ -271,11 +271,11 @@ solar_essence = BundleItem(Loot.solar_essence)
void_essence = BundleItem(Loot.void_essence)
petrified_slime = BundleItem(Mineral.petrified_slime)
blue_slime_egg = BundleItem(AnimalProduct.slime_egg_blue)
red_slime_egg = BundleItem(AnimalProduct.slime_egg_red)
purple_slime_egg = BundleItem(AnimalProduct.slime_egg_purple)
green_slime_egg = BundleItem(AnimalProduct.slime_egg_green)
tiger_slime_egg = BundleItem(AnimalProduct.slime_egg_tiger, source=BundleItem.Sources.island)
blue_slime_egg = BundleItem(Loot.blue_slime_egg)
red_slime_egg = BundleItem(Loot.red_slime_egg)
purple_slime_egg = BundleItem(Loot.purple_slime_egg)
green_slime_egg = BundleItem(Loot.green_slime_egg)
tiger_slime_egg = BundleItem(Loot.tiger_slime_egg, source=BundleItem.Sources.island)
cherry_bomb = BundleItem(Bomb.cherry_bomb, 5)
bomb = BundleItem(Bomb.bomb, 2)

View File

@@ -168,16 +168,15 @@ class StardewLogic(ReceivedLogicMixin, HasLogicMixin, RegionLogicMixin, Travelin
AnimalProduct.squid_ink: self.mine.can_mine_in_the_mines_floor_81_120() | (self.building.has_building(Building.fish_pond) & self.has(Fish.squid)),
AnimalProduct.sturgeon_roe: self.has(Fish.sturgeon) & self.building.has_building(Building.fish_pond),
AnimalProduct.truffle: self.animal.has_animal(Animal.pig) & self.season.has_any_not_winter(),
AnimalProduct.void_egg: self.has(AnimalProduct.void_egg_starter), # Should also check void chicken if there was an alternative to obtain it without void egg
AnimalProduct.void_egg: self.has(AnimalProduct.void_egg_starter), # Should also check void chicken if there was an alternative to obtain it without void egg
AnimalProduct.wool: self.animal.has_animal(Animal.rabbit) | self.animal.has_animal(Animal.sheep),
AnimalProduct.slime_egg_green: self.has(Machine.slime_egg_press) & self.has(Loot.slime),
AnimalProduct.slime_egg_blue: self.has(Machine.slime_egg_press) & self.has(Loot.slime) & self.time.has_lived_months(3),
AnimalProduct.slime_egg_red: self.has(Machine.slime_egg_press) & self.has(Loot.slime) & self.time.has_lived_months(6),
AnimalProduct.slime_egg_purple: self.has(Machine.slime_egg_press) & self.has(Loot.slime) & self.time.has_lived_months(9),
AnimalProduct.slime_egg_tiger: self.can_fish_pond(Fish.lionfish, *(Forageable.ginger, Fruit.pineapple, Fruit.mango)) & self.time.has_lived_months(12) &
self.building.has_building(Building.slime_hutch) & self.monster.can_kill(Monster.tiger_slime),
AnimalProduct.duck_egg_starter: self.logic.false_, # It could be purchased at the Feast of the Winter Star, but it's random every year, so not considering it yet...
AnimalProduct.dinosaur_egg_starter: self.logic.false_, # Dinosaur eggs are also part of the museum rules, and I don't want to touch them yet.
AnimalProduct.slime_egg_tiger: self.has(Fish.lionfish) & self.building.has_building(Building.fish_pond),
AnimalProduct.duck_egg_starter: self.logic.false_, # It could be purchased at the Feast of the Winter Star, but it's random every year, so not considering it yet...
AnimalProduct.dinosaur_egg_starter: self.logic.false_, # Dinosaur eggs are also part of the museum rules, and I don't want to touch them yet.
AnimalProduct.egg_starter: self.logic.false_, # It could be purchased at the Desert Festival, but festival logic is quite a mess, so not considering it yet...
AnimalProduct.golden_egg_starter: self.received(AnimalProduct.golden_egg) & (self.money.can_spend_at(Region.ranch, 100000) | self.money.can_trade_at(Region.qi_walnut_room, Currency.qi_gem, 100)),
AnimalProduct.void_egg_starter: self.money.can_spend_at(Region.sewer, 5000) | (self.building.has_building(Building.fish_pond) & self.has(Fish.void_salmon)),
@@ -234,7 +233,7 @@ class StardewLogic(ReceivedLogicMixin, HasLogicMixin, RegionLogicMixin, Travelin
Forageable.secret_note: self.quest.has_magnifying_glass() & (self.ability.can_chop_trees() | self.mine.can_mine_in_the_mines_floor_1_40()), #
Fossil.bone_fragment: (self.region.can_reach(Region.dig_site) & self.tool.has_tool(Tool.pickaxe)) | self.monster.can_kill(Monster.skeleton),
Fossil.fossilized_leg: self.region.can_reach(Region.dig_site) & self.tool.has_tool(Tool.pickaxe),
Fossil.fossilized_ribs: self.region.can_reach(Region.island_south) & self.tool.has_tool(Tool.hoe) & self.received("Open Professor Snail Cave"),
Fossil.fossilized_ribs: self.region.can_reach(Region.island_south) & self.tool.has_tool(Tool.hoe),
Fossil.fossilized_skull: self.action.can_open_geode(Geode.golden_coconut),
Fossil.fossilized_spine: self.fishing.can_fish_at(Region.dig_site),
Fossil.fossilized_tail: self.action.can_pan_at(Region.dig_site, ToolMaterial.copper),
@@ -289,9 +288,9 @@ class StardewLogic(ReceivedLogicMixin, HasLogicMixin, RegionLogicMixin, Travelin
MetalBar.quartz: self.can_smelt(Mineral.quartz) | self.can_smelt("Fire Quartz") | (self.has(Machine.recycling_machine) & (self.has(Trash.broken_cd) | self.has(Trash.broken_glasses))),
MetalBar.radioactive: self.can_smelt(Ore.radioactive),
Ore.copper: self.mine.can_mine_in_the_mines_floor_1_40() | self.mine.can_mine_in_the_skull_cavern() | self.tool.has_tool(Tool.pan, ToolMaterial.copper),
Ore.gold: self.mine.can_mine_in_the_mines_floor_81_120() | self.mine.can_mine_in_the_skull_cavern() | self.tool.has_tool(Tool.pan, ToolMaterial.gold),
Ore.iridium: self.count(2, *(self.mine.can_mine_in_the_skull_cavern(), self.can_fish_pond(Fish.super_cucumber), self.tool.has_tool(Tool.pan, ToolMaterial.iridium))),
Ore.iron: self.mine.can_mine_in_the_mines_floor_41_80() | self.mine.can_mine_in_the_skull_cavern() | self.tool.has_tool(Tool.pan, ToolMaterial.iron),
Ore.gold: self.mine.can_mine_in_the_mines_floor_81_120() | self.mine.can_mine_in_the_skull_cavern() | self.tool.has_tool(Tool.pan, ToolMaterial.iron),
Ore.iridium: self.mine.can_mine_in_the_skull_cavern() | self.can_fish_pond(Fish.super_cucumber) | self.tool.has_tool(Tool.pan, ToolMaterial.gold),
Ore.iron: self.mine.can_mine_in_the_mines_floor_41_80() | self.mine.can_mine_in_the_skull_cavern() | self.tool.has_tool(Tool.pan, ToolMaterial.copper),
Ore.radioactive: self.ability.can_mine_perfectly() & self.region.can_reach(Region.qi_walnut_room),
RetainingSoil.basic: self.money.can_spend_at(Region.pierre_store, 100),
RetainingSoil.quality: self.time.has_year_two & self.money.can_spend_at(Region.pierre_store, 150),
@@ -382,8 +381,5 @@ class StardewLogic(ReceivedLogicMixin, HasLogicMixin, RegionLogicMixin, Travelin
def can_use_obelisk(self, obelisk: str) -> StardewRule:
return self.region.can_reach(Region.farm) & self.received(obelisk)
def can_fish_pond(self, fish: str, *items: str) -> StardewRule:
rule = self.building.has_building(Building.fish_pond) & self.has(fish)
if items:
rule = rule & self.has_all(*items)
return rule
def can_fish_pond(self, fish: str) -> StardewRule:
return self.building.has_building(Building.fish_pond) & self.has(fish)

View File

@@ -1,4 +1,9 @@
class Loot:
blue_slime_egg = "Blue Slime Egg"
red_slime_egg = "Red Slime Egg"
purple_slime_egg = "Purple Slime Egg"
green_slime_egg = "Green Slime Egg"
tiger_slime_egg = "Tiger Slime Egg"
slime = "Slime"
bug_meat = "Bug Meat"
bat_wing = "Bat Wing"

View File

@@ -11,7 +11,7 @@ class EntranceRandomizationAssertMixin:
non_progression_connections = [connection for connection in all_connections.values() if RandomizationFlag.BIT_NON_PROGRESSION in connection.flag]
for non_progression_connections in non_progression_connections:
with self.subTest(connection=non_progression_connections.name):
with self.subTest(connection=non_progression_connections):
self.assert_can_reach_entrance(non_progression_connections.name)

View File

@@ -12,14 +12,14 @@ from ...regions.regions import create_all_regions, create_all_connections
class TestVanillaRegionsConnectionsWithGingerIsland(unittest.TestCase):
def test_region_exits_lead_somewhere(self):
for region in vanilla_data.regions_with_ginger_island_by_name.values():
with self.subTest(region=region.name):
with self.subTest(region=region):
for exit_ in region.exits:
self.assertIn(exit_, vanilla_data.connections_with_ginger_island_by_name,
f"{region.name} is leading to {exit_} but it does not exist.")
def test_connection_lead_somewhere(self):
for connection in vanilla_data.connections_with_ginger_island_by_name.values():
with self.subTest(connection=connection.name):
with self.subTest(connection=connection):
self.assertIn(connection.destination, vanilla_data.regions_with_ginger_island_by_name,
f"{connection.name} is leading to {connection.destination} but it does not exist.")
@@ -27,14 +27,14 @@ class TestVanillaRegionsConnectionsWithGingerIsland(unittest.TestCase):
class TestVanillaRegionsConnectionsWithoutGingerIsland(unittest.TestCase):
def test_region_exits_lead_somewhere(self):
for region in vanilla_data.regions_without_ginger_island_by_name.values():
with self.subTest(region=region.name):
with self.subTest(region=region):
for exit_ in region.exits:
self.assertIn(exit_, vanilla_data.connections_without_ginger_island_by_name,
f"{region.name} is leading to {exit_} but it does not exist.")
def test_connection_lead_somewhere(self):
for connection in vanilla_data.connections_without_ginger_island_by_name.values():
with self.subTest(connection=connection.name):
with self.subTest(connection=connection):
self.assertIn(connection.destination, vanilla_data.regions_without_ginger_island_by_name,
f"{connection.name} is leading to {connection.destination} but it does not exist.")

View File

@@ -8,7 +8,7 @@ class TestNeedRegionToCatchFish(SVTestBase):
SeasonRandomization.internal_name: SeasonRandomization.option_disabled,
ElevatorProgression.internal_name: ElevatorProgression.option_vanilla,
SkillProgression.internal_name: SkillProgression.option_vanilla,
ToolProgression.internal_name: ToolProgression.option_progressive,
ToolProgression.internal_name: ToolProgression.option_vanilla,
Fishsanity.internal_name: Fishsanity.option_all,
ExcludeGingerIsland.internal_name: ExcludeGingerIsland.option_false,
SpecialOrderLocations.internal_name: SpecialOrderLocations.option_board_qi,
@@ -18,7 +18,7 @@ class TestNeedRegionToCatchFish(SVTestBase):
fish_and_items = {
Fish.crimsonfish: ["Beach Bridge"],
Fish.void_salmon: ["Railroad Boulder Removed", "Dark Talisman"],
Fish.woodskip: ["Progressive Axe", "Progressive Axe", "Progressive Weapon"], # For the ores to get the axe upgrades
Fish.woodskip: ["Glittering Boulder Removed", "Progressive Weapon"], # For the ores to get the axe upgrades
Fish.mutant_carp: ["Rusty Key"],
Fish.slimejack: ["Railroad Boulder Removed", "Rusty Key"],
Fish.lionfish: ["Boat Repair"],
@@ -26,8 +26,8 @@ class TestNeedRegionToCatchFish(SVTestBase):
Fish.stingray: ["Boat Repair", "Island Resort"],
Fish.ghostfish: ["Progressive Weapon"],
Fish.stonefish: ["Progressive Weapon"],
Fish.ice_pip: ["Progressive Weapon", "Progressive Weapon", "Progressive Pickaxe", "Progressive Pickaxe"],
Fish.lava_eel: ["Progressive Weapon", "Progressive Weapon", "Progressive Weapon", "Progressive Pickaxe", "Progressive Pickaxe", "Progressive Pickaxe"],
Fish.ice_pip: ["Progressive Weapon", "Progressive Weapon"],
Fish.lava_eel: ["Progressive Weapon", "Progressive Weapon", "Progressive Weapon"],
Fish.sandfish: ["Bus Repair"],
Fish.scorpion_carp: ["Desert Obelisk"],
# Starting the extended family quest requires having caught all the legendaries before, so they all have the rules of every other legendary
@@ -37,7 +37,6 @@ class TestNeedRegionToCatchFish(SVTestBase):
Fish.legend_ii: ["Beach Bridge", "Island Obelisk", "Island West Turtle", "Qi Walnut Room", "Rusty Key"],
Fish.ms_angler: ["Beach Bridge", "Island Obelisk", "Island West Turtle", "Qi Walnut Room", "Rusty Key"],
}
self.collect("Progressive Fishing Rod", 4)
self.original_state = self.multiworld.state.copy()
for fish in fish_and_items:
with self.subTest(f"Region rules for {fish}"):