Stardew Valley: 5.x.x - The Allsanity Update (#2764)

Major Content update for Stardew Valley, including the following features

- Major performance improvements all across the Stardew Valley apworld, including a significant reduction in the test time
- Randomized Farm Type
- Bundles rework (Remixed Bundles and Missing Bundle!)
- New Settings:
  * Shipsanity - Shipping individual items
  * Monstersanity - Slaying monsters
  * Cooksanity - Cooking individual recipes
  * Chefsanity - Learning individual recipes
  * Craftsanity - Crafting individual items
- New Goals:
  * Protector of the Valley - Complete every monster slayer goal
  * Full Shipment - Ship every item
  * Craftmaster - Craft every item
  * Gourmet Chef - Cook every recipe
  * Legend - Earn 10 000 000g
  * Mystery of the Stardrops - Find every stardrop (Maguffin Hunt)
  * Allsanity - Complete every check in your slot
- Building Shuffle: Cheaper options
- Tool Shuffle: Cheaper options
- Money rework
- New traps
- New isolated checks and items, including the farm cave, the movie theater, etc
- Mod Support: SVE [Albrekka]
- Mod Support: Distant Lands [Albrekka]
- Mod Support: Hat Mouse Lacey [Albrekka]
- Mod Support: Boarding House [Albrekka]

Co-authored-by: Witchybun <elnendil@gmail.com>
Co-authored-by: Witchybun <96719127+Witchybun@users.noreply.github.com>
Co-authored-by: Jouramie <jouramie@hotmail.com>
Co-authored-by: Alchav <59858495+Alchav@users.noreply.github.com>
This commit is contained in:
agilbert1412
2024-03-15 15:05:14 +03:00
committed by GitHub
parent f7da833572
commit 52e65e208e
177 changed files with 17815 additions and 6863 deletions

View File

@@ -1,11 +1,13 @@
from .. import SVTestBase
from ... import options
from ...mods.mod_data import ModNames
from ...options import Mods, BackpackProgression
class TestBiggerBackpackVanilla(SVTestBase):
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_vanilla,
options.Mods.internal_name: ModNames.big_backpack}
options = {
BackpackProgression.internal_name: BackpackProgression.option_vanilla,
Mods.internal_name: ModNames.big_backpack
}
def test_no_backpack(self):
with self.subTest(check="no items"):
@@ -20,8 +22,10 @@ class TestBiggerBackpackVanilla(SVTestBase):
class TestBiggerBackpackProgressive(SVTestBase):
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_progressive,
options.Mods.internal_name: ModNames.big_backpack}
options = {
BackpackProgression.internal_name: BackpackProgression.option_progressive,
Mods.internal_name: ModNames.big_backpack
}
def test_backpack(self):
with self.subTest(check="has items"):
@@ -36,8 +40,10 @@ class TestBiggerBackpackProgressive(SVTestBase):
class TestBiggerBackpackEarlyProgressive(TestBiggerBackpackProgressive):
options = {options.BackpackProgression.internal_name: options.BackpackProgression.option_early_progressive,
options.Mods.internal_name: ModNames.big_backpack}
options = {
BackpackProgression.internal_name: BackpackProgression.option_early_progressive,
Mods.internal_name: ModNames.big_backpack
}
def test_backpack(self):
super().test_backpack()

View File

