Esempio n. 1
0
    def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata) -> "Preset":
        from randovania.interface_common.preset_manager import PresetManager
        manager: PresetManager = metadata["manager"]

        included_presets = [
            versioned.get_preset() for versioned in manager.included_presets
        ]

        is_custom_preset = bitpacking.decode_bool(decoder)
        reference = decoder.decode_element(included_presets)
        if is_custom_preset:
            preset = Preset(
                name="{} Custom".format(reference.name),
                description="A customized preset.",
                base_preset_name=reference.name,
                game=reference.game,
                configuration=reference.configuration.bit_pack_unpack(
                    decoder, {"reference": reference.configuration}),
            )
        else:
            preset = reference

        included_data_hash = decoder.decode_single(256)
        expected_data_hash = _dictionary_byte_hash(
            preset.configuration.game_data)
        if included_data_hash != expected_data_hash:
            raise ValueError(
                "Given permalink is for a Randovania database with hash '{}', "
                "but current database has hash '{}'.".format(
                    included_data_hash, expected_data_hash))
        return preset
    def bit_pack_unpack(cls, decoder: BitPackDecoder,
                        metadata) -> "MajorItemsConfiguration":
        from randovania.game_description import default_database
        item_database = default_database.default_prime2_item_database()

        progressive_suit = bitpacking.decode_bool(decoder)
        progressive_grapple = bitpacking.decode_bool(decoder)
        progressive_launcher = bitpacking.decode_bool(decoder)

        default = MajorItemsConfiguration.default()
        num_items = decoder.decode_single(len(default.items_state))
        indices_with_custom = {
            decoder.decode_single(len(default.items_state))
            for _ in range(num_items)
        }

        items_state = {}

        for index, item in enumerate(item_database.major_items.values()):
            if index in indices_with_custom:
                items_state[item] = MajorItemState.bit_pack_unpack(
                    decoder, item)
            else:
                items_state[item] = default.items_state[item]

        minimum, maximum = decoder.decode(RANDOM_STARTING_ITEMS_LIMIT,
                                          RANDOM_STARTING_ITEMS_LIMIT)

        return cls(items_state,
                   progressive_suit=progressive_suit,
                   progressive_grapple=progressive_grapple,
                   progressive_launcher=progressive_launcher,
                   minimum_random_starting_items=minimum,
                   maximum_random_starting_items=maximum)
    def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata):
        from randovania.game_description import default_database
        item_database = default_database.default_prime2_item_database()

        default = cls.default()
        has_value = {
            item_key: bool(decoder.decode_single(2))
            for item_key in default.maximum_ammo.keys()
        }

        maximum_ammo = {
            item_key: decoder.decode_single(256)
            if has_value[item_key] else default.maximum_ammo[item_key]
            for item_key, default_value in default.maximum_ammo.items()
        }

        num_items = decoder.decode_single(len(default.items_state))
        indices_with_custom = {
            decoder.decode_single(len(default.items_state))
            for _ in range(num_items)
        }

        items_state = {}
        for index, item in enumerate(item_database.ammo.values()):
            if index in indices_with_custom:
                items_state[item] = AmmoState.bit_pack_unpack(decoder, {})
            else:
                items_state[item] = default.items_state[item]

        return cls(maximum_ammo, items_state)
Esempio n. 4
0
def _decode_preset(decoder: BitPackDecoder, manager: PresetManager) -> Preset:
    included_presets = [versioned.get_preset() for versioned in manager.included_presets]

    is_custom_preset = bitpacking.decode_bool(decoder)
    reference_preset = decoder.decode_element(included_presets)
    if is_custom_preset:
        patcher_configuration = PatcherConfiguration.bit_pack_unpack(
            decoder, {"reference": reference_preset.patcher_configuration})
        layout_configuration = LayoutConfiguration.bit_pack_unpack(
            decoder, {"reference": reference_preset.layout_configuration})
        preset = Preset(
            name="{} Custom".format(reference_preset.name),
            description="A customized preset.",
            base_preset_name=reference_preset.name,
            patcher_configuration=patcher_configuration,
            layout_configuration=layout_configuration,
        )

    else:
        preset = reference_preset
    included_data_hash = decoder.decode_single(256)
    expected_data_hash = _dictionary_byte_hash(preset.layout_configuration.game_data)
    if included_data_hash != expected_data_hash:
        raise ValueError("Given permalink is for a Randovania database with hash '{}', "
                         "but current database has hash '{}'.".format(included_data_hash, expected_data_hash))
    return preset
