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