Esempio n. 1
0
    def run(self, status: Status):
        if not self.config['improvements']['download_portraits']:
            return status.done()

        status.step("Apply 'ActorAndLevelLoader' patch...")
        patcher = Patcher(self.rom, self.static_data)
        if not patcher.is_applied('ActorAndLevelLoader'):
            patcher.apply('ActorAndLevelLoader')

        overlay13 = get_binary_from_rom_ppmdu(
            self.rom, self.static_data.binaries['overlay/overlay_0013.bin'])
        actor_list: ActorListBin = FileType.SIR0.unwrap_obj(
            FileType.SIR0.deserialize(
                self.rom.getFileByName('BALANCE/actor_list.bin')),
            ActorListBin)
        starters = HardcodedPersonalityTestStarters.get_partner_md_ids(
            overlay13, self.static_data)
        partners = HardcodedPersonalityTestStarters.get_player_md_ids(
            overlay13, self.static_data)
        md = FileType.MD.deserialize(
            self.rom.getFileByName('BALANCE/monster.md'))

        with urllib.request.urlopen(
                "http://sprites.pmdcollab.org/resources/pokemons.json") as url:
            config = json.loads(url.read().decode())

        kao = FileType.KAO.deserialize(
            self.rom.getFileByName('FONT/kaomado.kao'))

        if fun.is_fun_allowed():
            status.step("Downloading portraits...")
            fun.replace_portraits(self.rom, self.static_data)
            return status.done()

        status.step("Downloading portraits for NPCs...")
        for actor in actor_list.list:
            if actor.entid > 0:
                self._import_portrait(kao, config, actor.entid,
                                      md.entries[actor.entid])

        status.step("Downloading portraits for starters...")
        for starter in starters:
            self._import_portrait(kao, config, starter, md.entries[starter])

        status.step("Downloading portraits for partners...")
        for partner in partners:
            self._import_portrait(kao, config, partner, md.entries[partner])

        self.rom.setFileByName('FONT/kaomado.kao', FileType.KAO.serialize(kao))

        def add_rows():
            if Global.main_builder:
                o = Global.main_builder.get_object('store_debug_portraits')
                o.clear()
                for row in self._debugs:
                    o.append(row)

        self.frontend.idle_add(add_rows)

        status.done()
    def run(self, status: Status):
        if not self.config['starters_npcs']['npcs']:
            return status.done()

        status.step("Apply 'ActorAndLevelLoader' patch...")
        patcher = Patcher(self.rom, self.static_data)
        if not patcher.is_applied('ActorAndLevelLoader'):
            patcher.apply('ActorAndLevelLoader')

        status.step("Updating special recruitment table...")

        actor_list: ActorListBin = FileType.SIR0.unwrap_obj(
            FileType.SIR0.deserialize(
                self.rom.getFileByName('BALANCE/actor_list.bin')),
            ActorListBin)

        binary = get_binary_from_rom_ppmdu(
            self.rom, self.static_data.binaries['overlay/overlay_0011.bin'])
        sp_list = HardcodedRecruitmentTables.get_monster_species_list(
            binary, self.static_data)

        for i, actor in enumerate(actor_list.list):
            if i in ACTOR_TO_RECRUIT_MAPPING:
                for bi in ACTOR_TO_RECRUIT_MAPPING[i]:
                    sp_list[bi] = actor.entid

        HardcodedRecruitmentTables.set_monster_species_list(
            sp_list, binary, self.static_data)
        set_binary_in_rom_ppmdu(
            self.rom, self.static_data.binaries['overlay/overlay_0011.bin'],
            binary)

        status.done()
