|  | 
| 1 | 1 | import unittest | 
|  | 2 | +from argparse import Namespace | 
|  | 3 | +from typing import Type | 
| 2 | 4 | 
 | 
| 3 |  | -from BaseClasses import CollectionState | 
| 4 |  | -from worlds.AutoWorld import AutoWorldRegister, call_all | 
|  | 5 | +from BaseClasses import CollectionState, MultiWorld | 
|  | 6 | +from Fill import distribute_items_restrictive | 
|  | 7 | +from Options import ItemLinks | 
|  | 8 | +from worlds.AutoWorld import AutoWorldRegister, World, call_all | 
| 5 | 9 | from . import setup_solo_multiworld | 
| 6 | 10 | 
 | 
| 7 | 11 | 
 | 
| @@ -83,6 +87,47 @@ def test_items_in_datapackage(self): | 
| 83 | 87 |                 multiworld = setup_solo_multiworld(world_type) | 
| 84 | 88 |                 for item in multiworld.itempool: | 
| 85 | 89 |                     self.assertIn(item.name, world_type.item_name_to_id) | 
|  | 90 | +     | 
|  | 91 | +    def test_item_links(self) -> None: | 
|  | 92 | +        """ | 
|  | 93 | +        Tests item link creation by creating a multiworld of 2 worlds for every game and linking their items together. | 
|  | 94 | +        """ | 
|  | 95 | +        def setup_link_multiworld(world: Type[World], link_replace: bool) -> None: | 
|  | 96 | +            multiworld = MultiWorld(2) | 
|  | 97 | +            multiworld.game = {1: world.game, 2: world.game} | 
|  | 98 | +            multiworld.player_name = {1: "Linker 1", 2: "Linker 2"} | 
|  | 99 | +            multiworld.set_seed() | 
|  | 100 | +            item_link_group = [{ | 
|  | 101 | +                "name": "ItemLinkTest", | 
|  | 102 | +                "item_pool": ["Everything"], | 
|  | 103 | +                "link_replacement": link_replace, | 
|  | 104 | +                "replacement_item": None, | 
|  | 105 | +            }] | 
|  | 106 | +            args = Namespace() | 
|  | 107 | +            for name, option in world.options_dataclass.type_hints.items(): | 
|  | 108 | +                setattr(args, name, {1: option.from_any(option.default), 2: option.from_any(option.default)}) | 
|  | 109 | +            setattr(args, "item_links", | 
|  | 110 | +                    {1: ItemLinks.from_any(item_link_group), 2: ItemLinks.from_any(item_link_group)}) | 
|  | 111 | +            multiworld.set_options(args) | 
|  | 112 | +            multiworld.set_item_links() | 
|  | 113 | +            # groups get added to state during its constructor so this has to be after item links are set | 
|  | 114 | +            multiworld.state = CollectionState(multiworld) | 
|  | 115 | +            gen_steps = ("generate_early", "create_regions", "create_items", "set_rules", "connect_entrances", "generate_basic") | 
|  | 116 | +            for step in gen_steps: | 
|  | 117 | +                call_all(multiworld, step) | 
|  | 118 | +            # link the items together and attempt to fill | 
|  | 119 | +            multiworld.link_items() | 
|  | 120 | +            multiworld._all_state = None | 
|  | 121 | +            call_all(multiworld, "pre_fill") | 
|  | 122 | +            distribute_items_restrictive(multiworld) | 
|  | 123 | +            call_all(multiworld, "post_fill") | 
|  | 124 | +            self.assertTrue(multiworld.can_beat_game(CollectionState(multiworld)), f"seed = {multiworld.seed}") | 
|  | 125 | + | 
|  | 126 | +        for game_name, world_type in AutoWorldRegister.world_types.items(): | 
|  | 127 | +            with self.subTest("Can generate with link replacement", game=game_name): | 
|  | 128 | +                setup_link_multiworld(world_type, True) | 
|  | 129 | +            with self.subTest("Can generate without link replacement", game=game_name): | 
|  | 130 | +                setup_link_multiworld(world_type, False) | 
| 86 | 131 | 
 | 
| 87 | 132 |     def test_itempool_not_modified(self): | 
| 88 | 133 |         """Test that worlds don't modify the itempool after `create_items`""" | 
|  | 
0 commit comments