Esempio n. 5
0
    def bit_pack_unpack(cls, decoder: BitPackDecoder,
                        item: MajorItem) -> "MajorItemState":
        original = decoder.decode_single(2)

        # num shuffled
        shuffled = bitpacking.decode_int_with_limits(decoder,
                                                     DEFAULT_MAXIMUM_SHUFFLED)

        # starting item
        starting = decoder.decode_single(
            ENERGY_TANK_MAXIMUM_COUNT if item.item_category ==
            ItemCategory.ENERGY_TANK else 2)

        if item.ammo_index:
            included_ammo = decoder.decode(*[256 for _ in item.ammo_index])
        else:
            included_ammo = []

        # allowed_as_random_starting_item
        allowed_as_random_starting_item = bitpacking.decode_bool(decoder)

        return cls(
            include_copy_in_original_location=bool(original),
            num_shuffled_pickups=shuffled,
            num_included_in_starting_items=starting,
            included_ammo=tuple(included_ammo),
            allowed_as_random_starting_item=allowed_as_random_starting_item,
        )
Esempio n. 6
0
    def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata) -> "Permalink":
        version, seed_number = decoder.decode(_PERMALINK_MAX_VERSION,
                                              _PERMALINK_MAX_SEED)
        cls._raise_if_different_version(version)

        spoiler = bitpacking.decode_bool(decoder)
        player_count = bitpacking.decode_int_with_limits(
            decoder, _PERMALINK_PLAYER_COUNT_LIMITS)
        manager = PresetManager(None)

        previous_unique_presets = []
        presets = {}

        for index in range(player_count):
            in_previous_presets = bitpacking.decode_bool(decoder)
            if in_previous_presets:
                presets[index] = decoder.decode_element(
                    previous_unique_presets)
                continue

            preset = _decode_preset(decoder, manager)
            previous_unique_presets.append(preset)
            presets[index] = preset

        return Permalink(seed_number, spoiler, presets)
Esempio n. 7
0
    def bit_pack_unpack(cls, decoder: BitPackDecoder,
                        metadata) -> "MajorItemsConfiguration":
        reference: MajorItemsConfiguration = metadata["reference"]

        num_items = decoder.decode_single(len(reference.items_state))
        indices_with_custom = {
            decoder.decode_single(len(reference.items_state))
            for _ in range(num_items)
        }

        items_state = {}

        for index, item in enumerate(reference.items_state.keys()):
            if index in indices_with_custom:
                items_state[item] = MajorItemState.bit_pack_unpack(
                    decoder, item)
            else:
                items_state[item] = reference.items_state[item]

        minimum, maximum = decoder.decode(RANDOM_STARTING_ITEMS_LIMIT,
                                          RANDOM_STARTING_ITEMS_LIMIT)

        return cls(items_state,
                   minimum_random_starting_items=minimum,
                   maximum_random_starting_items=maximum)
Esempio n. 8
0
    def bit_pack_unpack(cls, decoder: BitPackDecoder, item: MajorItem,
                        reference: "MajorItemState") -> "MajorItemState":
        db = default_database.resource_database_for(item.game)
        if item.progression:
            main_index = item.progression[0]
        else:
            main_index = item.ammo_index[0]
        main_item = db.get_item(main_index)

        # original location
        original = False
        if item.original_index is not None:
            original = bitpacking.decode_bool(decoder)

        # num shuffled
        shuffled = bitpacking.decode_int_with_limits(decoder,
                                                     DEFAULT_MAXIMUM_SHUFFLED)

        # starting item
        if main_item.max_capacity > 1:
            starting = bitpacking.decode_int_with_limits(
                decoder, (2, main_item.max_capacity + 1))
        else:
            starting = decoder.decode_single(main_item.max_capacity + 1)

        # priority
        priority = bitpacking.BitPackFloat.bit_pack_unpack(
            decoder, PRIORITY_LIMITS)

        # ammo index
        if item.ammo_index:
            custom_ammo = bitpacking.decode_bool(decoder)
            if custom_ammo:
                all_equal = len(
                    item.ammo_index) <= 1 or bitpacking.decode_bool(decoder)
                if all_equal:
                    ammo = decoder.decode_single(
                        db.get_item(item.ammo_index[0]).max_capacity + 1)
                    included_ammo = [ammo] * len(item.ammo_index)
                else:
                    included_ammo = [
                        decoder.decode_single(
                            db.get_item(item).max_capacity + 1)
                        for item in item.ammo_index
                    ]
            else:
                included_ammo = reference.included_ammo
        else:
            included_ammo = []

        return cls(
            include_copy_in_original_location=original,
            num_shuffled_pickups=shuffled,
            num_included_in_starting_items=starting,
            priority=priority,
            included_ammo=tuple(included_ammo),
        )
