コード例 #1
0
ファイル: main.py プロジェクト: marius851000/skytemple
    def _init_td_label_stores(self):
        self._labels_td_level = {}
        self._labels_td_dungeon = {}

        store: Gtk.ListStore = self.builder.get_object('td_level_store')
        self._labels_td_level[-1] = _('None')
        store.append([-1, _('None')])
        if self._list:
            for level in self._list.list:
                lbl = f'{level.name} (#{level.id:03})'
                self._labels_td_level[level.id] = lbl
                store.append([level.id, lbl])
        else:
            for i in range(0, 400):
                lbl = f'? (#{i:03})'
                self._labels_td_level[i] = lbl
                store.append([i, lbl])

        static = self.module.project.get_rom_module().get_static_data()
        dungeons = HardcodedDungeons.get_dungeon_list(
            self.module.project.get_binary(BinaryName.ARM9), static)
        store: Gtk.ListStore = self.builder.get_object('td_dungeon_store')
        for i, dungeon in enumerate(dungeons):
            lbl = f'{self.module.project.get_string_provider().get_value(StringType.DUNGEON_NAMES_SELECTION, i)} (#{i:03})'
            self._labels_td_dungeon[i] = lbl
            store.append([i, lbl])
コード例 #2
0
 def save_dungeon_restrictions(self,
                               restrictions: List[DungeonRestriction]):
     self.project.modify_binary(
         BinaryName.ARM9,
         lambda binary: HardcodedDungeons.set_dungeon_restrictions(
             restrictions, binary,
             self.project.get_rom_module().get_static_data()))
コード例 #3
0
    def __init__(self, config: RandomizerConfig, rom: NintendoDSRom,
                 static_data: Pmd2Data, seed: str):
        super().__init__(config, rom, static_data, seed)

        self.dungeons = HardcodedDungeons.get_dungeon_list(
            get_binary_from_rom_ppmdu(self.rom,
                                      self.static_data.binaries['arm9.bin']),
            self.static_data)
コード例 #4
0
ファイル: module.py プロジェクト: SkyTemple/skytemple
 def set_tileset_properties(self, lst: List[TilesetProperties]):
     self.project.modify_binary(
         BinaryName.OVERLAY_10,
         lambda binary: HardcodedDungeons.set_tileset_properties(
             lst, binary,
             self.project.get_rom_module().get_static_data()))
     row = self._tree_model[self._root_node]
     recursive_up_item_store_mark_as_modified(row)
コード例 #5
0
    def _init_secondary_terrain(self):
        w: Gtk.ComboBox = self.builder.get_object('secondary_terrain_type')
        s: Gtk.ListStore = w.get_model()
        for v in SecondaryTerrainTableEntry:
            s.append([v.value, v.name.capitalize()])

        secondary_terrain = HardcodedDungeons.get_secondary_terrains(
            self.module.project.get_binary(BinaryName.ARM9), self.module.project.get_rom_module().get_static_data()
        )[self.item_id]
        w.set_active(secondary_terrain.value)
コード例 #6
0
    def on_secondary_terrain_type_changed(self, w: Gtk.ComboBox):
        idx = w.get_active()
        static = self.module.project.get_rom_module().get_static_data()
        secondary_terrains = HardcodedDungeons.get_secondary_terrains(
            self.module.project.get_binary(BinaryName.ARM9), static
        )
        secondary_terrains[self.item_id] = SecondaryTerrainTableEntry(idx)

        def update(arm9):
            HardcodedDungeons.set_secondary_terrains(secondary_terrains, arm9, static)
        self.module.project.modify_binary(BinaryName.ARM9, update)

        self.mark_as_modified()
