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 _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
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) -> "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)
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, )
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)
def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata): minimal_logic = bitpacking.decode_bool(decoder) encodable_levels = list(LayoutTrickLevel) encodable_levels.remove(LayoutTrickLevel.NO_TRICKS) encodable_levels.remove(LayoutTrickLevel.MINIMAL_LOGIC) specific_levels = {} for trick in sorted(_all_tricks()): if bitpacking.decode_bool(decoder): specific_levels[trick.short_name] = decoder.decode_element( encodable_levels) return cls(minimal_logic, specific_levels)
def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata) -> "TranslatorConfiguration": templates = [ _get_vanilla_actual_translator_configurations(), _get_vanilla_colors_translator_configurations(), cls.default().with_full_random().translator_requirement, None, ] 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, )
def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata): game = metadata["reference"].game game_data = default_data.read_json_then_binary(game)[1] minimal_logic = bitpacking.decode_bool(decoder) specific_levels = {} if not minimal_logic: encodable_levels = list(LayoutTrickLevel) encodable_levels.remove(LayoutTrickLevel.DISABLED) for trick in sorted(_all_tricks(game_data)): if bitpacking.decode_bool(decoder): specific_levels[trick.short_name] = decoder.decode_element(encodable_levels) return cls(minimal_logic, specific_levels, game)
def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata): game = metadata["reference"].game resource_database = default_database.resource_database_for(game) minimal_logic = bitpacking.decode_bool(decoder) specific_levels = {} if not minimal_logic: encodable_levels = list(LayoutTrickLevel) encodable_levels.remove(LayoutTrickLevel.DISABLED) for trick in _all_tricks(resource_database): if bitpacking.decode_bool(decoder): specific_levels[trick.short_name] = decoder.decode_element( encodable_levels) return cls(minimal_logic, specific_levels, game)
def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata) -> "Permalink": version, seed, spoiler = decoder.decode(_PERMALINK_MAX_VERSION, _PERMALINK_MAX_SEED, 2) cls._raise_if_different_version(version) included_data_hash = decoder.decode_single(256) manager = PresetManager(None) is_custom_preset = bitpacking.decode_bool(decoder) reference_preset = decoder.decode_element(manager.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 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 Permalink( seed, bool(spoiler), preset, )
def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata) -> "MajorItemsConfiguration": reference: MajorItemsConfiguration = metadata["reference"] name_to_item: Dict[str, MajorItem] = { item.name: item for item in reference.items_state.keys() } modified_items = bitpacking.decode_sorted_array_elements( decoder, sorted(name_to_item.keys())) items_state = copy.copy(reference.items_state) for item_name in modified_items: item = name_to_item[item_name] items_state[item] = MajorItemState.bit_pack_unpack( decoder, item, reference=reference.items_state[item]) # default_items default_items = {} for category in reference.default_items.keys(): all_major = [ major for major in reference.items_state.keys() if major.item_category == category ] default_items[category] = decoder.decode_element(all_major) # random starting items minimum = bitpacking.decode_big_int(decoder) maximum = bitpacking.decode_big_int(decoder) return cls( game=reference.game, items_state=items_state, default_items=default_items, minimum_random_starting_items=minimum, maximum_random_starting_items=maximum, )
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] # default_items default_items = {} for category in reference.default_items.keys(): all_major = [ major for major in reference.items_state.keys() if major.item_category == category ] default_items[category] = decoder.decode_element(all_major) # random starting items minimum, maximum = decoder.decode(RANDOM_STARTING_ITEMS_LIMIT, RANDOM_STARTING_ITEMS_LIMIT) return cls(items_state, default_items=default_items, minimum_random_starting_items=minimum, maximum_random_starting_items=maximum)
def _decode_item(self, decoder: BitPackDecoder) -> ItemResourceInfo: return decoder.decode_element(self.database.item)