@@ -0,0 +1,226 @@
import unittest
from typing import Set
from ...data.fish_data import get_fish_for_mods
from ...mods.mod_data import ModNames
from ...strings.fish_names import Fish, SVEFish
no_mods: Set[str] = set()
sve: Set[str] = {ModNames.sve}
class TestGetFishForMods(unittest.TestCase):
def test_no_mods_all_vanilla_fish(self):
all_fish = get_fish_for_mods(no_mods)
fish_names = {fish.name for fish in all_fish}
self.assertIn(Fish.albacore, fish_names)
self.assertIn(Fish.anchovy, fish_names)
self.assertIn(Fish.blue_discus, fish_names)
self.assertIn(Fish.bream, fish_names)
self.assertIn(Fish.bullhead, fish_names)
self.assertIn(Fish.carp, fish_names)
self.assertIn(Fish.catfish, fish_names)
self.assertIn(Fish.chub, fish_names)
self.assertIn(Fish.dorado, fish_names)
self.assertIn(Fish.eel, fish_names)
self.assertIn(Fish.flounder, fish_names)
self.assertIn(Fish.ghostfish, fish_names)
self.assertIn(Fish.halibut, fish_names)
self.assertIn(Fish.herring, fish_names)
self.assertIn(Fish.ice_pip, fish_names)
self.assertIn(Fish.largemouth_bass, fish_names)
self.assertIn(Fish.lava_eel, fish_names)
self.assertIn(Fish.lingcod, fish_names)
self.assertIn(Fish.lionfish, fish_names)
self.assertIn(Fish.midnight_carp, fish_names)
self.assertIn(Fish.octopus, fish_names)
self.assertIn(Fish.perch, fish_names)
self.assertIn(Fish.pike, fish_names)
self.assertIn(Fish.pufferfish, fish_names)
self.assertIn(Fish.rainbow_trout, fish_names)
self.assertIn(Fish.red_mullet, fish_names)
self.assertIn(Fish.red_snapper, fish_names)
self.assertIn(Fish.salmon, fish_names)
self.assertIn(Fish.sandfish, fish_names)
self.assertIn(Fish.sardine, fish_names)
self.assertIn(Fish.scorpion_carp, fish_names)
self.assertIn(Fish.sea_cucumber, fish_names)
self.assertIn(Fish.shad, fish_names)
self.assertIn(Fish.slimejack, fish_names)
self.assertIn(Fish.smallmouth_bass, fish_names)
self.assertIn(Fish.squid, fish_names)
self.assertIn(Fish.stingray, fish_names)
self.assertIn(Fish.stonefish, fish_names)
self.assertIn(Fish.sturgeon, fish_names)
self.assertIn(Fish.sunfish, fish_names)
self.assertIn(Fish.super_cucumber, fish_names)
self.assertIn(Fish.tiger_trout, fish_names)
self.assertIn(Fish.tilapia, fish_names)
self.assertIn(Fish.tuna, fish_names)
self.assertIn(Fish.void_salmon, fish_names)
self.assertIn(Fish.walleye, fish_names)
self.assertIn(Fish.woodskip, fish_names)
self.assertIn(Fish.blob_fish, fish_names)
self.assertIn(Fish.midnight_squid, fish_names)
self.assertIn(Fish.spook_fish, fish_names)
self.assertIn(Fish.angler, fish_names)
self.assertIn(Fish.crimsonfish, fish_names)
self.assertIn(Fish.glacierfish, fish_names)
self.assertIn(Fish.legend, fish_names)
self.assertIn(Fish.mutant_carp, fish_names)
self.assertIn(Fish.ms_angler, fish_names)
self.assertIn(Fish.son_of_crimsonfish, fish_names)
self.assertIn(Fish.glacierfish_jr, fish_names)
self.assertIn(Fish.legend_ii, fish_names)
self.assertIn(Fish.radioactive_carp, fish_names)
self.assertIn(Fish.clam, fish_names)
self.assertIn(Fish.cockle, fish_names)
self.assertIn(Fish.crab, fish_names)
self.assertIn(Fish.crayfish, fish_names)
self.assertIn(Fish.lobster, fish_names)
self.assertIn(Fish.mussel, fish_names)
self.assertIn(Fish.oyster, fish_names)
self.assertIn(Fish.periwinkle, fish_names)
self.assertIn(Fish.shrimp, fish_names)
self.assertIn(Fish.snail, fish_names)
def test_no_mods_no_sve_fish(self):
all_fish = get_fish_for_mods(no_mods)
fish_names = {fish.name for fish in all_fish}
self.assertNotIn(SVEFish.baby_lunaloo, fish_names)
self.assertNotIn(SVEFish.bonefish, fish_names)
self.assertNotIn(SVEFish.bull_trout, fish_names)
self.assertNotIn(SVEFish.butterfish, fish_names)
self.assertNotIn(SVEFish.clownfish, fish_names)
self.assertNotIn(SVEFish.daggerfish, fish_names)
self.assertNotIn(SVEFish.frog, fish_names)
self.assertNotIn(SVEFish.gemfish, fish_names)
self.assertNotIn(SVEFish.goldenfish, fish_names)
self.assertNotIn(SVEFish.grass_carp, fish_names)
self.assertNotIn(SVEFish.king_salmon, fish_names)
self.assertNotIn(SVEFish.kittyfish, fish_names)
self.assertNotIn(SVEFish.lunaloo, fish_names)
self.assertNotIn(SVEFish.meteor_carp, fish_names)
self.assertNotIn(SVEFish.minnow, fish_names)
self.assertNotIn(SVEFish.puppyfish, fish_names)
self.assertNotIn(SVEFish.radioactive_bass, fish_names)
self.assertNotIn(SVEFish.seahorse, fish_names)
self.assertNotIn(SVEFish.shiny_lunaloo, fish_names)
self.assertNotIn(SVEFish.snatcher_worm, fish_names)
self.assertNotIn(SVEFish.starfish, fish_names)
self.assertNotIn(SVEFish.torpedo_trout, fish_names)
self.assertNotIn(SVEFish.undeadfish, fish_names)
self.assertNotIn(SVEFish.void_eel, fish_names)
self.assertNotIn(SVEFish.water_grub, fish_names)
self.assertNotIn(SVEFish.sea_sponge, fish_names)
self.assertNotIn(SVEFish.dulse_seaweed, fish_names)
def test_sve_all_vanilla_fish(self):
all_fish = get_fish_for_mods(no_mods)
fish_names = {fish.name for fish in all_fish}
self.assertIn(Fish.albacore, fish_names)
self.assertIn(Fish.anchovy, fish_names)
self.assertIn(Fish.blue_discus, fish_names)
self.assertIn(Fish.bream, fish_names)
self.assertIn(Fish.bullhead, fish_names)
self.assertIn(Fish.carp, fish_names)
self.assertIn(Fish.catfish, fish_names)
self.assertIn(Fish.chub, fish_names)
self.assertIn(Fish.dorado, fish_names)
self.assertIn(Fish.eel, fish_names)
self.assertIn(Fish.flounder, fish_names)
self.assertIn(Fish.ghostfish, fish_names)
self.assertIn(Fish.halibut, fish_names)
self.assertIn(Fish.herring, fish_names)
self.assertIn(Fish.ice_pip, fish_names)
self.assertIn(Fish.largemouth_bass, fish_names)
self.assertIn(Fish.lava_eel, fish_names)
self.assertIn(Fish.lingcod, fish_names)
self.assertIn(Fish.lionfish, fish_names)
self.assertIn(Fish.midnight_carp, fish_names)
self.assertIn(Fish.octopus, fish_names)
self.assertIn(Fish.perch, fish_names)
self.assertIn(Fish.pike, fish_names)
self.assertIn(Fish.pufferfish, fish_names)
self.assertIn(Fish.rainbow_trout, fish_names)
self.assertIn(Fish.red_mullet, fish_names)
self.assertIn(Fish.red_snapper, fish_names)
self.assertIn(Fish.salmon, fish_names)
self.assertIn(Fish.sandfish, fish_names)
self.assertIn(Fish.sardine, fish_names)
self.assertIn(Fish.scorpion_carp, fish_names)
self.assertIn(Fish.sea_cucumber, fish_names)
self.assertIn(Fish.shad, fish_names)
self.assertIn(Fish.slimejack, fish_names)
self.assertIn(Fish.smallmouth_bass, fish_names)
self.assertIn(Fish.squid, fish_names)
self.assertIn(Fish.stingray, fish_names)
self.assertIn(Fish.stonefish, fish_names)
self.assertIn(Fish.sturgeon, fish_names)
self.assertIn(Fish.sunfish, fish_names)
self.assertIn(Fish.super_cucumber, fish_names)
self.assertIn(Fish.tiger_trout, fish_names)
self.assertIn(Fish.tilapia, fish_names)
self.assertIn(Fish.tuna, fish_names)
self.assertIn(Fish.void_salmon, fish_names)
self.assertIn(Fish.walleye, fish_names)
self.assertIn(Fish.woodskip, fish_names)
self.assertIn(Fish.blob_fish, fish_names)
self.assertIn(Fish.midnight_squid, fish_names)
self.assertIn(Fish.spook_fish, fish_names)
self.assertIn(Fish.angler, fish_names)
self.assertIn(Fish.crimsonfish, fish_names)
self.assertIn(Fish.glacierfish, fish_names)
self.assertIn(Fish.legend, fish_names)
self.assertIn(Fish.mutant_carp, fish_names)
self.assertIn(Fish.ms_angler, fish_names)
self.assertIn(Fish.son_of_crimsonfish, fish_names)
self.assertIn(Fish.glacierfish_jr, fish_names)
self.assertIn(Fish.legend_ii, fish_names)
self.assertIn(Fish.radioactive_carp, fish_names)
self.assertIn(Fish.clam, fish_names)
self.assertIn(Fish.cockle, fish_names)
self.assertIn(Fish.crab, fish_names)
self.assertIn(Fish.crayfish, fish_names)
self.assertIn(Fish.lobster, fish_names)
self.assertIn(Fish.mussel, fish_names)
self.assertIn(Fish.oyster, fish_names)
self.assertIn(Fish.periwinkle, fish_names)
self.assertIn(Fish.shrimp, fish_names)
self.assertIn(Fish.snail, fish_names)
def test_sve_has_sve_fish(self):
all_fish = get_fish_for_mods(sve)
fish_names = {fish.name for fish in all_fish}
self.assertIn(SVEFish.baby_lunaloo, fish_names)
self.assertIn(SVEFish.bonefish, fish_names)
self.assertIn(SVEFish.bull_trout, fish_names)
self.assertIn(SVEFish.butterfish, fish_names)
self.assertIn(SVEFish.clownfish, fish_names)
self.assertIn(SVEFish.daggerfish, fish_names)
self.assertIn(SVEFish.frog, fish_names)
self.assertIn(SVEFish.gemfish, fish_names)
self.assertIn(SVEFish.goldenfish, fish_names)
self.assertIn(SVEFish.grass_carp, fish_names)
self.assertIn(SVEFish.king_salmon, fish_names)
self.assertIn(SVEFish.kittyfish, fish_names)
self.assertIn(SVEFish.lunaloo, fish_names)
self.assertIn(SVEFish.meteor_carp, fish_names)
self.assertIn(SVEFish.minnow, fish_names)
self.assertIn(SVEFish.puppyfish, fish_names)
self.assertIn(SVEFish.radioactive_bass, fish_names)
self.assertIn(SVEFish.seahorse, fish_names)
self.assertIn(SVEFish.shiny_lunaloo, fish_names)
self.assertIn(SVEFish.snatcher_worm, fish_names)
self.assertIn(SVEFish.starfish, fish_names)
self.assertIn(SVEFish.torpedo_trout, fish_names)
self.assertIn(SVEFish.undeadfish, fish_names)
self.assertIn(SVEFish.void_eel, fish_names)
self.assertIn(SVEFish.water_grub, fish_names)
self.assertIn(SVEFish.sea_sponge, fish_names)
self.assertIn(SVEFish.dulse_seaweed, fish_names)

