示例#1
0
def build_decorations(session : sqlalchemy.orm.Session, mhdata):
    "Performs the build process for decorations. Must be done after skills"

    skill_map = mhdata.skill_map
    decoration_map = mhdata.decoration_map

    for decoration_id, entry in decoration_map.items():
        skill_id = skill_map.id_of('en', entry['skill_en'])
        ensure(skill_id, f"Decoration {entry.name('en')} refers to " +
            f"skill {entry['skill_en']}, which doesn't exist.")

        ensure("chances" in entry, "Missing chance data for " + entry.name('en'))
        
        decoration = db.Decoration(
            id=decoration_id,
            rarity=entry['rarity'],
            slot=entry['slot'],
            icon_color=entry['icon_color'],
            skilltree_id=skill_id,
            mysterious_feystone_percent=entry['chances']['mysterious'],
            glowing_feystone_percent=entry['chances']['glowing'],
            worn_feystone_percent=entry['chances']['worn'],
            warped_feystone_percent=entry['chances']['warped']
        )

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

        session.add(decoration)

    print("Built Decorations")
示例#2
0
文件: sql.py 项目: kevinn/MHWorldData
def build_locations(session: sqlalchemy.orm.Session, mhdata):
    for location_id, entry in mhdata.location_map.items():
        location_name = entry['name']['en']

        for language in supported_languages:
            session.add(
                db.Location(id=location_id,
                            lang_id=language,
                            name=entry.name(language)))

        for item_entry in entry['items']:
            item_lang = item_entry['item_lang']
            item_name = item_entry['item']
            item_id = mhdata.item_map.id_of(item_lang, item_name)
            ensure(
                item_id,
                f"item {item_name} in monster {location_name} does not exist")

            session.add(
                db.LocationItem(
                    location_id=location_id,
                    rank=item_entry['rank'],
                    item_id=item_id,
                    stack=item_entry['stack'],
                    percentage=item_entry['percentage'],
                ))

    print("Built locations")
示例#3
0
文件: sql.py 项目: kevinn/MHWorldData
def build_charms(session: sqlalchemy.orm.Session, mhdata):
    item_map = mhdata.item_map
    skill_map = mhdata.skill_map
    charm_map = mhdata.charm_map

    for charm_id, entry in charm_map.items():
        charm = db.Charm(id=charm_id)

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

        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))

        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.CharmRecipe(item_id=item_id, quantity=quantity))

        session.add(charm)

    print("Built Charms")
示例#4
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")
示例#5
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")
示例#6
0
def build_decorations(session: sqlalchemy.orm.Session, mhdata):
    "Performs the build process for decorations. Must be done after skills"

    skill_map = mhdata.skill_map
    decoration_map = mhdata.decoration_map

    for decoration_id, entry in decoration_map.items():
        skills = [[None, None]] * 2
        for i in [1, 2]:
            skill_name = entry[f'skill{i}_name']
            if skill_name:
                skill_id = skill_map.id_of('en', skill_name)
                ensure(
                    skill_id, f"Decoration {entry.name('en')} refers to " +
                    f"skill {skill_name}, which doesn't exist.")
                skill_level = entry[f"skill{i}_level"]
                skills[i - 1] = [skill_id, skill_level]

        ensure("chances" in entry,
               "Missing chance data for " + entry.name('en'))

        decoration = db.Decoration(
            id=decoration_id,
            rarity=entry['rarity'],
            slot=entry['slot'],
            icon_color=entry['icon_color'],
            skilltree_id=skills[0][0],
            skilltree_level=skills[0][1],
            skilltree2_id=skills[1][0],
            skilltree2_level=skills[1][1],
            mysterious_feystone_percent=entry['chances']['mysterious'],
            glowing_feystone_percent=entry['chances']['glowing'],
            worn_feystone_percent=entry['chances']['worn'],
            warped_feystone_percent=entry['chances']['warped'],
            ancient_feystone_percent=entry['chances']['ancient'],
            carved_feystone_percent=entry['chances']['carved'],
            sealed_feystone_percent=entry['chances']['sealed'],
        )

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

        session.add(decoration)

    print("Built Decorations")