Esempio n. 3
0
def create_mapping():
    from ndspy.rom import NintendoDSRom
    rom = NintendoDSRom.fromFile(
        '/home/marco/dev/skytemple/skytemple/skyworkcopy_us_unpatched.nds')
    from skytemple_files.common.util import get_ppmdu_config_for_rom
    static_data = get_ppmdu_config_for_rom(rom)
    from skytemple_files.patch.patches import Patcher
    patcher = Patcher(rom, static_data)
    patcher.apply('ActorAndLevelLoader')

    from skytemple_files.common.types.file_types import FileType
    from skytemple_files.data.md.model import Md
    md: Md = FileType.MD.deserialize(rom.getFileByName('BALANCE/monster.md'))
    from skytemple_files.list.actor.model import ActorListBin
    actor_list: ActorListBin = FileType.SIR0.unwrap_obj(
        FileType.SIR0.deserialize(rom.getFileByName('BALANCE/actor_list.bin')),
        ActorListBin)
    from skytemple_files.hardcoded.fixed_floor import HardcodedFixedFloorTables
    from skytemple_files.common.util import get_binary_from_rom_ppmdu
    boss_list = HardcodedFixedFloorTables.get_monster_spawn_list(
        get_binary_from_rom_ppmdu(
            rom, static_data.binaries['overlay/overlay_0029.bin']),
        static_data)

    actor_list_pokedex_number_mapping = []
    for e in actor_list.list:
        monster = md.entries[e.entid]
        actor_list_pokedex_number_mapping.append(
            monster.national_pokedex_number)

    boss_list_pokedex_number_mapping = []
    for boss in boss_list:
        try:
            monster = md.entries[boss.md_idx]
            boss_list_pokedex_number_mapping.append(
                monster.national_pokedex_number)
        except IndexError:
            boss_list_pokedex_number_mapping.append(0)

    mapping = {}
    for idx, a in enumerate(actor_list_pokedex_number_mapping):
        if a == 0:
            continue
        indices = [
            i for i, x in enumerate(boss_list_pokedex_number_mapping) if x == a
        ]
        if len(indices) > 0:
            mapping[idx] = indices

    print(mapping)
Esempio n. 4
0
    def run(self, status: Status):
        if not self.config['starters_npcs']['npcs']:
            return status.done()
        lang, string_file = get_main_string_file(self.rom, self.static_data)
        pokemon_string_data = self.static_data.string_index_data.string_blocks[
            "Pokemon Names"]

        status.step("Apply 'ActorAndLevelLoader' patch...")
        patcher = Patcher(self.rom, self.static_data)
        if not patcher.is_applied('ActorAndLevelLoader'):
            patcher.apply('ActorAndLevelLoader')

        status.step("Randomizing NPC actor list...")
        mapped_actors = self._randomize_actors(string_file,
                                               pokemon_string_data)

        status.step("Replacing main text that mentions NPCs...")
        names_mapped_all = {}
        for lang, string_file in get_all_string_files(self.rom,
                                                      self.static_data):
            names_mapped = {}
            names_mapped_all[lang] = names_mapped
            for old, new in mapped_actors.items():
                old_base = old % 600
                new_base = new % 600
                old_name = self._get_name(string_file, old_base,
                                          pokemon_string_data)
                new_name = self._get_name(string_file, new_base,
                                          pokemon_string_data)
                names_mapped[old_name] = new_name
            replace_text_main(string_file, names_mapped,
                              pokemon_string_data.begin,
                              pokemon_string_data.end)
            self.rom.setFileByName(f'MESSAGE/{lang.filename}',
                                   FileType.STR.serialize(string_file))

        status.step("Replacing script text that mentions NPCs...")
        replace_text_script(self.rom, self.static_data, names_mapped_all)

        status.step("Cloning missing NPC portraits...")
        kao = FileType.KAO.deserialize(
            self.rom.getFileByName('FONT/kaomado.kao'))
        for new in mapped_actors.values():
            new_base = new % 600
            clone_missing_portraits(kao, new_base - 1)
        self.rom.setFileByName('FONT/kaomado.kao', FileType.KAO.serialize(kao))

        status.done()
Esempio n. 5
0
    def _patch_credits(self):
        credits = ""
        for patch in Patcher(self.rom, self.static_data).list():
            try:
                if patch.is_applied(self.rom, self.static_data):
                    desc = patch.description.replace('\n', '\\n')
                    credits += f"""
        case menu("{patch.name}"):
            message_Mail("[CS:A]{escape(patch.name)}[CR]\\nby [CS:A]{escape(patch.author)}[CR]\\n\\n{escape(desc)}");
            jump @l_patches; 
"""
            except NotImplementedError:
                pass
        return credits