コード例 #7
0
ファイル: module.py プロジェクト: marius851000/skytemple
    def get_mapping_dungeon_assets(
            self
    ) -> Tuple[List[GroundTilesetMapping], MappaBin, FixedBin, ModelContext[DungeonBinPack], List[DungeonDefinition]]:
        static_data = self.project.get_rom_module().get_static_data()
        config = self.project.get_rom_module().get_static_data()
        ov11 = self.project.get_binary(BinaryName.OVERLAY_11)
        mappings = HardcodedGroundDungeonTilesets.get_ground_dungeon_tilesets(ov11, config)

        mappa = self.project.open_file_in_rom('BALANCE/mappa_s.bin', FileType.MAPPA_BIN)
        fixed = self.project.open_file_in_rom(
            'BALANCE/fixed.bin', FileType.FIXED_BIN,
            static_data=static_data
        )

        dungeon_bin_context: ModelContext[DungeonBinPack] = self.project.open_file_in_rom(
            'DUNGEON/dungeon.bin', FileType.DUNGEON_BIN, static_data=static_data, threadsafe=True
        )

        dungeon_list = HardcodedDungeons.get_dungeon_list(
            self.project.get_binary(BinaryName.ARM9), static_data
        )

        return mappings, mappa, fixed, dungeon_bin_context, dungeon_list
コード例 #8
0
ファイル: module.py プロジェクト: retke/skytemple
 def update(arm9bin):
     static_data = self.project.get_rom_module().get_static_data()
     HardcodedDungeons.set_marker_placements(markers, arm9bin,
                                             static_data)
コード例 #9
0
ファイル: module.py プロジェクト: retke/skytemple
 def get_world_map_markers(self) -> List[MapMarkerPlacement]:
     """Returns the world map markers"""
     arm9bin = self.project.get_binary(BinaryName.ARM9)
     static_data = self.project.get_rom_module().get_static_data()
     markers = HardcodedDungeons.get_marker_placements(arm9bin, static_data)
     return markers
コード例 #10
0
ファイル: module.py プロジェクト: SkyTemple/skytemple
 def get_tileset_properties(self) -> List[TilesetProperties]:
     return HardcodedDungeons.get_tileset_properties(
         self.project.get_binary(BinaryName.OVERLAY_10),
         self.project.get_rom_module().get_static_data())
コード例 #11
0
from skytemple_files.hardcoded.dungeons import HardcodedDungeons

base_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..')
rom_us = NintendoDSRom.fromFile(
    os.path.join(base_dir, 'skyworkcopy_us_unpatched.nds'))
ppmdu_us = get_ppmdu_config_for_rom(rom_us)
arm9_us = get_binary_from_rom_ppmdu(rom_us, ppmdu_us.binaries['arm9.bin'])
ov10_us = get_binary_from_rom_ppmdu(
    rom_us, ppmdu_us.binaries['overlay/overlay_0010.bin'])
rom_eu = NintendoDSRom.fromFile(os.path.join(base_dir, 'skyworkcopy_edit.nds'))
ppmdu_eu = get_ppmdu_config_for_rom(rom_eu)
ov10_eu = get_binary_from_rom_ppmdu(
    rom_eu, ppmdu_eu.binaries['overlay/overlay_0010.bin'])

# TilesetProperties
lst = HardcodedDungeons.get_tileset_properties(ov10_us, ppmdu_us)
for i, e in enumerate(lst):
    print(i, ': ', e)
HardcodedDungeons.set_tileset_properties(lst, ov10_us, ppmdu_us)
assert lst == HardcodedDungeons.get_tileset_properties(ov10_us, ppmdu_us)
assert lst == HardcodedDungeons.get_tileset_properties(ov10_eu, ppmdu_eu)

