def load_database(self,
                      skip_skills=False,
                      skip_bonus=False,
                      skip_extra=False):
        base_dir = self.base_dir
        raw_cards = card.load_card_data(data_dir=base_dir)
        self.dungeons = dungeon.load_dungeon_data(data_dir=base_dir)

        if not skip_bonus:
            self.bonus_sets = {
                g.value: bonus.load_bonus_data(data_dir=base_dir,
                                               server=self.server,
                                               data_group=g.value)
                for g in StarterGroup
            }

        if not skip_skills:
            self.skills = skill.load_skill_data(data_dir=base_dir)
            parser = SkillParser()
            parser.parse(self.skills)
            self.leader_skills = parser.leader_skills
            self.active_skills = parser.active_skills
            self.skill_id_to_leader_skill = {
                s.skill_id: s
                for s in self.leader_skills
            }
            self.skill_id_to_active_skill = {
                s.skill_id: s
                for s in self.active_skills
            }

        self.raw_enemy_skills = enemy_skill.load_enemy_skill_data(
            data_dir=base_dir)
        es_parser = BehaviorParser()
        es_parser.parse(self.raw_enemy_skills)
        self.enemy_skills = es_parser.enemy_behaviors

        if not skip_extra:
            self.exchange = exchange.load_data(data_dir=base_dir,
                                               server=self.server)
            self.egg_machines = extra_egg_machine.load_data(data_dir=base_dir,
                                                            server=self.server)

        self.bonuses = _clean_bonuses(self.server, self.bonus_sets,
                                      self.dungeons)
        self.enemies = _clean_enemy(raw_cards, self.enemy_skills)
        self.cards = _clean_cards(self.server, raw_cards, self.enemies, self)

        self.dungeon_id_to_dungeon = {d.dungeon_id: d for d in self.dungeons}
        self.monster_no_to_card = {c.monster_no: c for c in self.cards}
        if self.server == Server.jp:
            self.monster_id_to_card = self.monster_no_to_card
        else:
            self.monster_id_to_card = {
                nakr_no_to_monster_id(c.monster_no): c
                for c in self.cards
            }

        self.enemy_id_to_enemy = {e.enemy_id: e for e in self.enemies}
    def load_database(self,
                      skip_skills=False,
                      skip_bonus=False,
                      skip_extra=False):
        base_dir = self.base_dir
        raw_cards = card.load_card_data(data_dir=base_dir)
        self.dungeons = dungeon.load_dungeon_data(data_dir=base_dir)

        if not skip_bonus:
            self.bonus_sets = {
                g.value: bonus.load_bonus_data(data_dir=base_dir,
                                               server=self.server,
                                               data_group=g.value)
                for g in StarterGroup
            }

        if not skip_skills:
            self.skills = skill.load_skill_data(data_dir=base_dir)
            self.skill_id_to_skill = {s.skill_id: s for s in self.skills}
            # TODO: need to compute skill data here

        self.enemy_skills = enemy_skill.load_enemy_skill_data(
            data_dir=base_dir)

        if not skip_extra:
            self.exchange = exchange.load_data(data_dir=base_dir)
            self.egg_machines = egg_machine.load_data(data_dir=base_dir)

        self.bonuses = _clean_bonuses(self.server, self.bonus_sets,
                                      self.dungeons)
        self.enemies = _clean_enemy(raw_cards, self.enemy_skills)
        self.cards = _clean_cards(self.server, raw_cards, self.skills,
                                  self.enemies)

        self.dungeon_id_to_dungeon = {d.dungeon_id: d for d in self.dungeons}
        self.monster_no_to_card = {c.monster_no: c for c in self.cards}
        if self.server == Server.jp:
            self.monster_id_to_card = self.monster_no_to_card
        else:
            self.monster_id_to_card = {
                nakr_no_to_monster_id(c.monster_no): c
                for c in self.cards
            }

        self.enemy_id_to_enemy = {e.enemy_id: e for e in self.enemies}
Beispiel #3
0
 def no_to_id(self, monster_no: MonsterNo) -> MonsterId:
     if self.server == Server.jp:
         return jp_no_to_monster_id(monster_no)
     else:
         return nakr_no_to_monster_id(monster_no)
