Beispiel #1
0
def build_kinsects(session: sqlalchemy.orm.Session, mhdata):
    # Prepass to determine which entries are "final"
    # Those that are a previous to another are "not final"
    all_final = set(mhdata.kinsect_map.keys())
    for entry in mhdata.kinsect_map.values():
        if not entry.get('previous_en', None):
            continue
        try:
            prev_id = mhdata.kinsect_map.id_of('en', entry['previous_en'])
            all_final.remove(prev_id)
        except KeyError:
            pass

    # Store next recipe id ahead of time
    next_recipe_id = calculate_next_recipe_id(session)

    # Save kinsects
    for entry in mhdata.kinsect_map.values():
        kinsect = db.Kinsect(id=entry.id,
                             rarity=entry['rarity'],
                             previous_kinsect_id=mhdata.kinsect_map.id_of(
                                 'en', entry['previous_en']),
                             attack_type=entry['attack_type'],
                             dust_effect=entry['dust_effect'],
                             power=entry['power'],
                             speed=entry['speed'],
                             heal=entry['heal'],
                             final=entry.id in all_final)

        # Add language translations
        for language in cfg.supported_languages:
            kinsect.translations.append(
                db.KinsectText(lang_id=language,
                               name=get_translated(entry, 'name', language)))

        # Save kinsect recipe
        recipe = entry.get('craft', None)
        if recipe:
            for item, quantity in datafn.iter_recipe(recipe):
                item_id = mhdata.item_map.id_of("en", item)
                ensure(
                    item_id, f"Kinsect {entry.name('en')} refers to " +
                    f"item {item}, which doesn't exist.")
                kinsect.craft_items.append(
                    db.RecipeItem(recipe_id=next_recipe_id,
                                  item_id=item_id,
                                  quantity=quantity))
            next_recipe_id += 1

        session.add(kinsect)

    print("Built Kinsects")
Beispiel #2
0
def build_charms(session : sqlalchemy.orm.Session, mhdata):
    item_map = mhdata.item_map
    skill_map = mhdata.skill_map
    charm_map = mhdata.charm_map

    for order_id, entry in enumerate(charm_map.values()):
        # Note: previous is ok to be None
        previous = charm_map.id_of('en', entry['previous_en'])

        charm = db.Charm(
            id=entry.id,
            order_id=order_id,
            previous_id=previous,
            rarity=entry['rarity']
        )

        for language in cfg.supported_languages:
            charm.translations.append(db.CharmText(
                lang_id=language,
                name=entry.name(language)
            ))

        # Add charm skills
        for skill_en, level in entry['skills'].items():
            skill_id = skill_map.id_of('en', skill_en)
            ensure(skill_id, f"Charm {entry.name('en')} refers to " +
                f"item {skill_en}, which doesn't exist.")

            charm.skills.append(db.CharmSkill(
                skilltree_id=skill_id,
                level=level
            ))

        # Add Charm Recipe
        if entry['craft']:
            charm.recipe_id = calculate_next_recipe_id(session)
            for item_en, quantity in entry['craft'].items():
                item_id = item_map.id_of('en', item_en)
                ensure(item_id, f"Charm {entry.name('en')} refers to " +
                    f"item {item_en}, which doesn't exist.")

                charm.craft_items.append(db.RecipeItem(
                    recipe_id=charm.recipe_id,
                    item_id=item_id,
                    quantity=quantity
                ))

        session.add(charm)

    print("Built Charms")