Esempio n. 6
0
    def run(self, status: Status):
        if not self.config['starters_npcs']['npcs']:
            return status.done()

        status.step("Apply 'ActorAndLevelLoader' patch...")
        patcher = Patcher(self.rom, self.static_data)
        if not patcher.is_applied('ActorAndLevelLoader'):
            patcher.apply('ActorAndLevelLoader')

        status.step("Updating bosses...")

        actor_list: ActorListBin = FileType.SIR0.unwrap_obj(
            FileType.SIR0.deserialize(
                self.rom.getFileByName('BALANCE/actor_list.bin')),
            ActorListBin)

        binary = get_binary_from_rom_ppmdu(
            self.rom, self.static_data.binaries['overlay/overlay_0029.bin'])
        boss_list = HardcodedFixedFloorTables.get_monster_spawn_list(
            binary, self.static_data)

        for i, actor in enumerate(actor_list.list):
            if i in ACTOR_TO_BOSS_MAPPING:
                for bi in ACTOR_TO_BOSS_MAPPING[i]:
                    boss_list[bi].md_idx = actor.entid

        for extra_id in EXTRA_FF_MONSTER_RANDOMIZE:
            boss_list[extra_id].md_idx = choice(
                get_allowed_md_ids(self.config, False))

        HardcodedFixedFloorTables.set_monster_spawn_list(
            binary, boss_list, self.static_data)
        set_binary_in_rom_ppmdu(
            self.rom, self.static_data.binaries['overlay/overlay_0029.bin'],
            binary)

        status.done()
Esempio n. 7
0
    def run(self, status: Status):
        if not self.config['starters_npcs']['global_items']:
            return

        status.step("Apply patches...")
        patcher = Patcher(self.rom, self.static_data)
        if not patcher.is_applied('ActorAndLevelLoader'):
            patcher.apply('ActorAndLevelLoader')
        if not patcher.is_applied('ExtractHardcodedItemLists'):
            patcher.apply('ExtractHardcodedItemLists')

        status.step("Randomizing global item lists...")
        for i in range(0, ITEM_LIST_COUNT):
            self.rom.setFileByName(
                f'TABLEDAT/list_{i:02}.bin',
                ItemListHandler.serialize(self._randomize_items()))

        status.done()
Esempio n. 8
0
#  along with SkyTemple.  If not, see <https://www.gnu.org/licenses/>.
import os

from ndspy.rom import NintendoDSRom

from skytemple_files.common.util import get_ppmdu_config_for_rom, create_file_in_rom, set_binary_in_rom_ppmdu
from skytemple_files.patch.patches import Patcher

