def write_essences(data_path, relational_reader, **kwargs): essences = { row['BaseItemTypesKey']['Id']: { 'name': row['BaseItemTypesKey']['Name'], 'spawn_level_min': row['DropLevelMinimum'], 'spawn_level_max': row['DropLevelMaximum'], 'level': row['Level'], 'item_level_restriction': row['ItemLevelRestriction'] if row['ItemLevelRestriction'] > 0 else None, 'type': { 'tier': row['EssenceTypeKey']['EssenceType'], 'is_corruption_only': row['EssenceTypeKey']['IsCorruptedEssence'], }, 'mods': _convert_mods(row) } for row in relational_reader['Essences.dat'] } write_json(essences, data_path, 'essences')
def write_synthesis_corrupted_implicits(data_path, relational_reader, **kwargs): data = { row['ItemClassesKey']['Id']: [mod['Id'] for mod in row['ModsKeys']] for row in relational_reader['ItemSynthesisCorruptedMods.dat'] } write_json(data, data_path, 'synthesis_corrupted_implicits')
def write_gems(ggpk, data_path, relational_reader, translation_file_cache, **kwargs): gems = {} tooltips = {} converter = GemConverter(ggpk, relational_reader, translation_file_cache) for gem in relational_reader['SkillGems.dat']: granted_effect = gem['GrantedEffectsKey'] ge_id = granted_effect['Id'] if ge_id in gems: print("Duplicate GrantedEffectsKey.Id '%s'" % ge_id) multipliers = {'str': gem['Str'], 'dex': gem['Dex'], 'int': gem['Int']} gems[ge_id], tooltips[ge_id] = \ converter.convert(gem['BaseItemTypesKey'], granted_effect, gem['GemTagsKeys'], multipliers) for mod in relational_reader['Mods.dat']: if mod['GrantedEffectsPerLevelKey'] is None: continue if ignore_mod_domain(mod['Domain']): continue granted_effect = mod['GrantedEffectsPerLevelKey']['GrantedEffectsKey'] ge_id = granted_effect['Id'] if ge_id in gems: # mod effects may exist as gems, those are handled above continue gems[ge_id], tooltips[ge_id] = \ converter.convert(None, granted_effect, None, None) write_json(gems, data_path, 'gems') write_json(tooltips, data_path, 'gem_tooltips')
def write_mods(data_path, relational_reader, **kwargs): root = {} for mod in relational_reader['Mods.dat']: domain = MOD_DOMAIN_FIX.get(mod['Id'], mod['Domain']) if ignore_mod_domain(domain): continue obj = { 'required_level': mod['Level'], 'stats': _convert_stats(mod['Stats']), 'domain': domain.name.lower(), 'name': mod['Name'], 'generation_type': mod['GenerationType'].name.lower(), 'group': mod['CorrectGroup'], 'spawn_weights': _convert_spawn_weights(mod['SpawnWeight']), 'generation_weights': _convert_generation_weights(mod['GenerationWeight']), 'grants_buff': _convert_buff(mod['BuffDefinitionsKey'], mod['BuffValue']), 'grants_effect': _convert_granted_effects(mod['GrantedEffectsPerLevelKey']), 'is_essence_only': mod['IsEssenceOnlyModifier'] > 0, 'adds_tags': _convert_tags_keys(mod['TagsKeys']) } if mod['Id'] in root: print("Duplicate mod id:", mod['Id']) else: root[mod['Id']] = obj write_json(root, data_path, 'mods')
def write_base_items(data_path, relational_reader, ot_file_cache, **kwargs): attribute_requirements = \ _create_default_dict(relational_reader['ComponentAttributeRequirements.dat']) armour_types = _create_default_dict( relational_reader['ComponentArmour.dat']) shield_types = _create_default_dict(relational_reader['ShieldTypes.dat']) flask_types = _create_default_dict(relational_reader['Flasks.dat']) flask_charges = _create_default_dict( relational_reader['ComponentCharges.dat']) weapon_types = _create_default_dict(relational_reader['WeaponTypes.dat']) currency_type = _create_default_dict( relational_reader['CurrencyItems.dat']) # Not covered here: SkillGems.dat (see gems.py), Essences.dat (see essences.py) root = {} for item in relational_reader['BaseItemTypes.dat']: if item['ItemClassesKey']['Id'] not in ITEM_CLASS_WHITELIST: continue inherited_tags = list(ot_file_cache[item['InheritsFrom'] + '.ot']['Base']['tag']) item_id = item['Id'] properties = {} _convert_armour_properties(armour_types[item_id], properties) _convert_shield_properties(shield_types[item_id], properties) _convert_flask_properties(flask_types[item_id], properties) _convert_flask_charge_properties(flask_charges[item_id], properties) _convert_weapon_properties(weapon_types[item_id], properties) _convert_currency_properties(currency_type[item_id], properties) root[item_id] = { 'name': item['Name'], 'item_class': item['ItemClassesKey']['Id'], 'inventory_width': item['Width'], 'inventory_height': item['Height'], 'drop_level': item['DropLevel'], 'implicits': [mod['Id'] for mod in item['Implicit_ModsKeys']], 'tags': [tag['Id'] for tag in item['TagsKeys']] + inherited_tags, 'visual_identity': { 'id': item['ItemVisualIdentityKey']['Id'], 'dds_file': item['ItemVisualIdentityKey']['DDSFile'], }, 'requirements': _convert_requirements(attribute_requirements[item_id], item['DropLevel']), 'properties': properties, 'release_state': get_release_state(item_id).name, 'domain': item['ModDomainsKey'].name.lower(), } _convert_flask_buff(flask_types[item_id], root[item_id]) write_json(root, data_path, 'base_items')
def write_stat_translations(data_path, translation_file_cache, **kwargs): tag_set = set() for in_file, out_file in STAT_TRANSLATION_DICT.items(): translations = translation_file_cache[in_file].translations result = _get_stat_translations(tag_set, translations, get_custom_translation_file().translations) write_json(result, data_path, out_file) print("Possible format tags: {}".format(tag_set))
def write_synthesis_implicits(data_path, relational_reader, **kwargs): data = [{ 'stat': { 'id': row['StatsKey']['Id'], 'value': row['StatValue'], }, 'item_classes': [item_class['Id'] for item_class in row['ItemClassesKeys']], 'mods': [mod['Id'] for mod in row['ModsKeys']], } for row in relational_reader['ItemSynthesisMods.dat']] write_json(data, data_path, 'synthesis_implicits')
def write_default_monster_stats(data_path, relational_reader, **kwargs): root = {} for row in relational_reader['DefaultMonsterStats.dat']: root[row['DisplayLevel']] = { 'physical_damage': row['Damage'], 'evasion': row['Evasion'], 'accuracy': row['Accuracy'], 'life': row['Life'], 'ally_life': row['AllyLife'] } write_json(root, data_path, 'default_monster_stats')
def write_npc_master(data_path, relational_reader, **kwargs): root = {} for row in relational_reader['NPCMaster.dat']: root[row['Id']] = { 'signature_mod': { 'id': row['SignatureMod_ModsKey']['Id'], 'spawn_weights': _convert_spawn_weights(row['SignatureModSpawnWeight_TagsKeys'], row['SignatureModSpawnWeight_Values']), }, } write_json(root, data_path, 'npc_master')
def write_crafting_bench_options(data_path, relational_reader, **kwargs): root = [] for row in relational_reader['CraftingBenchOptions.dat']: if row['ModsKey'] is None: continue root.append({ 'mod_id': row['ModsKey']['Id'], 'master_id': row['NPCMasterKey']['Id'], 'master_level': row['MasterLevel'], 'item_classes': [item_class['Id'] for item_class in row['ItemClassesKeys']] }) write_json(root, data_path, 'crafting_bench_options')
def write_gems(ggpk, data_path, relational_reader, translation_file_cache, **kwargs): gems = {} tooltips = {} converter = GemConverter(ggpk, relational_reader, translation_file_cache) # Skills from gems for gem in relational_reader['SkillGems.dat']: granted_effect = gem['GrantedEffectsKey'] ge_id = granted_effect['Id'] if ge_id in gems: print("Duplicate GrantedEffectsKey.Id '%s'" % ge_id) multipliers = {'str': gem['Str'], 'dex': gem['Dex'], 'int': gem['Int']} gems[ge_id], tooltips[ge_id] = converter.convert( gem['BaseItemTypesKey'], granted_effect, gem['GrantedEffectsKey2'], gem['GemTagsKeys'], multipliers) # Secondary skills from gems. This adds the support skill implicitly provided by Bane for gem in relational_reader['SkillGems.dat']: granted_effect = gem['GrantedEffectsKey2'] if not granted_effect: continue ge_id = granted_effect['Id'] if ge_id in gems: continue gems[ge_id], tooltips[ge_id] = converter.convert( None, granted_effect, None, None, None) # Skills from mods for mod in relational_reader['Mods.dat']: if mod['GrantedEffectsPerLevelKeys'] is None: continue if ignore_mod_domain(mod['Domain']): continue for granted_effect_per_level in mod['GrantedEffectsPerLevelKeys']: granted_effect = granted_effect_per_level['GrantedEffectsKey'] ge_id = granted_effect['Id'] if ge_id in gems: # mod effects may exist as gems, those are handled above continue gems[ge_id], tooltips[ge_id] = converter.convert( None, granted_effect, None, None, None) # Default Attack/PlayerMelee is neither gem nor mod effect for granted_effect in relational_reader['GrantedEffects.dat']: ge_id = granted_effect['Id'] if ge_id != 'PlayerMelee': continue gems[ge_id], tooltips[ge_id] = converter.convert( None, granted_effect, None, None, None) write_json(gems, data_path, 'gems') write_json(tooltips, data_path, 'gem_tooltips')
def write_fossils(data_path, relational_reader, **kwargs): root = {} for row in relational_reader['DelveCraftingModifiers.dat']: root[row["BaseItemTypesKey"]["Id"]] = { "added_mods": [mod['Id'] for mod in row["AddedModKeys"]], "forced_mods": [mod['Id'] for mod in row["ForcedAddModKeys"]], "negative_mod_weights": [{ "tag": tag["Id"], "weight": value } for tag, value in zip(row["NegativeWeight_TagsKeys"], row["NegativeWeight_Values"])], "positive_mod_weights": [{ "tag": tag["Id"], "weight": value } for tag, value in zip(row["Weight_TagsKeys"], row["Weight_Values"])], "forbidden_tags": [ tag["TagsKey"]["Id"] for tag in row["ForbiddenDelveCraftingTagsKeys"] ], "allowed_tags": [ tag["TagsKey"]["Id"] for tag in row["AllowedDelveCraftingTagsKeys"] ], "corrupted_essence_chance": row["CorruptedEssenceChance"], "mirrors": row["CanMirrorItem"], "changes_quality": row["CanImproveQuality"], "rolls_lucky": row["HasLuckyRolls"], "enchants": row["CanRollEnchant"], "rolls_white_sockets": row["CanRollWhiteSockets"], "sell_price_mods": [mod['Id'] for mod in row["SellPrice_ModsKeys"]], "descriptions": [ description["Description"] for description in row["DelveCraftingModifierDescriptionsKeys"] ], "blocked_descriptions": [ description["Id"] for description in row["BlockedDelveCraftingModifierDescriptionsKeys"] ] } write_json(root, data_path, 'fossils')
def write_stats(data_path, relational_reader, **kwargs): root = {} previous = set() for stat in relational_reader['Stats.dat']: if stat['Id'] in previous: print("Duplicate stat id %s" % stat['Id']) continue root[stat['Id']] = { 'is_local': stat['IsLocal'], 'is_aliased': stat['IsWeaponLocal'], 'alias': _convert_alias_stats(stat['MainHandAlias_StatsKey'], stat['OffHandAlias_StatsKey']), # 'is_on_character_panel': stat['Flag6'], # not sure # 'is_on_tooltip': stat['Flag7'], # not sure } write_json(root, data_path, 'stats')
def write_crafting_bench_options(data_path, relational_reader, **kwargs): root = [] for row in relational_reader['CraftingBenchOptions.dat']: if row['ModsKey'] is None or row['RequiredLevel'] > 100: continue item_class_row_lists = [ categories['ItemClassesKeys'] for categories in row['CraftingItemClassCategoriesKeys'] ] item_class_rows = itertools.chain.from_iterable(item_class_row_lists) item_classes = [item_class['Id'] for item_class in item_class_rows] root.append({ 'master': row['HideoutNPCsKey']['NPCMasterKey']['Id'], 'mod_id': row['ModsKey']['Id'], 'bench_group': row['ModFamily'], 'bench_tier': row['Tier'], 'item_classes': item_classes, }) write_json(root, data_path, 'crafting_bench_options')
def write_characters(data_path, relational_reader, **kwargs): root = [] for row in relational_reader['Characters.dat']: root.append({ 'metadata_id': row['Id'], 'integer_id': row['IntegerId'], 'name': row['Name'], 'base_stats': { 'life': row['BaseMaxLife'], 'mana': row['BaseMaxMana'], 'strength': row['BaseStrength'], 'dexterity': row['BaseDexterity'], 'intelligence': row['BaseIntelligence'], 'unarmed': { 'attack_time': row['WeaponSpeed'], 'min_physical_damage': row['MinDamage'], 'max_physical_damage': row['MaxDamage'], 'range': row['MaxAttackDistance'], }, }, }) write_json(root, data_path, 'characters')
def write_tags(data_path, relational_reader, **kwargs): tags = [row['Id'] for row in relational_reader['Tags.dat']] write_json(tags, data_path, 'tags')
def write_gem_tags(data_path, relational_reader, **kwargs): root = {} for tag in relational_reader['GemTags.dat']: name = tag['Tag'] root[tag['Id']] = name if name != '' else None write_json(root, data_path, 'gem_tags')