# IMPORT HELP USING THE PMD SPREADSHEET
info = """Beach Cave,Rock Slide,Rock,Cringe
Beach Cave Pit,Rock Slide,Rock,Cringe
Drenched Bluff,Rock Slide,Rock,Cringe
Mt. Bristle,Rock Slide,Rock,Cringe
Mt. Bristle Peak,Rock Slide,Rock,Cringe
Waterfall Cave,Rock Slide,Rock,Cringe
Apple Woods,Seed Bomb,Grass,Sleep
Craggy Coast,Rock Slide,Rock,Cringe
コード例 #12
0
 def get_dungeon_restrictions(self) -> List[DungeonRestriction]:
     # TODO: Cache?
     return HardcodedDungeons.get_dungeon_restrictions(
         self.project.get_binary(BinaryName.ARM9),
         self.project.get_rom_module().get_static_data())
コード例 #13
0
 def get_dungeon_list(self) -> List[DungeonDefinition]:
     if self._cached_dungeon_list == None:
         self._cached_dungeon_list = HardcodedDungeons.get_dungeon_list(
             self.project.get_binary(BinaryName.ARM9),
             self.project.get_rom_module().get_static_data())
     return self._cached_dungeon_list
コード例 #14
0
#  You should have received a copy of the GNU General Public License
#  along with SkyTemple.  If not, see <https://www.gnu.org/licenses/>.
import os

from ndspy.rom import NintendoDSRom

from skytemple_files.common.types.file_types import FileType
from skytemple_files.common.util import get_ppmdu_config_for_rom, get_binary_from_rom_ppmdu
from skytemple_files.hardcoded.dungeons import HardcodedDungeons

base_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..')
rom_us = NintendoDSRom.fromFile('/tmp/rando.nds')
ppmdu_us = get_ppmdu_config_for_rom(rom_us)
arm9_us = get_binary_from_rom_ppmdu(rom_us, ppmdu_us.binaries['arm9.bin'])

dungeon_list = HardcodedDungeons.get_dungeon_list(arm9_us, ppmdu_us)
for i, d in enumerate(dungeon_list):
    print(i, d)

# 0x35 (53) is used by dungeons >= 0xB4, which are NOT on the list (dojo dungeons).
print(set(range(0, 100)) - set([x.mappa_index for x in dungeon_list]))
# <<< {53}

# End:
# Function that returns the number of floors in a dungeon:
# if ID >= 0xB4 && ID <= 0xBD {
#     return 5
# } else if ID == 0xBE {
#     return 1
# } else if ID >= 0xBF {
#     return 0x30
コード例 #15
0
def draw_dungeon_map_bgs(rom, dungeon_map_bg_dir, config):
    os.makedirs(dungeon_map_bg_dir, exist_ok=True)
    dungeon_bin = FileType.DUNGEON_BIN.deserialize(rom.getFileByName('DUNGEON/dungeon.bin'), config)

    ground_dungeon_tilesets = HardcodedGroundDungeonTilesets.get_ground_dungeon_tilesets(
        get_binary_from_rom_ppmdu(rom, config.binaries['overlay/overlay_0011.bin']),
        config
    )
    dungeons = HardcodedDungeons.get_dungeon_list(
        get_binary_from_rom_ppmdu(rom, config.binaries['arm9.bin']),
        config
    )
    mappa = FileType.MAPPA_BIN.deserialize(rom.getFileByName('BALANCE/mappa_s.bin'))
    
    levels_by_id = config.script_data.level_list__by_id

    bg_list_bin = rom.getFileByName('MAP_BG/bg_list.dat')
    bg_list = FileType.BG_LIST_DAT.deserialize(bg_list_bin)

    for i, entry in enumerate(ground_dungeon_tilesets):
        if entry.ground_level >= 0xFFFF:
            continue
        level = levels_by_id[entry.ground_level]
        print(f"{i + 1}/{len(ground_dungeon_tilesets)-1} - {level.name}")
        print(entry)

        mappa_idx = dungeons[entry.dungeon_id].mappa_index
        start_offset = dungeons[entry.dungeon_id].start_after
        length = dungeons[entry.dungeon_id].number_floors
        if entry.dungeon_id == 71:
            print("DEEP CONCEALED RUINS SKIPPED")
            continue
        if entry.unk2 == 1:
            tileset_id = mappa.floor_lists[mappa_idx][start_offset].layout.tileset_id
        elif entry.unk2 == 100:
            tileset_id = mappa.floor_lists[mappa_idx][start_offset + length - 1].layout.tileset_id
        else:
            raise ValueError("Unknown unk2")
        if tileset_id == 170:
            tileset_id = 1
        dma: Dma = dungeon_bin.get(f'dungeon{tileset_id}.dma')
        dpl: Dpl = dungeon_bin.get(f'dungeon{tileset_id}.dpl')
        dpla: Dpla = dungeon_bin.get(f'dungeon{tileset_id}.dpla')
        dpci: Dpci = dungeon_bin.get(f'dungeon{tileset_id}.dpci')
        dpc: Dpc = dungeon_bin.get(f'dungeon{tileset_id}.dpc')

        bma: Bma = bg_list.level[level.mapid].get_bma(rom)

        duration = round(1000 / 60 * max(16, min(dpla.durations_per_frame_for_colors)))

        drawer = DmaDrawer(dma)
        rules = drawer.rules_from_bma(bma)
        mappings = drawer.get_mappings_for_rules(rules, treat_outside_as_wall=True, variation_index=0)
        frames = drawer.draw(mappings, dpci, dpc, dpl, dpla)
        frames[0].save(
            os.path.join(dungeon_map_bg_dir, level.name + '.gif'),
            save_all=True,
            append_images=frames[1:],
            duration=duration,
            loop=0,
            optimize=False
        )
        frames[0].save(
            os.path.join(dungeon_map_bg_dir, level.name + '.png')
        )
コード例 #16
0
from ndspy.rom import NintendoDSRom

from skytemple_files.common.types.file_types import FileType
from skytemple_files.common.util import get_ppmdu_config_for_rom, get_binary_from_rom_ppmdu
from skytemple_files.dungeon_data.mappa_bin.validator.exception import DungeonTotalFloorCountInvalidError
from skytemple_files.dungeon_data.mappa_bin.validator.validator import DungeonValidator
from skytemple_files.hardcoded.dungeons import HardcodedDungeons

rom = NintendoDSRom.fromFile('../../../../../4261 - Pokemon Mystery Dungeon Explorers of Sky (U)(Xenophobia).nds')
config = get_ppmdu_config_for_rom(rom)

mappa_bin = rom.getFileByName('BALANCE/mappa_s.bin')
mappa = FileType.MAPPA_BIN.deserialize(mappa_bin)

dungeons = HardcodedDungeons.get_dungeon_list(
    get_binary_from_rom_ppmdu(rom, config.binaries['arm9.bin']),
    config
)

for i, dungeon in enumerate(dungeons):
    print(i, dungeon)
print("")

validator = DungeonValidator(mappa.floor_lists)
validator.validate(dungeons)
for e in validator.errors:
    if not isinstance(e, DungeonTotalFloorCountInvalidError):
        print(repr(e))

print("")
print(validator.invalid_dungeons)
コード例 #17
0
 def update(arm9):
     HardcodedDungeons.set_secondary_terrains(secondary_terrains, arm9, static)
コード例 #18
0
 def save_dungeon_list(self, dungeons: List[DungeonDefinition]):
     self.project.modify_binary(
         BinaryName.ARM9, lambda binary: HardcodedDungeons.set_dungeon_list(
             dungeons, binary,
             self.project.get_rom_module().get_static_data()))
     self._cached_dungeon_list = None
コード例 #19
0
    def apply(self, apply: Callable[[], None], rom: NintendoDSRom,
              config: Pmd2Data):
        if not self.is_applied(rom, config):
            if config.game_version == GAME_VERSION_EOS:
                if config.game_region == GAME_REGION_US:
                    rank_table = FLOOR_RANKS_TABLE_US
                    item_table = ITEM_AVAILABLE_TABLE_US
                    forbid_table = FLOOR_FORBID_TABLE_US
                if config.game_region == GAME_REGION_EU:
                    rank_table = FLOOR_RANKS_TABLE_EU
                    item_table = ITEM_AVAILABLE_TABLE_EU
                    forbid_table = FLOOR_FORBID_TABLE_EU

            header = bytearray(NB_ITEMS_TABLE * 4)
            rank_data = bytearray(0)
            forbid_data = bytearray(0)
            current_ptr = len(header)
            for i in range(NB_ITEMS_TABLE):
                start = read_uintle(rom.arm9, rank_table + i * 4,
                                    4) - ARM9_START
                end = start + 1 + FLOORS_NB[i]
                if end % 4 != 0:
                    end += 4 - (end % 4)
                rdata = rom.arm9[start:end]
                fdata = bytearray(len(rdata))
                x = forbid_table
                while rom.arm9[x] != 0x64:
                    if rom.arm9[x] == i:
                        fdata[rom.arm9[x + 1]] = 1
                    x += 2
                rom.arm9 = rom.arm9[:start] + bytes(
                    [0xCC] * (end - start)) + rom.arm9[end:]
                write_uintle(header, current_ptr, i * 4, 4)
                rank_data += bytearray(rdata)
                forbid_data += bytearray(fdata)

                current_ptr += end - start
            file_data = header + rank_data
            if FLOOR_RANKS_PATH not in rom.filenames:
                create_file_in_rom(rom, FLOOR_RANKS_PATH, file_data)
            else:
                rom.setFileByName(FLOOR_RANKS_PATH, file_data)
            file_data = header + forbid_data
            if FLOOR_FORBID_PATH not in rom.filenames:
                create_file_in_rom(rom, FLOOR_FORBID_PATH, file_data)
            else:
                rom.setFileByName(FLOOR_FORBID_PATH, file_data)

            dungeon_list = HardcodedDungeons.get_dungeon_list(rom.arm9, config)
            groups = [d.mappa_index for d in dungeon_list]
            print(hex(len(groups)))
            list_available = []
            for x in range(AVAILABLE_ITEMS_NB):
                list_available.append(bytearray(0x100 // 8))
                for i, g in enumerate(groups):
                    off = item_table + g * (AVAILABLE_ITEMS_NB // 8) + (x // 8)
                    if rom.arm9[off] & (1 << (x % 8)):
                        list_available[-1][i // 8] |= 1 << (i % 8)
            file_data = bytearray().join(list_available)
            if AVAILABLE_ITEMS_PATH not in rom.filenames:
                create_file_in_rom(rom, AVAILABLE_ITEMS_PATH, file_data)
            else:
                rom.setFileByName(AVAILABLE_ITEMS_PATH, file_data)
        try:
            apply()
        except RuntimeError as ex:
            raise ex
コード例 #20
0
    def apply(self, apply: Callable[[], None], rom: NintendoDSRom,
              config: Pmd2Data) -> None:
        if config.game_version == GAME_VERSION_EOS:
            if config.game_region == GAME_REGION_US:
                new_pkmn_str_region = US_NEW_PKMN_STR_REGION
                new_cat_str_region = US_NEW_CAT_STR_REGION
                file_assoc = US_FILE_ASSOC
                table_sf = US_TABLE_SF
                table_mf = US_TABLE_MF
                table_sp = US_TABLE_SP
            if config.game_region == GAME_REGION_EU:
                new_pkmn_str_region = EU_NEW_PKMN_STR_REGION
                new_cat_str_region = EU_NEW_CAT_STR_REGION
                file_assoc = EU_FILE_ASSOC
                table_sf = EU_TABLE_SF
                table_mf = EU_TABLE_MF
                table_sp = EU_TABLE_SP
        if not self.is_applied(rom, config):
            bincfg = config.binaries['arm9.bin']
            binary = bytearray(get_binary_from_rom_ppmdu(rom, bincfg))

            # Apply the patch
            for filename in get_files_from_rom_with_extension(rom, 'str'):
                bin_before = rom.getFileByName(filename)
                strings = StrHandler.deserialize(bin_before)
                block = config.string_index_data.string_blocks['Pokemon Names']
                monsters = strings.strings[block.begin:block.end]
                strings.strings[block.begin:block.end] = [""] * (block.end -
                                                                 block.begin)
                block = config.string_index_data.string_blocks[
                    'Pokemon Categories']
                cats = strings.strings[block.begin:block.end]
                strings.strings[block.begin:block.end] = [""] * (block.end -
                                                                 block.begin)
                for x in range(NUM_NEW_ENTRIES):
                    if x < NUM_PREVIOUS_ENTRIES * 2:
                        str_pkmn = monsters[x % NUM_PREVIOUS_ENTRIES]
                    else:
                        str_pkmn = "DmyPk%04d" % x
                    if len(strings.strings) <= new_pkmn_str_region + x - 1:
                        strings.strings.append(str_pkmn)
                    else:
                        strings.strings[new_pkmn_str_region + x - 1] = str_pkmn
                for x in range(NUM_NEW_ENTRIES):
                    if x < NUM_PREVIOUS_ENTRIES * 2:
                        str_cat = cats[x % NUM_PREVIOUS_ENTRIES]
                    else:
                        str_cat = "DmyCa%04d" % x
                    if len(strings.strings) <= new_cat_str_region + x - 1:
                        strings.strings.append(str_cat)
                    else:
                        strings.strings[new_cat_str_region + x - 1] = str_cat
                bin_after = StrHandler.serialize(strings)
                rom.setFileByName(filename, bin_after)

                sorted_list = list(
                    enumerate(strings.strings[new_pkmn_str_region -
                                              1:new_pkmn_str_region - 1 +
                                              NUM_NEW_ENTRIES]))
                sorted_list.sort(key=lambda x: normalize_string(x[1]))
                sorted_list = [x[0] for x in sorted_list]
                inv_sorted_list = [
                    sorted_list.index(i) for i in range(NUM_NEW_ENTRIES)
                ]
                m2n_model = ValListHandler.deserialize(
                    rom.getFileByName(file_assoc[filename][0]))
                m2n_model.set_list(inv_sorted_list)
                rom.setFileByName(file_assoc[filename][0],
                                  ValListHandler.serialize(m2n_model))
                n2m_model = ValListHandler.deserialize(
                    rom.getFileByName(file_assoc[filename][1]))
                n2m_model.set_list(sorted_list)
                rom.setFileByName(file_assoc[filename][1],
                                  ValListHandler.serialize(n2m_model))

            # Expand kao file
            kao_bin = rom.getFileByName('FONT/kaomado.kao')
            kao_model = KaoHandler.deserialize(kao_bin)
            kao_model.expand(NUM_NEW_ENTRIES - 1)
            for i in range(NUM_PREVIOUS_ENTRIES - 1):
                for j in range(SUBENTRIES):
                    a = kao_model.get(i, j)
                    b = kao_model.get(i + NUM_PREVIOUS_ENTRIES, j)
                    if b == None and a != None:
                        kao_model.set(i + NUM_PREVIOUS_ENTRIES, j, a)
            rom.setFileByName('FONT/kaomado.kao',
                              KaoHandler.serialize(kao_model))

            # Expand tbl_talk
            tlk_bin = rom.getFileByName('MESSAGE/tbl_talk.tlk')
            tlk_model = TblTalkHandler.deserialize(tlk_bin)
            while tlk_model.get_nb_monsters() < NUM_NEW_ENTRIES:
                tlk_model.add_monster_personality(DUMMY_PERSONALITY)
            rom.setFileByName('MESSAGE/tbl_talk.tlk',
                              TblTalkHandler.serialize(tlk_model))

            # Add monsters
            md_bin = rom.getFileByName('BALANCE/monster.md')
            md_model = MdHandler.deserialize(md_bin)
            while len(md_model.entries) < NUM_NEW_ENTRIES:
                md_model.entries.append(
                    MdEntry.new_empty(u16_checked(len(md_model.entries))))
            for i in range(NUM_PREVIOUS_ENTRIES):
                md_model.entries[i].entid = i
                if md_model.entries[NUM_PREVIOUS_ENTRIES +
                                    i].gender == Gender.INVALID:
                    md_model.entries[NUM_PREVIOUS_ENTRIES +
                                     i].entid = NUM_PREVIOUS_ENTRIES + i
                else:
                    md_model.entries[NUM_PREVIOUS_ENTRIES + i].entid = i
            block = bincfg.symbols['MonsterSpriteData']
            data = binary[block.begin:block.end] + binary[block.begin:block.
                                                          end]
            data += b'\x00\x00' * (NUM_NEW_ENTRIES - (len(data) // 2))
            for i in range(0, len(data), 2):
                md_model.entries[i // 2].unk17 = data[i]
                md_model.entries[i // 2].unk18 = data[i + 1]
                md_model.entries[i // 2].bitfield1_0 = False
                md_model.entries[i // 2].bitfield1_1 = False
                md_model.entries[i // 2].bitfield1_2 = False
                md_model.entries[i // 2].bitfield1_3 = False

            x = table_sf
            while read_u16(rom.arm9, x) != 0:
                pkmn_id = read_u16(rom.arm9, x)
                md_model.entries[pkmn_id].bitfield1_3 = True  # pylint: disable=invalid-sequence-index
                if md_model.entries[NUM_PREVIOUS_ENTRIES +
                                    pkmn_id].gender != Gender.INVALID:
                    md_model.entries[NUM_PREVIOUS_ENTRIES +
                                     pkmn_id].bitfield1_3 = True
                x += 2
            x = table_mf
            while read_u16(rom.arm9, x) != 0:
                pkmn_id = read_u16(rom.arm9, x)
                md_model.entries[pkmn_id].bitfield1_2 = True  # pylint: disable=invalid-sequence-index
                if md_model.entries[NUM_PREVIOUS_ENTRIES +
                                    pkmn_id].gender != Gender.INVALID:
                    md_model.entries[NUM_PREVIOUS_ENTRIES +
                                     pkmn_id].bitfield1_2 = True
                x += 2
            ov19 = rom.loadArm9Overlays([19])[19].data
            for x in range(table_sp, table_sp + TABLE_SP_SIZE, 2):
                pkmn_id = read_u16(ov19, x)
                md_model.entries[pkmn_id].bitfield1_1 = True  # pylint: disable=invalid-sequence-index
                md_model.entries[pkmn_id].bitfield1_0 = True  # pylint: disable=invalid-sequence-index
                if md_model.entries[NUM_PREVIOUS_ENTRIES +
                                    pkmn_id].gender != Gender.INVALID:
                    md_model.entries[NUM_PREVIOUS_ENTRIES +
                                     pkmn_id].bitfield1_1 = True
                    md_model.entries[NUM_PREVIOUS_ENTRIES +
                                     pkmn_id].bitfield1_0 = True

            rom.setFileByName('BALANCE/monster.md',
                              MdHandler.serialize(md_model))

            # Edit Mappa bin
            mappa_bin = rom.getFileByName('BALANCE/mappa_s.bin')
            mappa_model = MappaBinHandler.deserialize(mappa_bin)
            dl = HardcodedDungeons.get_dungeon_list(bytes(rom.arm9), config)
            # Handle Dojos
            start_floor = 0
            for x in range(DOJO_DUNGEONS_FIRST, DOJO_DUNGEONS_LAST - 2):
                dl.append(
                    DungeonDefinition(u8(5), DOJO_MAPPA_ENTRY, u8(start_floor),
                                      u8(0)))
                start_floor += 5
            dl.append(
                DungeonDefinition(u8(1), DOJO_MAPPA_ENTRY, u8(start_floor),
                                  u8(0)))
            start_floor += 1
            dl.append(
                DungeonDefinition(u8(0x30), DOJO_MAPPA_ENTRY, u8(start_floor),
                                  u8(0)))
            start_floor += 0x30
            for dungeon in dl:
                for f in range(dungeon.start_after + 1,
                               dungeon.start_after + dungeon.number_floors, 2):
                    try:
                        for entry in mappa_model.floor_lists[
                                dungeon.mappa_index][f].monsters:
                            if entry.md_index != DUMMY_PKMN and entry.md_index < NUM_PREVIOUS_ENTRIES and \
                                    entry.md_index + NUM_PREVIOUS_ENTRIES < len(md_model.entries) and \
                                    md_model.entries[entry.md_index + NUM_PREVIOUS_ENTRIES].gender != Gender.INVALID:
                                entry.md_index += NUM_PREVIOUS_ENTRIES
                    except:
                        print(f"{dungeon.mappa_index}, {f} is not valid.")
            rom.setFileByName('BALANCE/mappa_s.bin',
                              MappaBinHandler.serialize(mappa_model))

            # Add moves
            waza_p_bin = rom.getFileByName('BALANCE/waza_p.bin')
            waza_p_model = WazaPHandler.deserialize(waza_p_bin)
            while len(waza_p_model.learnsets) < NUM_PREVIOUS_ENTRIES:
                waza_p_model.learnsets.append(
                    waza_p_model.learnsets[DUMMY_LS])  # Max Moveset
            waza_p_model.learnsets = waza_p_model.learnsets + waza_p_model.learnsets
            while len(waza_p_model.learnsets) < NUM_NEW_ENTRIES:
                waza_p_model.learnsets.append(
                    waza_p_model.learnsets[DUMMY_LS])  # Max Moveset
            rom.setFileByName('BALANCE/waza_p.bin',
                              WazaPHandler.serialize(waza_p_model))

            # Add moves 2
            waza_p_bin = rom.getFileByName('BALANCE/waza_p2.bin')
            waza_p_model = WazaPHandler.deserialize(waza_p_bin)
            while len(waza_p_model.learnsets) < NUM_PREVIOUS_ENTRIES:
                waza_p_model.learnsets.append(
                    waza_p_model.learnsets[DUMMY_LS])  # Max Moveset
            waza_p_model.learnsets = waza_p_model.learnsets + waza_p_model.learnsets
            while len(waza_p_model.learnsets) < NUM_NEW_ENTRIES:
                waza_p_model.learnsets.append(
                    waza_p_model.learnsets[DUMMY_LS])  # Max Moveset
            rom.setFileByName('BALANCE/waza_p2.bin',
                              WazaPHandler.serialize(waza_p_model))

            # Add levels
            level_bin = rom.getFileByName('BALANCE/m_level.bin')
            level_model = BinPackHandler.deserialize(level_bin)
            while len(level_model.get_files_bytes()) < NUM_PREVIOUS_ENTRIES:
                new_bytes_unpacked = bytes(LEVEL_BIN_ENTRY_LEVEL_LEN * 100)
                new_bytes_pkdpx = PkdpxHandler.serialize(
                    PkdpxHandler.compress(new_bytes_unpacked))
                new_bytes = Sir0Handler.serialize(
                    Sir0Handler.wrap(new_bytes_pkdpx, []))
                level_model.append(new_bytes)  # Empty Levelup data
            for i in range(NUM_PREVIOUS_ENTRIES):
                level_model.append(level_model[i])
            while len(level_model.get_files_bytes()) < NUM_NEW_ENTRIES:
                new_bytes_unpacked = bytes(LEVEL_BIN_ENTRY_LEVEL_LEN * 100)
                new_bytes_pkdpx = PkdpxHandler.serialize(
                    PkdpxHandler.compress(new_bytes_unpacked))
                new_bytes = Sir0Handler.serialize(
                    Sir0Handler.wrap(new_bytes_pkdpx, []))
                level_model.append(new_bytes)  # Empty Levelup data
            rom.setFileByName('BALANCE/m_level.bin',
                              BinPackHandler.serialize(level_model))

            # Add evolutions
            evo_bin = rom.getFileByName('BALANCE/md_evo.bin')
            evo_model = MdEvoHandler.deserialize(evo_bin)
            while len(evo_model.evo_entries) < NUM_NEW_ENTRIES:
                evo_model.evo_entries.append(
                    MdEvoEntry(bytearray(MEVO_ENTRY_LENGTH)))
            while len(evo_model.evo_stats) < NUM_NEW_ENTRIES:
                evo_model.evo_stats.append(
                    MdEvoStats(bytearray(MEVO_STATS_LENGTH)))
            rom.setFileByName('BALANCE/md_evo.bin',
                              MdEvoHandler.serialize(evo_model))

            # Fixed floors
            ov29 = config.binaries['overlay/overlay_0029.bin']
            ov29bin = bytearray(get_binary_from_rom_ppmdu(rom, ov29))
            monster_list = HardcodedFixedFloorTables.get_monster_spawn_list(
                ov29bin, config)
            for m in monster_list:
                if m.md_idx >= NUM_PREVIOUS_MD_MAX:
                    m.md_idx += NUM_NEW_ENTRIES - NUM_PREVIOUS_MD_MAX
            HardcodedFixedFloorTables.set_monster_spawn_list(
                ov29bin, monster_list, config)
            set_binary_in_rom_ppmdu(rom, ov29, bytes(ov29bin))
        try:
            apply()
        except RuntimeError as ex:
            raise ex