示例#7
0
def build_decorations(session: sqlalchemy.orm.Session, mhdata):
    "Performs the build process for decorations. Must be done after skills"

    skill_map = mhdata.skill_map
    decoration_map = mhdata.decoration_map

    for decoration_id, entry in decoration_map.items():
        skills = list(datafn.iter_skill_levels(entry, amount=2, pad=True))
        ensure("chances" in entry,
               "Missing chance data for " + entry.name('en'))

        decoration = db.Decoration(
            id=decoration_id,
            rarity=entry['rarity'],
            slot=entry['slot'],
            icon_color=entry['icon_color'],
            skilltree_id=skill_map.id_of('en', skills[0][0]),
            skilltree_level=skills[0][1],
            skilltree2_id=skill_map.id_of('en', skills[1][0]),
            skilltree2_level=skills[1][1],
            mysterious_feystone_percent=entry['chances']['mysterious'],
            glowing_feystone_percent=entry['chances']['glowing'],
            worn_feystone_percent=entry['chances']['worn'],
            warped_feystone_percent=entry['chances']['warped'],
            ancient_feystone_percent=entry['chances']['ancient'],
            carved_feystone_percent=entry['chances']['carved'],
            sealed_feystone_percent=entry['chances']['sealed'],
        )

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

        session.add(decoration)

    print("Built Decorations")