Beispiel #4
0
def copy_media(args):
    base_dir = args.base_dir
    alt_base_dir = args.alt_base_dir
    output_dir = args.output_dir

    jp_icon_input_dir = os.path.join(base_dir, 'jp', 'portrait', 'local')
    na_icon_input_dir = os.path.join(base_dir, 'na', 'portrait', 'local')

    jp_portrait_input_dir = os.path.join(base_dir, 'jp', 'full',
                                         'corrected_data')
    na_portrait_input_dir = os.path.join(base_dir, 'na', 'full',
                                         'corrected_data')

    hq_portrait_input_dir = os.path.join(base_dir, 'hq_images')
    animated_portrait_input_dir = os.path.join(base_dir, 'animated')

    orb_skins_input_dir = os.path.join(alt_base_dir, 'orb_styles', 'extract',
                                       'jp')
    jp_voice_input_dir = os.path.join(alt_base_dir, 'voices', 'fixed', 'jp')
    na_voice_input_dir = os.path.join(alt_base_dir, 'voices', 'fixed', 'na')

    icon_output_dir = os.path.join(output_dir, 'icons')
    portrait_output_dir = os.path.join(output_dir, 'portraits')
    hq_portrait_output_dir = os.path.join(output_dir, 'hq_portraits')
    animated_portrait_output_dir = os.path.join(output_dir,
                                                'animated_portraits')
    orb_skins_output_dir = os.path.join(output_dir, 'orb_skins')
    jp_voice_output_dir = os.path.join(output_dir, 'voices', 'jp')
    na_voice_output_dir = os.path.join(output_dir, 'voices', 'na')

    for jp_id in range(1, 9000):
        monster_id = jp_id
        monster_id_filled = str(monster_id).zfill(5)

        do_copy(jp_icon_input_dir, '{}.png'.format(monster_id),
                icon_output_dir, '{}.png'.format(monster_id_filled))

        do_copy(jp_portrait_input_dir, '{}.png'.format(monster_id),
                portrait_output_dir, '{}.png'.format(monster_id_filled))

        do_copy(hq_portrait_input_dir, '{}.png'.format(monster_id),
                hq_portrait_output_dir, '{}.png'.format(monster_id_filled))

        do_copy(animated_portrait_input_dir, '{}.mp4'.format(monster_id),
                animated_portrait_output_dir,
                '{}.mp4'.format(monster_id_filled))

        do_copy(animated_portrait_input_dir, '{}.gif'.format(monster_id),
                animated_portrait_output_dir,
                '{}.gif'.format(monster_id_filled))

        do_copy(jp_voice_input_dir, '{}.wav'.format(monster_id),
                jp_voice_output_dir, '{}.wav'.format(monster_id_filled))

    for na_id in range(1, 9000):
        monster_id = monster_id_mapping.nakr_no_to_monster_id(MonsterNo(na_id))
        monster_id_filled = str(monster_id).zfill(5)

        do_copy(na_icon_input_dir, '{}.png'.format(na_id), icon_output_dir,
                '{}.png'.format(monster_id_filled))

        do_copy(na_portrait_input_dir, '{}.png'.format(na_id),
                portrait_output_dir, '{}.png'.format(monster_id_filled))

        do_copy(na_voice_input_dir, '{}.wav'.format(na_id),
                na_voice_output_dir, '{}.wav'.format(monster_id_filled))

    for file_name in os.listdir(orb_skins_input_dir):
        clean_file_name = file_name.lower().lstrip('block')
        do_copy(orb_skins_input_dir, file_name, orb_skins_output_dir,
                clean_file_name)
    def convert(self, wave_items: List[WaveItem], try_common_monsters: bool) -> ResultFloor:
        result = ProcessedFloor()

        waves_by_entry = defaultdict(list)
        waves_by_stage_and_entry = defaultdict(lambda: defaultdict(list))
        for wave_item in wave_items:
            drop_id = wave_item.get_drop()

            # Stuff in this range is supposedly:
            # 9900: coins
            # 9901: stones
            # 9902: pal points
            # 9911: gift dungeon
            # 9912: monster points
            # 9916: permanent dungeon
            # 9917: badge
            # 9999: announcement
            if drop_id and (9000 < drop_id < 10000):
                raise ValueError('Special drop detected (not handled yet)')

            # Correct for NA server mappings if necessary
            monster_id = wave_item.monster_id
            if wave_item.server != Server.jp:
                monster_id = monster_id_mapping.nakr_no_to_monster_id(monster_id)
                if drop_id:
                    drop_id = monster_id_mapping.nakr_no_to_monster_id(drop_id)

            # Build a structure that merges DB info with wave data.
            card = self.data.card_by_monster_id(monster_id)
            drop = self.data.card_by_monster_id(drop_id) if drop_id else None
            wave_card = WaveCard(monster_id, card, wave_item, drop)

            # Store data for an individual dungeon entry.
            waves_by_entry[wave_item.entry_id].append(wave_card)

            # Store data for each stage, separated by dungeon entry.
            waves_by_stage_and_entry[wave_item.stage][wave_item.entry_id].append(wave_card)

        # Calculate stuff that should be done per-entry instead of per-floor. This more
        # correctly handles invades and alternate spawns.
        for entry_waves in waves_by_entry.values():
            result.add_entry(entry_waves)

        # Calculate stuff at a per-stage level, like spawns and drops.
        invades = ProcessedStage(ProcessedStage.INVADE_IDX)
        stages = [ProcessedStage(i + 1) for i in sorted(waves_by_stage_and_entry.keys())]
        last_stage_idx = stages[-1].stage_idx
        for stage in stages:
            waves_for_stage = waves_by_stage_and_entry[stage.stage_idx - 1]

            for entry_waves in waves_for_stage.values():
                if stage.stage_idx != last_stage_idx and entry_waves[0].wave_item.is_invade():
                    # Invades happen only on non-boss floors; some bosses represent as invades though.
                    invades.add_wave_group(entry_waves)
                else:
                    stage.add_wave_group(entry_waves)

        if invades.count:
            result.invades = invades

        result.stages.extend(stages)

        return ResultFloor(result, try_common_monsters)