Esempio n. 9
0
    def bit_pack_unpack(cls, decoder: BitPackDecoder, name: str,
                        database: ResourceDatabase) -> PickupEntry:
        model_index = decoder.decode_single(255)
        probability_offset = BitPackFloat.bit_pack_unpack(
            decoder, _PROBABILITY_OFFSET_META)
        probability_multiplier = BitPackFloat.bit_pack_unpack(
            decoder, _PROBABILITY_MULTIPLIER_META)
        item_category = ItemCategory.bit_pack_unpack(decoder, {})
        broad_category = ItemCategory.bit_pack_unpack(decoder, {})
        has_name = bitpacking.decode_bool(decoder)
        num_conditional = decoder.decode_single(
            MAXIMUM_PICKUP_CONDITIONAL_RESOURCES) + 1

        conditional_resources = []
        for i in range(num_conditional):
            item_name = None  # TODO: get the first resource name
            if i > 0:
                item_dependency = decoder.decode_element(database.item)
            else:
                item_dependency = None

            resources = []
            for _ in range(decoder.decode_single(MAXIMUM_PICKUP_RESOURCES +
                                                 1)):
                resource = decoder.decode_element(database.item)
                quantity = decoder.decode_single(255)
                resources.append((resource, quantity))

            if has_name:
                if bitpacking.decode_bool(decoder):
                    item_name = name
                else:
                    item_name = resources[0][0].long_name

            conditional_resources.append(
                ConditionalResources(
                    name=item_name,
                    item=item_dependency,
                    resources=tuple(resources),
                ))

        num_convert = decoder.decode_single(MAXIMUM_PICKUP_CONVERSION + 1)
        convert_resources = []
        for i in range(num_convert):
            source = decoder.decode_element(database.item)
            target = decoder.decode_element(database.item)
            convert_resources.append(ResourceConversion(source, target))

        return PickupEntry(
            name=name,
            model_index=model_index,
            item_category=item_category,
            broad_category=broad_category,
            resources=tuple(conditional_resources),
            convert_resources=tuple(convert_resources),
            probability_offset=probability_offset,
            probability_multiplier=probability_multiplier,
        )
def test_encode_no_tricks_are_removed():
    from_json = TrickLevelConfiguration.from_json(
        {
            "minimal_logic": False,
            "specific_levels": {
                "Dash": "disabled"
            }
        },
        game=RandovaniaGame.METROID_PRIME_ECHOES)

    encoded, byte_count = bitpacking.pack_results_and_bit_count(
        from_json.bit_pack_encode({}))

    assert encoded == b'\x00\x00\x00\x00'
    assert byte_count == 26

    decoder = BitPackDecoder(encoded)
    decoded = TrickLevelConfiguration.bit_pack_unpack(
        decoder, {
            "reference":
            TrickLevelConfiguration(False, {},
                                    RandovaniaGame.METROID_PRIME_ECHOES),
        })

    assert decoded.specific_levels == {}
