diff --git a/worlds/stardew_valley/data/fish_data.py b/worlds/stardew_valley/data/fish_data.py index 26b1a0d58a81..dfa8891077ee 100644 --- a/worlds/stardew_valley/data/fish_data.py +++ b/worlds/stardew_valley/data/fish_data.py @@ -26,6 +26,7 @@ def __repr__(self): fresh_water = (Region.farm, Region.forest, Region.town, Region.mountain) ocean = (Region.beach,) +tide_pools = (Region.tide_pools,) town_river = (Region.town,) mountain_lake = (Region.mountain,) forest_pond = (Region.forest,) @@ -118,13 +119,13 @@ def create_fish(name: str, locations: Tuple[str, ...], seasons: Union[str, Tuple spook_fish = create_fish(Fish.spook_fish, night_market, season.winter, 60) angler = create_fish(Fish.angler, town_river, season.fall, 85, True, False) -crimsonfish = create_fish(Fish.crimsonfish, ocean, season.summer, 95, True, False) +crimsonfish = create_fish(Fish.crimsonfish, tide_pools, season.summer, 95, True, False) glacierfish = create_fish(Fish.glacierfish, forest_river, season.winter, 100, True, False) legend = create_fish(Fish.legend, mountain_lake, season.spring, 110, True, False) mutant_carp = create_fish(Fish.mutant_carp, sewers, season.all_seasons, 80, True, False) ms_angler = create_fish(Fish.ms_angler, town_river, season.fall, 85, True, True) -son_of_crimsonfish = create_fish(Fish.son_of_crimsonfish, ocean, season.summer, 95, True, True) +son_of_crimsonfish = create_fish(Fish.son_of_crimsonfish, tide_pools, season.summer, 95, True, True) glacierfish_jr = create_fish(Fish.glacierfish_jr, forest_river, season.winter, 100, True, True) legend_ii = create_fish(Fish.legend_ii, mountain_lake, season.spring, 110, True, True) radioactive_carp = create_fish(Fish.radioactive_carp, sewers, season.all_seasons, 80, True, True) diff --git a/worlds/stardew_valley/test/TestDynamicGoals.py b/worlds/stardew_valley/test/TestDynamicGoals.py index bfa58dd34063..b0e6d6c62655 100644 --- a/worlds/stardew_valley/test/TestDynamicGoals.py +++ b/worlds/stardew_valley/test/TestDynamicGoals.py @@ -27,6 +27,7 @@ def collect_fishing_abilities(tester: SVTestBase): 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("Beach Bridge"), 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) diff --git a/worlds/stardew_valley/test/__init__.py b/worlds/stardew_valley/test/__init__.py index c2c2a6a20baf..4dee0ebf6d66 100644 --- a/worlds/stardew_valley/test/__init__.py +++ b/worlds/stardew_valley/test/__init__.py @@ -258,15 +258,19 @@ def run_default_tests(self) -> bool: def collect_lots_of_money(self): 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)) + real_total_prog_items = self.multiworld.worlds[self.player].total_progression_items + required_prog_items = int(round(real_total_prog_items * 0.25)) for i in range(required_prog_items): self.multiworld.state.collect(self.world.create_item("Stardrop"), prevent_sweep=False) + self.multiworld.worlds[self.player].total_progression_items = real_total_prog_items def collect_all_the_money(self): 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)) + real_total_prog_items = self.multiworld.worlds[self.player].total_progression_items + required_prog_items = int(round(real_total_prog_items * 0.95)) for i in range(required_prog_items): self.multiworld.state.collect(self.world.create_item("Stardrop"), prevent_sweep=False) + self.multiworld.worlds[self.player].total_progression_items = real_total_prog_items def collect_everything(self): non_event_items = [item for item in self.multiworld.get_items() if item.code] diff --git a/worlds/stardew_valley/test/rules/TestFishing.py b/worlds/stardew_valley/test/rules/TestFishing.py new file mode 100644 index 000000000000..04a1528dd8b1 --- /dev/null +++ b/worlds/stardew_valley/test/rules/TestFishing.py @@ -0,0 +1,61 @@ +from ...options import SeasonRandomization, Friendsanity, FriendsanityHeartSize, Fishsanity, ExcludeGingerIsland, SkillProgression, ToolProgression, \ + ElevatorProgression, SpecialOrderLocations +from ...strings.fish_names import Fish +from ...test import SVTestBase + + +class TestNeedRegionToCatchFish(SVTestBase): + options = { + SeasonRandomization.internal_name: SeasonRandomization.option_disabled, + ElevatorProgression.internal_name: ElevatorProgression.option_vanilla, + SkillProgression.internal_name: SkillProgression.option_vanilla, + 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, + } + + def test_catch_fish_requires_region_unlock(self): + fish_and_items = { + Fish.crimsonfish: ["Beach Bridge"], + Fish.void_salmon: ["Railroad Boulder Removed", "Dark Talisman"], + 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"], + Fish.blue_discus: ["Island Obelisk", "Island West Turtle"], + Fish.stingray: ["Boat Repair", "Island Resort"], + Fish.ghostfish: ["Progressive Weapon"], + Fish.stonefish: ["Progressive Weapon"], + 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 + Fish.son_of_crimsonfish: ["Beach Bridge", "Island Obelisk", "Island West Turtle", "Qi Walnut Room", "Rusty Key"], + Fish.radioactive_carp: ["Beach Bridge", "Rusty Key", "Boat Repair", "Island West Turtle", "Qi Walnut Room"], + Fish.glacierfish_jr: ["Beach Bridge", "Island Obelisk", "Island West Turtle", "Qi Walnut Room", "Rusty Key"], + 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.original_state = self.multiworld.state.copy() + for fish in fish_and_items: + with self.subTest(f"Region rules for {fish}"): + self.collect_all_the_money() + item_names = fish_and_items[fish] + location = self.multiworld.get_location(f"Fishsanity: {fish}", self.player) + self.assert_reach_location_false(location, self.multiworld.state) + items = [] + for item_name in item_names: + items.append(self.collect(item_name)) + with self.subTest(f"{fish} can be reached with {item_names}"): + self.assert_reach_location_true(location, self.multiworld.state) + for item_required in items: + self.multiworld.state = self.original_state.copy() + with self.subTest(f"{fish} requires {item_required.name}"): + for item_to_collect in items: + if item_to_collect.name != item_required.name: + self.collect(item_to_collect) + self.assert_reach_location_false(location, self.multiworld.state) + + self.multiworld.state = self.original_state.copy()