Beispiel #3
0
def build_weapons(session: sqlalchemy.orm.Session, mhdata):
    item_map = mhdata.item_map
    weapon_map = mhdata.weapon_map

    # Save all weapon ammo configurations
    for entry in mhdata.weapon_ammo_map.values():
        ammo = db.WeaponAmmo(id=entry.id,
                             deviation=entry['deviation'],
                             special_ammo=entry['special'])

        # helper to assign the entirety of a group to the db
        def assign_group(ammotype):
            group = entry[ammotype]
            setattr(ammo, ammotype + "_clip", group['clip'])
            setattr(ammo, ammotype + "_rapid", group['rapid'])
            setattr(ammo, ammotype + "_recoil", group.get('recoil', None) or 0)
            setattr(ammo, ammotype + "_reload", group.get('reload', None))

        assign_group('normal1')
        assign_group('normal2')
        assign_group('normal3')
        assign_group('pierce1')
        assign_group('pierce2')
        assign_group('pierce3')
        assign_group('spread1')
        assign_group('spread2')
        assign_group('spread3')
        assign_group('sticky1')
        assign_group('sticky2')
        assign_group('sticky3')
        assign_group('cluster1')
        assign_group('cluster2')
        assign_group('recover1')
        assign_group('recover2')
        assign_group('poison1')
        assign_group('poison2')
        assign_group('paralysis1')
        assign_group('paralysis2')
        assign_group('sleep1')
        assign_group('sleep2')
        assign_group('exhaust1')
        assign_group('exhaust2')
        assign_group('flaming')
        assign_group('water')
        assign_group('freeze')
        assign_group('thunder')
        assign_group('dragon')

        assign_group('slicing')
        assign_group('demon')
        assign_group('armor')
        assign_group('tranq')

        ammo.wyvern_clip = entry['wyvern']['clip']
        ammo.wyvern_reload = entry['wyvern']['reload']

        session.add(ammo)

    # Save all weapon melodies
    for melody_entry in mhdata.weapon_melodies.values():
        melody = db.WeaponMelody(base_duration=melody_entry['base_duration'],
                                 base_extension=melody_entry['base_extension'],
                                 m1_duration=melody_entry['m1_duration'],
                                 m1_extension=melody_entry['m1_extension'],
                                 m2_duration=melody_entry['m2_duration'],
                                 m2_extension=melody_entry['m2_extension'])

        for language in cfg.supported_languages:
            melody.translations.append(
                db.WeaponMelodyText(
                    lang_id=language,
                    name=get_translated(melody_entry, 'name', language),
                    effect1=get_translated(melody_entry, 'effect1', language),
                    effect2=get_translated(melody_entry, 'effect2', language)))

        for note_entry in melody_entry['notes']:
            melody.notes.append(
                db.WeaponMelodyNotes(notes=note_entry['notes']))

        session.add(melody)

    # Prepass to determine which weapons are "final"
    # All items that are a previous to another are "not final"
    all_final = set(weapon_map.keys())
    for entry in weapon_map.values():
        if not entry.get('previous_en', None):
            continue
        try:
            prev_id = weapon_map.id_of('en', entry['previous_en'],
                                       entry['weapon_type'])
            all_final.remove(prev_id)
        except KeyError:
            pass

    # Query next recipe id beforehand
    next_recipe_id = calculate_next_recipe_id(session)

    # now iterate over actual weapons
    for idx, entry in enumerate(weapon_map.values()):
        weapon_id = entry.id
        weapon_type = entry['weapon_type']

        weapon = db.Weapon(
            id=weapon_id,
            order_id=idx,
            weapon_type=weapon_type,
        )

        # Add language translations
        for language in cfg.supported_languages:
            weapon.translations.append(
                db.WeaponText(lang_id=language,
                              name=get_translated(entry, 'name', language)))

        weapon.category = entry['category']
        weapon.rarity = entry['rarity']
        weapon.attack = entry['attack']
        weapon.attack_true = int(entry['attack'] /
                                 cfg.weapon_multiplier[weapon_type])
        weapon.affinity = entry['affinity']
        weapon.defense = entry['defense'] or 0
        weapon.slot_1 = entry['slot_1']
        weapon.slot_2 = entry['slot_2']
        weapon.slot_3 = entry['slot_3']

        weapon.element1 = entry['element1']
        weapon.element1_attack = entry['element1_attack']
        weapon.element2 = entry['element2']
        weapon.element2_attack = entry['element2_attack']
        weapon.element_hidden = entry['element_hidden']
        weapon.elderseal = entry['elderseal']

        if entry.get('sharpness', None):
            weapon.sharpness = datafn.merge_sharpness(entry)
            weapon.sharpness_maxed = entry['sharpness']['maxed']

        weapon.kinsect_bonus = entry['kinsect_bonus']
        weapon.phial = entry['phial']
        weapon.phial_power = entry['phial_power']
        weapon.shelling = entry['shelling']
        weapon.shelling_level = entry['shelling_level']
        weapon.notes = entry['notes']

        weapon.craftable = False  # set to true later if it can be crafted
        weapon.final = weapon_id in all_final

        previous_weapon_name = entry.get('previous_en', None)
        if previous_weapon_name:
            previous_weapon_id = weapon_map.id_of("en", previous_weapon_name,
                                                  weapon_type)
            ensure(previous_weapon_id,
                   f"Weapon {previous_weapon_name} does not exist")
            weapon.previous_weapon_id = previous_weapon_id

        # Add crafting/upgrade recipes
        for recipe in entry.get('craft', {}):
            recipe_type = recipe['type']
            if recipe_type == "Create":
                weapon.craftable = True
                weapon.create_recipe_id = next_recipe_id
            else:
                weapon.upgrade_recipe_id = next_recipe_id

            for item, quantity in datafn.iter_recipe(recipe):
                item_id = item_map.id_of("en", item)
                session.add(
                    db.RecipeItem(recipe_id=next_recipe_id,
                                  item_id=item_id,
                                  quantity=quantity))

            next_recipe_id += 1

        # Bow data (if any)
        if entry.get("bow", None):
            bow_data = entry['bow']
            weapon.coating_close = bow_data['close']
            weapon.coating_power = bow_data['power']
            weapon.coating_poison = bow_data['poison']
            weapon.coating_paralysis = bow_data['paralysis']
            weapon.coating_sleep = bow_data['sleep']
            weapon.coating_blast = bow_data['blast']

        # Gun data mapping (if any)
        ammo_config_name = entry.get('ammo_config', None)
        if ammo_config_name:
            weapon.ammo_id = mhdata.weapon_ammo_map[ammo_config_name].id

        # Skills
        if entry['skill']:
            skill_id = mhdata.skill_map.id_of('en', entry['skill'])
            weapon.skills.append(db.WeaponSkill(skilltree_id=skill_id,
                                                level=1))

        session.add(weapon)

    print("Built Weapons")