def test_prime_thing(default_prime_configuration):
    config = {
        "mode": "two-way",
        "types_state": {
            "door": {
                "can_change_from": [
                    "Ice Door", "Missile Blast Shield", "Normal Door",
                    "Plasma Door", "Wave Door"
                ],
                "can_change_to": [
                    "Ice Door", "Ice Spreader Blast Shield",
                    "Missile Blast Shield (randomprime)", "Normal Door",
                    "Plasma Door", "Power Bomb Blast Shield",
                    "Super Missile Blast Shield", "Wave Door"
                ]
            },
            "morph_ball": {
                "can_change_from": [],
                "can_change_to": []
            },
            "other": {
                "can_change_from": [],
                "can_change_to": []
            }
        }
    }
    ref = {"reference": default_prime_configuration.dock_rando}

    dc = DockRandoConfiguration.from_json(config, RandovaniaGame.METROID_PRIME)
    encoded = bitpacking.pack_value(dc, metadata=ref)

    decoder = BitPackDecoder(encoded)
    decoded = DockRandoConfiguration.bit_pack_unpack(decoder, ref)

    assert dc == decoded
    def bit_pack_unpack(cls, decoder: BitPackDecoder,
                        metadata) -> "TranslatorConfiguration":
        from randovania.layout import configuration_factory
        templates = [
            configuration_factory.get_vanilla_actual_translator_configurations(
            ),
            configuration_factory.get_vanilla_colors_translator_configurations(
            ),
            cls.default().with_full_random().translator_requirement,
            None,
        ]

        fixed_gfmc_compound = bitpacking.decode_bool(decoder)
        fixed_torvus_temple = bitpacking.decode_bool(decoder)
        fixed_great_temple = bitpacking.decode_bool(decoder)

        translator_requirement = decoder.decode_element(templates)
        if translator_requirement is None:
            translator_requirement = {}
            for gate in templates[0].keys():
                translator_requirement[
                    gate] = LayoutTranslatorRequirement.bit_pack_unpack(
                        decoder, {})

        return cls(
            translator_requirement,
            fixed_gfmc_compound=fixed_gfmc_compound,
            fixed_torvus_temple=fixed_torvus_temple,
            fixed_great_temple=fixed_great_temple,
        )
Esempio n. 13
0
 def bit_pack_unpack(cls, decoder: BitPackDecoder):
     disable_hud_popup, menu_mod, speed_up_credits = decoder.decode(2, 2, 2)
     return cls(
         disable_hud_popup=bool(disable_hud_popup),
         menu_mod=bool(menu_mod),
         speed_up_credits=bool(speed_up_credits),
     )
Esempio n. 14
0
    def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata) -> "AmmoState":
        pickup_count = decoder.decode_single(cls.maximum_pickup_count())
        requires_major_item = bitpacking.decode_bool(decoder)

        return cls(
            variance=0,
            pickup_count=pickup_count,
            requires_major_item=requires_major_item,
        )
def test_decode(location_with_data):
    # Setup
    data, expected = location_with_data

    # Run
    decoder = BitPackDecoder(data)
    result = StartingLocation.bit_pack_unpack(decoder, {})

    # Assert
    assert result == expected
Esempio n. 16
0
def test_decode(translator_data):
    # Setup
    data, _, expected = translator_data

    # Run
    decoder = BitPackDecoder(data)
    result = TranslatorConfiguration.bit_pack_unpack(decoder, {})

    # Assert
    assert result == expected
def test_decode(patcher_with_data):
    # Setup
    data, expected = patcher_with_data

    # Run
    decoder = BitPackDecoder(data)
    result = PatcherConfiguration.bit_pack_unpack(decoder, {})

    # Assert
    assert result == expected
Esempio n. 18
0
def test_decode(mock_possible_tricks, configuration_with_data):
    # Setup
    data, expected = configuration_with_data

    # Run
    decoder = BitPackDecoder(data)
    result = TrickLevelConfiguration.bit_pack_unpack(decoder, {})

    # Assert
    assert result == expected
Esempio n. 19
0
def test_decode(state_with_data):
    # Setup
    data, expected = state_with_data

    # Run
    decoder = BitPackDecoder(data)
    result = AmmoState.bit_pack_unpack(decoder, {})

    # Assert
    assert result == expected
Esempio n. 20
0
def test_decode(major_item_state):
    # Setup
    item, data, _, expected, reference = major_item_state

    # Run
    decoder = BitPackDecoder(data)
    result = MajorItemState.bit_pack_unpack(decoder, item, reference=reference)

    # Assert
    assert result == expected
Esempio n. 21
0
def test_decode(layout_config_with_data):
    # Setup
    data, expected, _ = layout_config_with_data

    # Run
    decoder = BitPackDecoder(data)
    result = EchoesConfiguration.bit_pack_unpack(decoder, {})

    # Assert
    assert result == expected