示例#8
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")
示例#9
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")
示例#10
0
def build_monsters(session: sqlalchemy.orm.Session, mhdata,
                   item_tracker: ItemTracker):
    item_map = mhdata.item_map
    location_map = mhdata.location_map
    monster_map = mhdata.monster_map
    monster_reward_conditions_map = mhdata.monster_reward_conditions_map

    # Save conditions first
    for condition_id, entry in monster_reward_conditions_map.items():
        for language in cfg.supported_languages:
            session.add(
                db.MonsterRewardConditionText(
                    id=condition_id,
                    lang_id=language,
                    name=get_translated(entry, 'name', language),
                ))

    # Save monsters
    for order_id, entry in enumerate(monster_map.values()):
        monster = db.Monster(id=entry.id,
                             order_id=order_id,
                             size=entry['size'],
                             pitfall_trap=entry['pitfall_trap'],
                             shock_trap=entry['shock_trap'],
                             vine_trap=entry['vine_trap'])

        # todo: refactor to allow translations. Currently set when weaknesses are read
        alt_state_description = None

        # Save basic weakness summary data
        if 'weaknesses' in entry and entry['weaknesses']:
            elements = [
                'fire', 'water', 'ice', 'thunder', 'dragon', 'poison', 'sleep',
                'paralysis', 'blast', 'stun'
            ]

            weaknesses = {e['form']: e for e in entry['weaknesses']}
            form_normal = weaknesses.get('normal')
            form_alt = weaknesses.get('alt')

            invalid_keys = [
                k for k in weaknesses.keys() if k not in ('normal', 'alt')
            ]
            if invalid_keys:
                raise Exception(
                    f"Monster {entry.name('en')} has invalid form(s) {', '.join(invalid_keys)}"
                )

            if form_normal:
                monster.has_weakness = True
                for element in elements:
                    setattr(monster, 'weakness_' + element,
                            form_normal[element])

            if form_alt:
                monster.has_alt_weakness = True
                alt_state_description = form_alt['alt_description']

                for element in elements:
                    value = form_alt[element]
                    if value is None:
                        value = form_normal[element]
                    setattr(monster, 'alt_weakness_' + element, value)

        # Save language data
        for language in cfg.supported_languages:
            monster.translations.append(
                db.MonsterText(lang_id=language,
                               name=get_translated(entry, 'name', language),
                               ecology=entry['ecology_en'],
                               description=get_translated(
                                   entry, 'description', language),
                               alt_state_description=alt_state_description))

        # Save hitzones
        for hitzone_data in entry.get('hitzones', []):
            hitzone = db.MonsterHitzone(cut=hitzone_data['cut'],
                                        impact=hitzone_data['impact'],
                                        shot=hitzone_data['shot'],
                                        fire=hitzone_data['fire'],
                                        water=hitzone_data['water'],
                                        thunder=hitzone_data['thunder'],
                                        ice=hitzone_data['ice'],
                                        dragon=hitzone_data['dragon'],
                                        ko=hitzone_data['ko'])

            for language in cfg.supported_languages:
                part_name = get_translated(hitzone_data, 'hitzone', language)
                hitzone.translations.append(
                    db.MonsterHitzoneText(lang_id=language, name=part_name))

            monster.hitzones.append(hitzone)

        # Save breaks
        for break_data in entry.get('breaks', []):
            breakzone = db.MonsterBreak(flinch=break_data['flinch'],
                                        wound=break_data['wound'],
                                        sever=break_data['sever'],
                                        extract=break_data['extract'])

            for language in cfg.supported_languages:
                breakzone.translations.append(
                    db.MonsterBreakText(
                        lang_id=language,
                        part_name=get_translated(break_data, 'part', language),
                    ))

            monster.breaks.append(breakzone)

        # Save ailments
        ailments = entry.get('ailments', None)
        if ailments:
            monster.ailment_roar = ailments['roar']
            monster.ailment_wind = ailments['wind']
            monster.ailment_tremor = ailments['tremor']
            monster.ailment_defensedown = ailments['defense_down']
            monster.ailment_fireblight = ailments['fireblight']
            monster.ailment_waterblight = ailments['waterblight']
            monster.ailment_thunderblight = ailments['thunderblight']
            monster.ailment_iceblight = ailments['iceblight']
            monster.ailment_dragonblight = ailments['dragonblight']
            monster.ailment_blastblight = ailments['blastblight']
            monster.ailment_regional = ailments['regional']
            monster.ailment_poison = ailments['poison']
            monster.ailment_sleep = ailments['sleep']
            monster.ailment_paralysis = ailments['paralysis']
            monster.ailment_bleed = ailments['bleed']
            monster.ailment_stun = ailments['stun']
            monster.ailment_mud = ailments['mud']
            monster.ailment_effluvia = ailments['effluvia']

        # Create a temp base map of the conditions
        # This temp map extends the global map with monster-specific conditions
        #monster_conditions = DataMap(reward_conditions_map)
        #monster_conditions.extend(entry.get('break_conditions', []))

        # Save hunting rewards
        for reward in entry.get('rewards', []):
            condition_en = reward['condition_en']
            rank = reward['rank']
            item_name = reward['item_en']

            condition_id = monster_reward_conditions_map.id_of(
                'en', condition_en)
            item_id = item_map.id_of('en', item_name)

            item_tracker.mark_encountered_id(item_id)

            monster.rewards.append(
                db.MonsterReward(condition_id=condition_id,
                                 rank=rank,
                                 item_id=item_id,
                                 stack=reward['stack'],
                                 percentage=reward['percentage'] or 0))

        # Save Habitats
        for habitat_data in entry.get('habitats', []):
            location_name = habitat_data['map_en']
            location_id = location_map.id_of("en", location_name)
            ensure(location_id, "Invalid location name " + location_name)

            monster.habitats.append(
                db.MonsterHabitat(location_id=location_id,
                                  start_area=habitat_data['start_area'],
                                  move_area=habitat_data['move_area'],
                                  rest_area=habitat_data['rest_area']))

        # Complete - add to session
        session.add(monster)

    print("Built Monsters")