View File

@@ -0,0 +1,132 @@
import unittest
from typing import Set
from ...data.villagers_data import get_villagers_for_mods
from ...mods.mod_data import ModNames
from ...strings.villager_names import NPC, ModNPC
no_mods: Set[str] = set()
sve: Set[str] = {ModNames.sve}
class TestGetVillagersForMods(unittest.TestCase):
def test_no_mods_all_vanilla_villagers(self):
villagers = get_villagers_for_mods(no_mods)
villager_names = {villager.name for villager in villagers}
self.assertIn(NPC.alex, villager_names)
self.assertIn(NPC.elliott, villager_names)
self.assertIn(NPC.harvey, villager_names)
self.assertIn(NPC.sam, villager_names)
self.assertIn(NPC.sebastian, villager_names)
self.assertIn(NPC.shane, villager_names)
self.assertIn(NPC.abigail, villager_names)
self.assertIn(NPC.emily, villager_names)
self.assertIn(NPC.haley, villager_names)
self.assertIn(NPC.leah, villager_names)
self.assertIn(NPC.maru, villager_names)
self.assertIn(NPC.penny, villager_names)
self.assertIn(NPC.caroline, villager_names)
self.assertIn(NPC.clint, villager_names)
self.assertIn(NPC.demetrius, villager_names)
self.assertIn(NPC.dwarf, villager_names)
self.assertIn(NPC.evelyn, villager_names)
self.assertIn(NPC.george, villager_names)
self.assertIn(NPC.gus, villager_names)
self.assertIn(NPC.jas, villager_names)
self.assertIn(NPC.jodi, villager_names)
self.assertIn(NPC.kent, villager_names)
self.assertIn(NPC.krobus, villager_names)
self.assertIn(NPC.leo, villager_names)
self.assertIn(NPC.lewis, villager_names)
self.assertIn(NPC.linus, villager_names)
self.assertIn(NPC.marnie, villager_names)
self.assertIn(NPC.pam, villager_names)
self.assertIn(NPC.pierre, villager_names)
self.assertIn(NPC.robin, villager_names)
self.assertIn(NPC.sandy, villager_names)
self.assertIn(NPC.vincent, villager_names)
self.assertIn(NPC.willy, villager_names)
self.assertIn(NPC.wizard, villager_names)
def test_no_mods_no_mod_villagers(self):
villagers = get_villagers_for_mods(no_mods)
villager_names = {villager.name for villager in villagers}
self.assertNotIn(ModNPC.alec, villager_names)
self.assertNotIn(ModNPC.ayeisha, villager_names)
self.assertNotIn(ModNPC.delores, villager_names)
self.assertNotIn(ModNPC.eugene, villager_names)
self.assertNotIn(ModNPC.jasper, villager_names)
self.assertNotIn(ModNPC.juna, villager_names)
self.assertNotIn(ModNPC.mr_ginger, villager_names)
self.assertNotIn(ModNPC.riley, villager_names)
self.assertNotIn(ModNPC.shiko, villager_names)
self.assertNotIn(ModNPC.wellwick, villager_names)
self.assertNotIn(ModNPC.yoba, villager_names)
self.assertNotIn(ModNPC.lance, villager_names)
self.assertNotIn(ModNPC.apples, villager_names)
self.assertNotIn(ModNPC.claire, villager_names)
self.assertNotIn(ModNPC.olivia, villager_names)
self.assertNotIn(ModNPC.sophia, villager_names)
self.assertNotIn(ModNPC.victor, villager_names)
self.assertNotIn(ModNPC.andy, villager_names)
self.assertNotIn(ModNPC.gunther, villager_names)
self.assertNotIn(ModNPC.martin, villager_names)
self.assertNotIn(ModNPC.marlon, villager_names)
self.assertNotIn(ModNPC.morgan, villager_names)
self.assertNotIn(ModNPC.morris, villager_names)
self.assertNotIn(ModNPC.scarlett, villager_names)
self.assertNotIn(ModNPC.susan, villager_names)
self.assertNotIn(ModNPC.goblin, villager_names)
self.assertNotIn(ModNPC.alecto, villager_names)
def test_sve_has_sve_villagers(self):
villagers = get_villagers_for_mods(sve)
villager_names = {villager.name for villager in villagers}
self.assertIn(ModNPC.lance, villager_names)
self.assertIn(ModNPC.apples, villager_names)
self.assertIn(ModNPC.claire, villager_names)
self.assertIn(ModNPC.olivia, villager_names)
self.assertIn(ModNPC.sophia, villager_names)
self.assertIn(ModNPC.victor, villager_names)
self.assertIn(ModNPC.andy, villager_names)
self.assertIn(ModNPC.gunther, villager_names)
self.assertIn(ModNPC.martin, villager_names)
self.assertIn(ModNPC.marlon, villager_names)
self.assertIn(ModNPC.morgan, villager_names)
self.assertIn(ModNPC.morris, villager_names)
self.assertIn(ModNPC.scarlett, villager_names)
self.assertIn(ModNPC.susan, villager_names)
def test_sve_has_no_other_mod_villagers(self):
villagers = get_villagers_for_mods(sve)
villager_names = {villager.name for villager in villagers}
self.assertNotIn(ModNPC.alec, villager_names)
self.assertNotIn(ModNPC.ayeisha, villager_names)
self.assertNotIn(ModNPC.delores, villager_names)
self.assertNotIn(ModNPC.eugene, villager_names)
self.assertNotIn(ModNPC.jasper, villager_names)
self.assertNotIn(ModNPC.juna, villager_names)
self.assertNotIn(ModNPC.mr_ginger, villager_names)
self.assertNotIn(ModNPC.riley, villager_names)
self.assertNotIn(ModNPC.shiko, villager_names)
self.assertNotIn(ModNPC.wellwick, villager_names)
self.assertNotIn(ModNPC.yoba, villager_names)
self.assertNotIn(ModNPC.goblin, villager_names)
self.assertNotIn(ModNPC.alecto, villager_names)
def test_no_mods_wizard_is_not_bachelor(self):
villagers = get_villagers_for_mods(no_mods)
villagers_by_name = {villager.name: villager for villager in villagers}
self.assertFalse(villagers_by_name[NPC.wizard].bachelor)
self.assertEqual(villagers_by_name[NPC.wizard].mod_name, ModNames.vanilla)
def test_sve_wizard_is_bachelor(self):
villagers = get_villagers_for_mods(sve)
villagers_by_name = {villager.name: villager for villager in villagers}
self.assertTrue(villagers_by_name[NPC.wizard].bachelor)
self.assertEqual(villagers_by_name[NPC.wizard].mod_name, ModNames.sve)

