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)
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, )
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)
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 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), )
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) -> "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 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)
def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata) -> "BitPackPickupEntryList": result = [] index_mapping = metadata["index_mapping"] for _ in range(len(index_mapping)): index = PickupIndex(decoder.decode_single(255)) pickup = BitPackPickupEntry.bit_pack_unpack( decoder, index_mapping[index], metadata["database"]) result.append((index, pickup)) return BitPackPickupEntryList(result, metadata["database"])
def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata) -> "BitPackPickupEntryList": result = [] index_mapping = metadata["index_mapping"] num_players = metadata["num_players"] for _ in range(len(index_mapping)): index = PickupIndex(decoder.decode_single(255)) target_player = bitpacking.decode_int_with_limits(decoder, (num_players,)) pickup = BitPackPickupEntry.bit_pack_unpack(decoder, index_mapping[index], metadata["database"]) result.append((index, PickupTarget(pickup, target_player))) return BitPackPickupEntryList(result, num_players, metadata["database"])
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 bit_pack_unpack(cls, decoder: BitPackDecoder, metadata): default: AmmoConfiguration = metadata["reference"] # Maximum Ammo maximum_ammo = {} for item_key, default_value in default.maximum_ammo.items(): is_different = bitpacking.decode_bool(decoder) if is_different: maximum_ammo[item_key] = decoder.decode_single(256) else: maximum_ammo[item_key] = default_value items_state = {} for item, default_state in default.items_state.items(): is_different = bitpacking.decode_bool(decoder) if is_different: items_state[item] = AmmoState.bit_pack_unpack(decoder, {}) else: items_state[item] = default_state return cls(maximum_ammo, items_state)
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 decode_resource_quantity(self, decoder: BitPackDecoder) -> ResourceQuantity: resource = self._decode_item(decoder) quantity = decoder.decode_single(resource.max_capacity + 1) return resource, quantity
def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata): reference: BitPackValueUsingReference = metadata["reference"] value = decoder.decode_single(128) + reference.value return BitPackValueUsingReference(value)