示例#11
0
def build_monsters(session : sqlalchemy.orm.Session, mhdata):
    item_map = mhdata.item_map
    location_map = mhdata.location_map
    monster_map = mhdata.monster_map
    monster_reward_conditions_map = mhdata.monster_reward_conditions_map

    # Save conditions first
    for condition_id, entry in monster_reward_conditions_map.items():
        for language in cfg.supported_languages:
            session.add(db.MonsterRewardConditionText(
                id=condition_id,
                lang_id=language,
                name=get_translated(entry, 'name', language),
            ))

    # Save monsters
    for order_id, entry in enumerate(monster_map.values()):
        monster = db.Monster(
            id=entry.id,
            order_id=order_id,
            size=entry['size']
        )

        # Save basic weakness summary data
        if 'weaknesses' in entry and entry['weaknesses']:
            monster.has_weakness = True
            weaknesses = entry['weaknesses']
            for key, value in weaknesses['normal'].items():
                setattr(monster, 'weakness_'+key, value)

            if 'alt' in weaknesses:
                monster.has_alt_weakness = True
                for key, value in weaknesses['alt'].items():
                    setattr(monster, 'alt_weakness_'+key, value)

        # Save language data
        for language in cfg.supported_languages:
            alt_state_description = None
            if 'alt_description' in entry.get('weaknesses', {}):
                alt_state_description = get_translated(entry['weaknesses'], 'alt_description', language)

            monster.translations.append(db.MonsterText(
                lang_id=language,
                name=get_translated(entry, 'name', language),
                ecology=get_translated(entry, 'ecology', language),
                description=get_translated(entry, 'description', language),
                alt_state_description=alt_state_description
            ))

        # Save hitzones
        for hitzone_data in entry.get('hitzones', []):
            hitzone = db.MonsterHitzone(
                cut=hitzone_data['cut'],
                impact=hitzone_data['impact'],
                shot=hitzone_data['shot'],
                fire=hitzone_data['fire'],
                water=hitzone_data['water'],
                thunder=hitzone_data['thunder'],
                ice=hitzone_data['ice'],
                dragon=hitzone_data['dragon'],
                ko=hitzone_data['ko'])

            for language in cfg.supported_languages:
                part_name = get_translated(hitzone_data, 'hitzone', language)
                hitzone.translations.append(db.MonsterHitzoneText(
                    lang_id=language,
                    name=part_name
                ))

            monster.hitzones.append(hitzone)

        # Save breaks
        for break_data in entry.get('breaks', []):
            breakzone = db.MonsterBreak(
                flinch=break_data['flinch'],
                wound=break_data['wound'],
                sever=break_data['sever'],
                extract=break_data['extract']
            )

            for language in cfg.supported_languages:
                breakzone.translations.append(db.MonsterBreakText(
                    lang_id=language,
                    part_name=get_translated(break_data, 'part', language),
                ))

            monster.breaks.append(breakzone)

        # Save ailments
        ailments = entry.get('ailments', None)
        if ailments:
            monster.ailment_roar = ailments['roar']
            monster.ailment_wind = ailments['wind']
            monster.ailment_tremor = ailments['tremor']
            monster.ailment_defensedown = ailments['defense_down']
            monster.ailment_fireblight = ailments['fireblight']
            monster.ailment_waterblight = ailments['waterblight']
            monster.ailment_thunderblight = ailments['thunderblight']
            monster.ailment_iceblight = ailments['iceblight']
            monster.ailment_dragonblight = ailments['dragonblight']
            monster.ailment_blastblight = ailments['blastblight']
            monster.ailment_poison = ailments['poison']
            monster.ailment_sleep = ailments['sleep']
            monster.ailment_paralysis = ailments['paralysis']
            monster.ailment_bleed = ailments['bleed']
            monster.ailment_stun = ailments['stun']
            monster.ailment_mud = ailments['mud']
            monster.ailment_effluvia = ailments['effluvia']

        # Create a temp base map of the conditions
        # This temp map extends the global map with monster-specific conditions
        #monster_conditions = DataMap(reward_conditions_map)
        #monster_conditions.extend(entry.get('break_conditions', []))

        # Save hunting rewards
        for reward in entry.get('rewards', []):
            condition_en = reward['condition_en']
            rank = reward['rank']
            item_name = reward['item_en']

            condition_id = monster_reward_conditions_map.id_of('en', condition_en)
            item_id = item_map.id_of('en', item_name)

            monster.rewards.append(db.MonsterReward(
                condition_id=condition_id,
                rank=rank,
                item_id=item_id,
                stack=reward['stack'],
                percentage=reward['percentage']
            ))

        # Save Habitats
        for habitat_data in entry.get('habitats', []):
            location_name = habitat_data['map_en']
            location_id = location_map.id_of("en", location_name)
            ensure(location_id, "Invalid location name " + location_name)

            monster.habitats.append(db.MonsterHabitat(
                location_id=location_id,
                start_area=habitat_data['start_area'],
                move_area=habitat_data['move_area'],
                rest_area=habitat_data['rest_area']
            ))

        # Complete - add to session
        session.add(monster)

    print("Built Monsters")