View File

@@ -1,69 +1,74 @@
from typing import List, Union
import unittest
import random
import sys
from BaseClasses import MultiWorld
from ...mods.mod_data import all_mods
from .. import setup_solo_multiworld, SVTestBase, SVTestCase, allsanity_options_without_mods
from ..TestOptions import basic_checks
from BaseClasses import get_seed
from .. import setup_solo_multiworld, SVTestBase, SVTestCase, allsanity_options_without_mods, allsanity_options_with_mods, complete_options_with_default
from ..assertion import ModAssertMixin, WorldAssertMixin
from ... import items, Group, ItemClassification
from ...regions import RandomizationFlag, create_final_connections, randomize_connections, create_final_regions
from ...items import item_table, items_by_group
from ...locations import location_table
from ...options import Mods, EntranceRandomization, Friendsanity, SeasonRandomization, SpecialOrderLocations, ExcludeGingerIsland, TrapItems
from ... import options
from ...items import items_by_group
from ...mods.mod_data import all_mods
from ...regions import RandomizationFlag, randomize_connections, create_final_connections_and_regions
def check_stray_mod_items(chosen_mods: Union[List[str], str], tester: unittest.TestCase, multiworld: MultiWorld):
if isinstance(chosen_mods, str):
chosen_mods = [chosen_mods]
for multiworld_item in multiworld.get_items():
item = item_table[multiworld_item.name]
tester.assertTrue(item.mod_name is None or item.mod_name in chosen_mods)
for multiworld_location in multiworld.get_locations():
if multiworld_location.event:
continue
location = location_table[multiworld_location.name]
tester.assertTrue(location.mod_name is None or location.mod_name in chosen_mods)
class TestGenerateModsOptions(SVTestCase):
class TestGenerateModsOptions(WorldAssertMixin, ModAssertMixin, SVTestCase):
def test_given_single_mods_when_generate_then_basic_checks(self):
for mod in all_mods:
with self.subTest(f"Mod: {mod}"):
multi_world = setup_solo_multiworld({Mods: mod})
basic_checks(self, multi_world)
check_stray_mod_items(mod, self, multi_world)
with self.solo_world_sub_test(f"Mod: {mod}", {options.Mods: mod}, dirty_state=True) as (multi_world, _):
self.assert_basic_checks(multi_world)
self.assert_stray_mod_items(mod, multi_world)
def test_given_mod_names_when_generate_paired_with_entrance_randomizer_then_basic_checks(self):
for option in EntranceRandomization.options:
for option in options.EntranceRandomization.options:
for mod in all_mods:
with self.subTest(f"entrance_randomization: {option}, Mod: {mod}"):
multiworld = setup_solo_multiworld({EntranceRandomization.internal_name: option, Mods: mod})
basic_checks(self, multiworld)
check_stray_mod_items(mod, self, multiworld)
if self.skip_extra_tests:
return # assume the rest will work as well
world_options = {
options.EntranceRandomization.internal_name: options.EntranceRandomization.options[option],
options.Mods: mod
}
with self.solo_world_sub_test(f"entrance_randomization: {option}, Mod: {mod}", world_options, dirty_state=True) as (multi_world, _):
self.assert_basic_checks(multi_world)
self.assert_stray_mod_items(mod, multi_world)
def test_allsanity_all_mods_when_generate_then_basic_checks(self):
with self.solo_world_sub_test(world_options=allsanity_options_with_mods(), dirty_state=True) as (multi_world, _):
self.assert_basic_checks(multi_world)
def test_allsanity_all_mods_exclude_island_when_generate_then_basic_checks(self):
world_options = allsanity_options_with_mods()
world_options.update({options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_true})
with self.solo_world_sub_test(world_options=world_options, dirty_state=True) as (multi_world, _):
self.assert_basic_checks(multi_world)
class TestBaseLocationDependencies(SVTestBase):
options = {
options.Mods.internal_name: all_mods,
options.ToolProgression.internal_name: options.ToolProgression.option_progressive,
options.SeasonRandomization.internal_name: options.SeasonRandomization.option_randomized
}
class TestBaseItemGeneration(SVTestBase):
options = {
Friendsanity.internal_name: Friendsanity.option_all_with_marriage,
SeasonRandomization.internal_name: SeasonRandomization.option_progressive,
SpecialOrderLocations.internal_name: SpecialOrderLocations.option_board_qi,
Mods.internal_name: all_mods
options.Friendsanity.internal_name: options.Friendsanity.option_all_with_marriage,
options.SeasonRandomization.internal_name: options.SeasonRandomization.option_progressive,
options.SpecialOrderLocations.internal_name: options.SpecialOrderLocations.option_board_qi,
options.Shipsanity.internal_name: options.Shipsanity.option_everything,
options.Chefsanity.internal_name: options.Chefsanity.option_all,
options.Craftsanity.internal_name: options.Craftsanity.option_all,
options.Mods.internal_name: all_mods
}
def test_all_progression_items_are_added_to_the_pool(self):
all_created_items = [item.name for item in self.multiworld.itempool]
# Ignore all the stuff that the algorithm chooses one of, instead of all, to fulfill logical progression
items_to_ignore = [event.name for event in items.events]
items_to_ignore.extend(deprecated.name for deprecated in items.items_by_group[Group.DEPRECATED])
items_to_ignore.extend(season.name for season in items.items_by_group[Group.SEASON])
items_to_ignore.extend(weapon.name for weapon in items.items_by_group[Group.WEAPON])
items_to_ignore.extend(footwear.name for footwear in items.items_by_group[Group.FOOTWEAR])
items_to_ignore.extend(baby.name for baby in items.items_by_group[Group.BABY])
items_to_ignore.extend(resource_pack.name for resource_pack in items.items_by_group[Group.RESOURCE_PACK])
items_to_ignore.append("The Gateway Gazette")
progression_items = [item for item in items.all_items if item.classification is ItemClassification.progression
and item.name not in items_to_ignore]
for progression_item in progression_items:
@@ -73,21 +78,25 @@ class TestBaseItemGeneration(SVTestBase):
class TestNoGingerIslandModItemGeneration(SVTestBase):
options = {
Friendsanity.internal_name: Friendsanity.option_all_with_marriage,
SeasonRandomization.internal_name: SeasonRandomization.option_progressive,
ExcludeGingerIsland.internal_name: ExcludeGingerIsland.option_true,
Mods.internal_name: all_mods
options.Friendsanity.internal_name: options.Friendsanity.option_all_with_marriage,
options.SeasonRandomization.internal_name: options.SeasonRandomization.option_progressive,
options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_true,
options.Shipsanity.internal_name: options.Shipsanity.option_everything,
options.Chefsanity.internal_name: options.Chefsanity.option_all,
options.Craftsanity.internal_name: options.Craftsanity.option_all,
options.Mods.internal_name: all_mods
}
def test_all_progression_items_except_island_are_added_to_the_pool(self):
all_created_items = [item.name for item in self.multiworld.itempool]
# Ignore all the stuff that the algorithm chooses one of, instead of all, to fulfill logical progression
items_to_ignore = [event.name for event in items.events]
items_to_ignore.extend(deprecated.name for deprecated in items.items_by_group[Group.DEPRECATED])
items_to_ignore.extend(season.name for season in items.items_by_group[Group.SEASON])
items_to_ignore.extend(weapon.name for weapon in items.items_by_group[Group.WEAPON])
items_to_ignore.extend(footwear.name for footwear in items.items_by_group[Group.FOOTWEAR])
items_to_ignore.extend(baby.name for baby in items.items_by_group[Group.BABY])
items_to_ignore.extend(resource_pack.name for resource_pack in items.items_by_group[Group.RESOURCE_PACK])
items_to_ignore.append("The Gateway Gazette")
progression_items = [item for item in items.all_items if item.classification is ItemClassification.progression
and item.name not in items_to_ignore]
for progression_item in progression_items:
@@ -101,44 +110,41 @@ class TestNoGingerIslandModItemGeneration(SVTestBase):
class TestModEntranceRando(SVTestCase):
def test_mod_entrance_randomization(self):
for option, flag in [(options.EntranceRandomization.option_pelican_town, RandomizationFlag.PELICAN_TOWN),
(options.EntranceRandomization.option_non_progression, RandomizationFlag.NON_PROGRESSION),
(options.EntranceRandomization.option_buildings, RandomizationFlag.BUILDINGS)]:
sv_options = complete_options_with_default({
options.EntranceRandomization.internal_name: option,
options.ExcludeGingerIsland.internal_name: options.ExcludeGingerIsland.option_false,
options.Mods.internal_name: all_mods
})
seed = get_seed()
rand = random.Random(seed)
with self.subTest(option=option, flag=flag, seed=seed):
final_connections, final_regions = create_final_connections_and_regions(sv_options)
for option, flag in [(EntranceRandomization.option_pelican_town, RandomizationFlag.PELICAN_TOWN),
(EntranceRandomization.option_non_progression, RandomizationFlag.NON_PROGRESSION),
(EntranceRandomization.option_buildings, RandomizationFlag.BUILDINGS)]:
with self.subTest(option=option, flag=flag):
seed = random.randrange(sys.maxsize)
rand = random.Random(seed)
world_options = {EntranceRandomization.internal_name: option,
ExcludeGingerIsland.internal_name: ExcludeGingerIsland.option_false,
Mods.internal_name: all_mods}
multiworld = setup_solo_multiworld(world_options)
world = multiworld.worlds[1]
final_regions = create_final_regions(world.options)
final_connections = create_final_connections(world.options)
_, randomized_connections = randomize_connections(rand, sv_options, final_regions, final_connections)
regions_by_name = {region.name: region for region in final_regions}
_, randomized_connections = randomize_connections(rand, world.options, regions_by_name)
for connection in final_connections:
for connection_name in final_connections:
connection = final_connections[connection_name]
if flag in connection.flag:
connection_in_randomized = connection.name in randomized_connections
connection_in_randomized = connection_name in randomized_connections
reverse_in_randomized = connection.reverse in randomized_connections
self.assertTrue(connection_in_randomized,
f"Connection {connection.name} should be randomized but it is not in the output. Seed = {seed}")
self.assertTrue(reverse_in_randomized,
f"Connection {connection.reverse} should be randomized but it is not in the output. Seed = {seed}")
self.assertTrue(connection_in_randomized, f"Connection {connection_name} should be randomized but it is not in the output")
self.assertTrue(reverse_in_randomized, f"Connection {connection.reverse} should be randomized but it is not in the output.")
self.assertEqual(len(set(randomized_connections.values())), len(randomized_connections.values()),
f"Connections are duplicated in randomization. Seed = {seed}")
f"Connections are duplicated in randomization.")
class TestModTraps(SVTestCase):
def test_given_traps_when_generate_then_all_traps_in_pool(self):
for value in TrapItems.options:
for value in options.TrapItems.options:
if value == "no_traps":
continue
world_options = allsanity_options_without_mods()
world_options.update({TrapItems.internal_name: TrapItems.options[value], Mods: "Magic"})
world_options.update({options.TrapItems.internal_name: options.TrapItems.options[value], options.Mods: "Magic"})
multi_world = setup_solo_multiworld(world_options)
trap_items = [item_data.name for item_data in items_by_group[Group.TRAP] if Group.DEPRECATED not in item_data.groups]
multiworld_items = [item.name for item in multi_world.get_items()]