if __name__ == '__main__':
    out_dir = os.path.join(os.path.dirname(__file__), 'dbg_output')
    base_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..')
    os.makedirs(out_dir, exist_ok=True)

    in_rom = NintendoDSRom.fromFile(
        os.path.join(base_dir, 'skyworkcopy_us.nds'))
    patcher = Patcher(in_rom, get_ppmdu_config_for_rom(in_rom))
    assert not patcher.is_applied('ActorAndLevelLoader')

    patcher.apply('ActorAndLevelLoader')
    with open(os.path.join(out_dir, 'actor_list.bin'), 'wb') as f:
        f.write(in_rom.getFileByName('BALANCE/actor_list.bin'))
    with open(os.path.join(out_dir, 'level_list.bin'), 'wb') as f:
        f.write(in_rom.getFileByName('BALANCE/level_list.bin'))

    assert patcher.is_applied('ActorAndLevelLoader')
    in_rom.saveToFile(os.path.join(out_dir, 'patched.nds'))

    # Check if really patched
    out_rom = NintendoDSRom.fromFile(os.path.join(out_dir, 'patched.nds'))
    assert Patcher(
        out_rom,
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  SkyTemple is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  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.util import get_ppmdu_config_for_rom, create_file_in_rom, set_binary_in_rom_ppmdu
from skytemple_files.patch.patches import Patcher

if __name__ == '__main__':
    out_dir = os.path.join(os.path.dirname(__file__), 'dbg_output')
    base_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..')
    os.makedirs(out_dir, exist_ok=True)

    in_rom = NintendoDSRom.fromFile(os.path.join(base_dir, 'skyworkcopy.nds'))
    patcher = Patcher(in_rom, get_ppmdu_config_for_rom(in_rom))
    assert not patcher.is_applied('MoveShortcuts')

    patcher.apply('MoveShortcuts')

    assert patcher.is_applied('MoveShortcuts')
    in_rom.saveToFile(os.path.join(out_dir, 'patched.nds'))
Esempio n. 10
0
 def create_patcher(self):
     if self._patcher is None:
         self._patcher = Patcher(self._rom,
                                 self.get_rom_module().get_static_data())
     return self._patcher
Esempio n. 11
0
 def create_patcher(self):
     return Patcher(self._rom, self.get_rom_module().get_static_data())
from skytemple_files.patch.errors import PatchNotConfiguredError

if __name__ == '__main__':
    out_dir = os.path.join(os.path.dirname(__file__), 'dbg_output')
    base_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..')
    package = os.path.join(os.path.dirname(__file__), 'parameters_test')
    os.makedirs(out_dir, exist_ok=True)
    os.environ['SKYTEMPLE_DEBUG_ARMIPS_OUTPUT'] = 'YES'

    in_rom = NintendoDSRom.fromFile(os.path.join(base_dir, 'skyworkcopy.nds'))

    # Load PPMDU config, but remove all data about Patches and LooseBinFiles.
    config = get_ppmdu_config_for_rom(in_rom)
    config.asm_patches_constants.patches = {}
    config.asm_patches_constants.loose_bin_files = {}
    patcher = Patcher(in_rom, config, skip_core_patches=True)

    # Load the package
    patcher.add_pkg(package, False)
    assert not patcher.is_applied('ParametersTest')

    # Missing params
    try:
        patcher.apply('ParametersTest')
    except PatchNotConfiguredError:
        pass
    else:
        assert False, "Must throw PatchNotConfiguredError"

    # Invalid params
    try:
    def run(self, status: Status):
        patcher = Patcher(self.rom, self.static_data)

        status.step("Apply base patches by psy_commando, irdkwia and End45...")
        sleep(5)  # gotta give some spotlight to them.
        if not patcher.is_applied('ActorAndLevelLoader'):
            patcher.apply('ActorAndLevelLoader')
        if not patcher.is_applied('ProvideATUPXSupport'):
            patcher.apply('ProvideATUPXSupport')
        if not patcher.is_applied('ExtraSpace'):
            patcher.apply('ExtraSpace')

        if self.config['improvements']['patch_moveshortcuts']:
            status.step("Apply 'MoveShortcuts' patch...")
            if not patcher.is_applied('MoveShortcuts'):
                patcher.apply('MoveShortcuts')

        if self.config['improvements']['patch_unuseddungeonchance']:
            status.step("Apply 'UnusedDungeonChancePatch' patch...")
            if not patcher.is_applied('UnusedDungeonChancePatch'):
                patcher.apply('UnusedDungeonChancePatch')

        if self.config['improvements']['patch_totalteamcontrol']:
            status.step("Apply 'Complete Team Control' patches...")
            if not patcher.is_applied('CompleteTeamControl'):
                patcher.apply('CompleteTeamControl')
            if not patcher.is_applied('FarOffPalOverdrive'):
                patcher.apply('FarOffPalOverdrive')
            if not patcher.is_applied('PartnersTriggerHiddenTraps'):
                patcher.apply('PartnersTriggerHiddenTraps')
            if not patcher.is_applied('ReduceJumpcutPauseTime'):
                patcher.apply('ReduceJumpcutPauseTime')

        status.done()
Esempio n. 14
0
if __name__ == '__main__':
    out_dir = os.path.join(os.path.dirname(__file__), 'dbg_output')
    base_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..')
    package = os.path.join(os.path.dirname(__file__), '..', '..', '..', 'docs',
                           'patch_packages', 'example_patch.skypatch')
    os.makedirs(out_dir, exist_ok=True)

    in_rom = NintendoDSRom.fromFile(
        os.path.join(base_dir, 'skyworkcopy_us.nds'))

    # Load PPMDU config, but remove all data about Patches and LooseBinFiles.
    config = get_ppmdu_config_for_rom(in_rom)
    config.asm_patches_constants.patches = {}
    config.asm_patches_constants.loose_bin_files = {}

    patcher = Patcher(in_rom, config, skip_core_patches=True)

    # Load the package
    patcher.add_pkg(package)
    assert not patcher.is_applied('ExamplePatch')

    patcher.apply('ExamplePatch')
    with open(os.path.join(out_dir, 'example_patch_ov11.bin'), 'wb') as f:
        f.write(
            get_binary_from_rom_ppmdu(
                in_rom, config.binaries['overlay/overlay_0011.bin']))

    assert patcher.is_applied('ExamplePatch')
    in_rom.saveToFile(os.path.join(out_dir, 'patched.nds'))

    # Check if really patched