示例#12
0
def build_weapons(session: sqlalchemy.orm.Session, mhdata):
    item_map = mhdata.item_map
    weapon_map = mhdata.weapon_map

    # 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'])
            all_final.remove(prev_id)
        except KeyError:
            pass

    # now iterate over actual weapons
    for weapon_id, entry in weapon_map.items():
        weapon = db.Weapon(id=weapon_id)

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

        weapon.weapon_type = entry['weapon_type']
        weapon.rarity = entry['rarity']
        weapon.attack = entry['attack']
        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.sharpness = entry['sharpness']
        weapon.sharpness_complete = entry['sharpness_complete']
        weapon.kinsect_bonus = entry.get('kinsect_bonus', None)

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

        if entry.get('previous', None):
            previous_weapon_id = weapon_map.id_of("en", entry['previous'])
            ensure(previous_weapon_id,
                   f"Weapon {entry['previous']} 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

            for item, quantity in datafn.iter_weapon_recipe(recipe):
                item_id = item_map.id_of("en", item)
                session.add(
                    db.WeaponRecipe(weapon_id=weapon_id,
                                    item_id=item_id,
                                    quantity=quantity,
                                    recipe_type=recipe_type))

        # 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
        if entry.get("gun", None):
            gun_data = entry['gun']
            weapon.deviation = gun_data['deviation']
            weapon.special_ammo = gun_data['special']
            weapon.ammo_normal_1 = gun_data['normal_1']
            weapon.ammo_normal_2 = gun_data['normal_2']
            weapon.ammo_normal_3 = gun_data['normal_3']
            weapon.ammo_pierce_1 = gun_data['pierce_1']
            weapon.ammo_pierce_2 = gun_data['pierce_2']
            weapon.ammo_pierce_3 = gun_data['pierce_3']
            weapon.ammo_spread_1 = gun_data['spread_1']
            weapon.ammo_spread_2 = gun_data['spread_2']
            weapon.ammo_spread_3 = gun_data['spread_3']
            weapon.ammo_sticky_1 = gun_data['sticky_1']
            weapon.ammo_sticky_2 = gun_data['sticky_2']
            weapon.ammo_sticky_3 = gun_data['sticky_3']
            weapon.ammo_cluster_1 = gun_data['cluster_1']
            weapon.ammo_cluster_2 = gun_data['cluster_2']
            weapon.ammo_cluster_3 = gun_data['cluster_3']
            weapon.ammo_recover_1 = gun_data['recover_1']
            weapon.ammo_recover_2 = gun_data['recover_2']
            weapon.ammo_poison_1 = gun_data['poison_1']
            weapon.ammo_poison_2 = gun_data['poison_2']
            weapon.ammo_paralysis_1 = gun_data['paralysis_1']
            weapon.ammo_paralysis_2 = gun_data['paralysis_2']
            weapon.ammo_sleep_1 = gun_data['sleep_1']
            weapon.ammo_sleep_2 = gun_data['sleep_2']
            weapon.ammo_exhaust_1 = gun_data['exhaust_1']
            weapon.ammo_exhaust_2 = gun_data['exhaust_2']
            weapon.ammo_flaming = gun_data['flaming']
            weapon.ammo_water = gun_data['water']
            weapon.ammo_freeze = gun_data['freeze']
            weapon.ammo_thunder = gun_data['thunder']
            weapon.ammo_dragon = gun_data['dragon']
            weapon.ammo_slicing = gun_data['slicing']
            weapon.ammo_wyvern = gun_data['wyvern']
            weapon.ammo_demon = gun_data['demon']
            weapon.ammo_armor = gun_data['armor']
            weapon.ammo_tranq = gun_data['tranq']

        session.add(weapon)

    print("Built Weapons")
示例#13
0
def build_monsters(session: sqlalchemy.orm.Session, mhdata):
    item_map = mhdata.item_map
    location_map = mhdata.location_map
    monster_map = mhdata.monster_map
    monster_reward_conditions_map = mhdata.monster_reward_conditions_map

    # Save conditions first
    for condition_id, entry in monster_reward_conditions_map.items():
        for language in cfg.supported_languages:
            session.add(
                db.MonsterRewardConditionText(id=condition_id,
                                              lang_id=language,
                                              name=entry.name(language)))

    # Save monsters
    for order_id, entry in enumerate(monster_map.values()):
        monster = db.Monster(id=entry.id,
                             order_id=order_id,
                             size=entry['size'])

        # Save basic weakness summary data
        if 'weaknesses' in entry and entry['weaknesses']:
            monster.has_weakness = True
            weaknesses = entry['weaknesses']
            for key, value in weaknesses['normal'].items():
                setattr(monster, 'weakness_' + key, value)

            if 'alt' in weaknesses:
                monster.has_alt_weakness = True
                for key, value in weaknesses['normal'].items():
                    setattr(monster, 'alt_weakness_' + key, value)

        # Save language data
        for language in cfg.supported_languages:
            alt_state_description = None
            if 'alt_description' in entry.get('weaknesses', {}):
                alt_state_description = entry['weaknesses']['alt_description'][
                    language]

            monster.translations.append(
                db.MonsterText(lang_id=language,
                               name=entry.name(language),
                               ecology=entry['ecology'][language],
                               description=entry['description'][language],
                               alt_state_description=alt_state_description))

        # Save hitzones
        for hitzone_data in entry.get('hitzones', []):
            hitzone = db.MonsterHitzone(cut=hitzone_data['cut'],
                                        impact=hitzone_data['impact'],
                                        shot=hitzone_data['shot'],
                                        fire=hitzone_data['fire'],
                                        water=hitzone_data['water'],
                                        thunder=hitzone_data['thunder'],
                                        dragon=hitzone_data['dragon'],
                                        ko=hitzone_data['ko'])

            for lang, part_name in hitzone_data['hitzone'].items():
                hitzone.translations.append(
                    db.MonsterHitzoneText(lang_id=lang, name=part_name))

            monster.hitzones.append(hitzone)

        # Save breaks
        for break_data in entry.get('breaks', []):
            breakzone = db.MonsterBreak(flinch=break_data['flinch'],
                                        wound=break_data['wound'],
                                        sever=break_data['sever'],
                                        extract=break_data['extract'])

            for lang, part_name in break_data['part'].items():
                breakzone.translations.append(
                    db.MonsterBreakText(lang_id=lang, part_name=part_name))

            monster.breaks.append(breakzone)

        # Create a temp base map of the conditions
        # This temp map extends the global map with monster-specific conditions
        #monster_conditions = DataMap(reward_conditions_map)
        #monster_conditions.extend(entry.get('break_conditions', []))

        # Save hunting rewards
        for reward in entry.get('rewards', []):
            condition_en = reward['condition_en']
            rank = reward['rank']
            item_name = reward['item_en']

            condition_id = monster_reward_conditions_map.id_of(
                'en', condition_en)
            item_id = item_map.id_of('en', item_name)

            monster.rewards.append(
                db.MonsterReward(condition_id=condition_id,
                                 rank=rank,
                                 item_id=item_id,
                                 stack=reward['stack'],
                                 percentage=reward['percentage']))

        # Save Habitats
        for location_name, habitat_values in entry.get('habitats', {}).items():
            location_id = location_map.id_of("en", location_name)
            ensure(location_id, "Invalid location name " + location_name)

            monster.habitats.append(
                db.MonsterHabitat(location_id=location_id, **habitat_values))

        # Complete - add to session
        session.add(monster)

    print("Built Monsters")
示例#14
0
文件: sql.py 项目: kevinn/MHWorldData
def build_weapons(session: sqlalchemy.orm.Session, mhdata):
    item_map = mhdata.item_map
    weapon_data = mhdata.weapon_data
    weapon_map = mhdata.weapon_map

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

    for weapon_id, entry in weapon_data.items():
        weapon = db.Weapon(id=weapon_id)
        weapon.weapon_type = entry['weapon_type']
        weapon.rarity = entry['rarity']
        weapon.attack = entry['attack']
        weapon.slot_1 = entry['slots'][0]
        weapon.slot_2 = entry['slots'][1]
        weapon.slot_3 = entry['slots'][2]

        weapon.element_type = entry['element_type']
        weapon.element_damage = entry['element_damage']
        weapon.element_hidden = entry['element_hidden']

        # todo: sharpness, coatings, ammo

        # Note: High probably the way this is stored in data will be refactored
        # Possibilities are either split weapon_data files, or separated sub-data files
        weapon.glaive_boost_type = entry.get('glaive_boost_type', None)
        weapon.deviation = entry.get('deviation', None)
        weapon.special_ammo = entry.get('special_ammo', None)

        weapon.craftable = bool(entry.get('craft', False))
        weapon.final = weapon_id in all_final

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

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

        # Add crafting/upgrade recipes
        for recipe_type in ('craft', 'upgrade'):
            recipe = entry.get(recipe_type, {}) or {}
            for item, quantity in recipe.items():
                item_id = item_map.id_of("en", item)
                ensure(
                    item_id,
                    f"Item {item_id} in weapon {entry.name('en')} does not exist"
                )
                session.add(
                    db.WeaponRecipe(weapon_id=weapon_id,
                                    item_id=item_id,
                                    quantity=quantity,
                                    recipe_type=recipe_type))

        session.add(weapon)

    print("Built Weapons")
示例#15
0
文件: sql.py 项目: kevinn/MHWorldData
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

    armor_parts = ['head', 'chest', 'arms', 'waist', 'legs']

    # 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 entry in armorset_bonus_map.values():
        for language in supported_languages:
            session.add(
                db.ArmorSetBonusText(id=entry.id,
                                     lang_id=language,
                                     name=entry.name(language)))

        for skill_entry in entry['skills']:
            skill_id = skill_map.id_of('en', skill_entry['skill'])
            ensure(
                skill_id,
                f"Skill {skill_entry['skill']} in armorset bonuses doesn't exist"
            )

            session.add(
                db.ArmorSetBonusSkill(id=entry.id,
                                      skilltree_id=skill_id,
                                      points=skill_entry['points'],
                                      threshold=skill_entry['threshold']))

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

        if entry['bonus']:
            armorset_bonus_id = armorset_bonus_map.id_of(
                armor_lang, 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, armorset_bonus_id=armorset_bonus_id)

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

        session.add(armorset)

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

            armor_id = mhdata.armor_map.id_of(armor_lang, entry[part])
            ensure(armor_id, f"Armor {entry[part]} in armorset does not exist")
            armor_to_armorset[armor_id] = set_id

    # Write entries for armor
    for armor_id, entry in armor_map.items():
        armor_name_en = entry.name('en')

        armor = db.Armor(id=armor_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(armor_id, None)
        ensure(armorset_id, f"Armor {armor_name_en} is not in an armor set")

        armor.armorset_id = armorset_id
        armor.armorset_bonus_id = armorset_to_bonus.get(armorset_id, None)

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

        # Armor Skills
        for skill, level in entry['skills'].items():
            skill_id = skill_map.id_of('en', skill)
            ensure(skill_id,
                   f"Skill {skill} in Armor {armor_name_en} does not exist")

            armor.skills.append(
                db.ArmorSkill(skilltree_id=skill_id, level=level))

        # Armor Crafting
        for item, quantity in entry['craft'].items():
            item_id = item_map.id_of('en', item)
            ensure(item_id,
                   f"Item {item} in Armor {armor_name_en} does not exist")

            armor.craft_items.append(
                db.ArmorRecipe(item_id=item_id, quantity=quantity))

        session.add(armor)

    print("Built Armor")