Esempio n. 22
0
def test_decode(state_with_data):
    # Setup
    item, data, expected = state_with_data

    # Run
    decoder = BitPackDecoder(data)
    result = MajorItemState.bit_pack_unpack(decoder, item)

    # Assert
    assert result == expected
def test_decode(config_with_data):
    # Setup
    data, expected = config_with_data

    # Run
    decoder = BitPackDecoder(data)
    result = MajorItemsConfiguration.bit_pack_unpack(decoder, {})

    # Assert
    assert result == expected
Esempio n. 24
0
    def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata) -> "GeneratorParameters":
        games = decode_game_list(decoder)
        seed_number = decoder.decode_single(_PERMALINK_MAX_SEED)
        spoiler = bitpacking.decode_bool(decoder)

        manager = PresetManager(None)
        presets = [
            Preset.bit_pack_unpack(decoder, {"manager": manager, "game": game})
            for game in games
        ]
        for game in _get_unique_games(presets):
            included_data_hash = decoder.decode_single(256)
            expected_data_hash = _game_db_hash(game)
            if included_data_hash != expected_data_hash:
                raise ValueError("Given permalink is for a Randovania {} database with hash '{}', "
                                 "but current database has hash '{}'.".format(game.long_name,
                                                                              included_data_hash,
                                                                              expected_data_hash))

        return GeneratorParameters(seed_number, spoiler, presets)
Esempio n. 25
0
def test_decode_prime2(prime2_data):
    # Setup
    data, default, expected = prime2_data

    # Run
    decoder = BitPackDecoder(data)
    result = MajorItemsConfiguration.bit_pack_unpack(decoder,
                                                     {"reference": default})

    # Assert
    assert result == expected
Esempio n. 26
0
def test_decode(with_data):
    # Setup
    reference, data, _, expected = with_data

    # Run
    decoder = BitPackDecoder(data)
    result = TeleporterConfiguration.bit_pack_unpack(decoder,
                                                     {"reference": reference})

    # Assert
    assert result == expected
Esempio n. 27
0
    def bit_pack_unpack(cls, decoder: BitPackDecoder) -> "Permalink":
        version, seed, spoiler = decoder.decode(_PERMALINK_MAX_VERSION,
                                                _PERMALINK_MAX_SEED, 2)
        cls._raise_if_different_version(version)

        included_data_hash = decoder.decode(256)[0]

        patcher_configuration = PatcherConfiguration.bit_pack_unpack(decoder)
        layout_configuration = LayoutConfiguration.bit_pack_unpack(decoder)

        expected_data_hash = _dictionary_byte_hash(
            layout_configuration.game_data)
        if included_data_hash != expected_data_hash:
            raise ValueError(
                "Given permalink is for a Randovania database with hash '{}', "
                "but current database has hash '{}'.".format(
                    included_data_hash, expected_data_hash))

        return Permalink(seed, bool(spoiler), patcher_configuration,
                         layout_configuration)
Esempio n. 28
0
def test_decode(location_with_data):
    # Setup
    data, expected = location_with_data

    # Run
    decoder = BitPackDecoder(data)
    result = LocationList.bit_pack_unpack(
        decoder, {"reference": LocationList.with_elements([], RandovaniaGame.METROID_PRIME_ECHOES)})

    # Assert
    assert result == expected
Esempio n. 29
0
def test_decode(config_with_data):
    # Setup
    data, expected, reference = config_with_data

    # Run
    decoder = BitPackDecoder(data)
    result = AmmoConfiguration.bit_pack_unpack(decoder,
                                               {"reference": reference})

    # Assert
    assert result == expected
Esempio n. 30
0
    def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata):
        global_level = LayoutTrickLevel.bit_pack_unpack(decoder, metadata)

        encodable_levels = list(LayoutTrickLevel)
        encodable_levels.remove(LayoutTrickLevel.MINIMAL_LOGIC)

        specific_levels = {}
        for trick in sorted(_all_trick_indices()):
            if bitpacking.decode_bool(decoder):
                specific_levels[trick] = decoder.decode_element(encodable_levels)

        return cls(global_level, specific_levels)