Beispiel #4
0
def build_armor(session: sqlalchemy.orm.Session, mhdata):
    item_map = mhdata.item_map
    skill_map = mhdata.skill_map
    armorset_map = mhdata.armorset_map
    armorset_bonus_map = mhdata.armorset_bonus_map
    armor_map = mhdata.armor_map

    # Create reverse mapping. In SQL, armor links to armorset instead
    armor_to_armorset = {}
    armorset_to_bonus = {}

    # Write entries from armor set bonuses
    # These are written first as they are "linked to"
    for bonus_entry in armorset_bonus_map.values():
        for language in cfg.supported_languages:
            session.add(
                db.ArmorSetBonusText(id=bonus_entry.id,
                                     lang_id=language,
                                     name=get_translated(
                                         bonus_entry, 'name', language)))

        for skill_name, required in datafn.iter_setbonus_skills(bonus_entry):
            skill_id = skill_map.id_of('en', skill_name)
            session.add(
                db.ArmorSetBonusSkill(setbonus_id=bonus_entry.id,
                                      skilltree_id=skill_id,
                                      required=required))

    # Write entries for armor sets
    for set_id, entry in armorset_map.items():
        armorset_bonus_id = None

        if entry['bonus']:
            armorset_bonus_id = armorset_bonus_map.id_of('en', entry['bonus'])
            ensure(
                armorset_bonus_id,
                f"Armorset bonus {entry['bonus']} in armorsets doesn't exist")
            armorset_to_bonus[set_id] = armorset_bonus_id

        armorset = db.ArmorSet(id=set_id,
                               rank=entry['rank'],
                               armorset_bonus_id=armorset_bonus_id)

        if entry['monster']:
            armorset.monster_id = mhdata.monster_map.id_of(
                'en', entry['monster'])

        for language in cfg.supported_languages:
            armorset.translations.append(
                db.ArmorSetText(lang_id=language,
                                name=get_translated(entry, 'name', language)))

        session.add(armorset)

        # Populate reverse map (to allow armor to link to armorset)
        for part in cfg.armor_parts:
            if not entry[part]:
                continue

            armor_reverse_id = mhdata.armor_map.id_of('en', entry[part])
            armor_to_armorset[armor_reverse_id] = set_id

    # Store recipe id to start from for armor
    next_recipe_id = calculate_next_recipe_id(session)

    # Write entries for armor
    for order_id, entry in enumerate(armor_map.values()):
        armor_name_en = entry.name('en')

        armor = db.Armor(id=entry.id)
        armor.order_id = order_id
        armor.rarity = entry['rarity']
        armor.armor_type = entry['type']
        armor.male = entry['gender'] in ('male', 'both')
        armor.female = entry['gender'] in ('female', 'both')
        armor.slot_1 = entry['slot_1']
        armor.slot_2 = entry['slot_2']
        armor.slot_3 = entry['slot_3']
        armor.defense_base = entry['defense_base']
        armor.defense_max = entry['defense_max']
        armor.defense_augment_max = entry['defense_augment_max']
        armor.fire = entry['defense_fire']
        armor.water = entry['defense_water']
        armor.thunder = entry['defense_thunder']
        armor.ice = entry['defense_ice']
        armor.dragon = entry['defense_dragon']

        armorset_id = armor_to_armorset.get(entry.id, None)
        armorset_entry = armorset_map[armorset_id]
        armor.rank = armorset_entry['rank']
        armor.armorset_id = armorset_id
        armor.armorset_bonus_id = armorset_to_bonus.get(armorset_id, None)

        for language in cfg.supported_languages:
            armor.translations.append(
                db.ArmorText(
                    lang_id=language,
                    name=get_translated(entry, 'name', language),
                ))

        # Armor Skills
        for skill, level in datafn.iter_skill_levels(entry['skills']):
            skill_id = skill_map.id_of('en', skill)
            armor.skills.append(
                db.ArmorSkill(skilltree_id=skill_id, level=level))

        # Armor Crafting
        for item_name, quantity in datafn.iter_armor_recipe(entry):
            item_id = item_map.id_of('en', item_name)
            armor.craft_items.append(
                db.RecipeItem(recipe_id=next_recipe_id,
                              item_id=item_id,
                              quantity=quantity))

        next_recipe_id += 1

        session.add(armor)

    print("Built Armor")