Ejemplo n.º 1
0
 def from_bytes(cls, b: bytes) -> 'DungeonRestriction':
     bitfield0 = read_uintle(b, 0)
     bitfield1 = read_uintle(b, 1)
     dir_bool, enemies_evolve_when_team_member_koed, enemies_grant_exp, recruiting_allowed, \
         level_reset, money_allowed, leader_can_be_changed, dont_save_before_entering = \
         (bool(bitfield0 >> i & 1) for i in range(8))
     iq_skills_disabled, traps_remain_invisible_on_attack, enemies_can_drop_chests = \
         (bool(bitfield1 >> i & 1) for i in range(3))
     assert read_uintle(b, 2) == 0
     assert read_uintle(b, 3) == 0
     return cls(
         DungeonRestrictionDirection(int(dir_bool)),
         enemies_evolve_when_team_member_koed,
         enemies_grant_exp,
         recruiting_allowed,
         level_reset,
         money_allowed,
         leader_can_be_changed,
         dont_save_before_entering,
         iq_skills_disabled,
         traps_remain_invisible_on_attack,
         enemies_can_drop_chests,
         read_sintle(b, 4),
         read_sintle(b, 5),
         read_sintle(b, 6),
         read_sintle(b, 7),
         read_sintle(b, 8, 2),
         read_sintle(b, 10),
         read_sintle(b, 11),
     )
 def get(cls, arm9bin: bytes,
         config: Pmd2Data) -> List[MonsterSpriteDataTableEntry]:
     """Returns the list."""
     block = config.binaries['arm9.bin'].blocks['MonsterSpriteData']
     lst = []
     for i in range(block.begin, block.end, ENTRY_LEN):
         lst.append(
             MonsterSpriteDataTableEntry(read_uintle(arm9bin, i + 0x00, 1),
                                         read_uintle(arm9bin, i + 0x01, 1)))
     return lst
Ejemplo n.º 3
0
 def _write_pair24(self, data: bytes):
     """Writes 4 bytes of 2 16 bit LE integers in pair24 encoding."""
     assert len(data) == 4
     int1 = read_uintle(data, 0, 2)
     int2 = read_uintle(data, 2, 2)
     pair24 = ((int1 & 0xff) << 16) + ((int2 & 0xf) << 12) + (int1 & 0xf00) + ((int2 & 0xff0) >> 4)
     if DEBUG:
         print(f"W {int1:02x} and {int2:02x} as {pair24:06x}")
     self.compressed_data[self.bytes_written:self.bytes_written+3] = pair24.to_bytes(3, 'big')
     self.bytes_written += 3
Ejemplo n.º 4
0
 def get_rank_up_table(cls, arm9bin: bytes, config: Pmd2Data) -> List[Rank]:
     """Returns the list of ranks in the game."""
     block = config.binaries['arm9.bin'].blocks['RankUpTable']
     lst = []
     for i in range(block.begin, block.end, ENTRY_LEN):
         lst.append(
             Rank(read_uintle(arm9bin, i + 0x00, 4),
                  read_uintle(arm9bin, i + 0x04, 4),
                  read_uintle(arm9bin, i + 0x08, 4),
                  read_uintle(arm9bin, i + 0x0C, 4)))
     return lst
Ejemplo n.º 5
0
 def get_monster_spawn_list(cls, overlay29: bytes, config: Pmd2Data) -> List[MonsterSpawn]:
     """
     Returns the list of monsters that can be spawned in fixed floors.
     """
     block = config.binaries['overlay/overlay_0029.bin'].blocks['MonsterSpawnTable']
     lst = []
     for i in range(block.begin, block.end, 4):
         lst.append(MonsterSpawn(
             read_uintle(overlay29, i + 0x00, 2),
             read_uintle(overlay29, i + 0x02, 1),
             read_uintle(overlay29, i + 0x03, 1)
         ))
     return lst
Ejemplo n.º 6
0
 def get_dungeon_list(arm9bin: bytes,
                      config: Pmd2Data) -> List[DungeonDefinition]:
     """Returns the list of dungeon definitions."""
     block = config.binaries['arm9.bin'].blocks['DungeonList']
     lst = []
     for i in range(block.begin, block.end, DUNGEON_LIST_ENTRY_LEN):
         lst.append(
             DungeonDefinition(
                 read_uintle(arm9bin, i),
                 read_uintle(arm9bin, i + 1),
                 read_uintle(arm9bin, i + 2),
                 read_uintle(arm9bin, i + 3),
             ))
     return lst
Ejemplo n.º 7
0
 def get_item_spawn_list(cls, overlay29: bytes, config: Pmd2Data) -> List[ItemSpawn]:
     """
     Returns the list of items that can be spawned in fixed floors.
     """
     block = config.binaries['overlay/overlay_0029.bin'].blocks['ItemSpawnTable']
     lst = []
     for i in range(block.begin, block.end, 8):
         lst.append(ItemSpawn(
             read_uintle(overlay29, i + 0x00, 2),
             read_uintle(overlay29, i + 0x02, 2),
             read_uintle(overlay29, i + 0x04, 2),
             read_uintle(overlay29, i + 0x06, 2),
         ))
     return lst
Ejemplo n.º 8
0
 def list_from_mappa(cls, read: 'MappaBinReadContainer',
                     pointer: int) -> List['MappaMonster']:
     monsters = []
     while not cls._is_end_of_entries(read.data, pointer):
         monsters.append(
             MappaMonster(
                 int(
                     read_uintle(read.data, pointer + 0, 2) /
                     LEVEL_MULTIPLIER),
                 read_uintle(read.data, pointer + 2, 2),
                 read_uintle(read.data, pointer + 4, 2),
                 read_uintle(read.data, pointer + 6, 2),
             ))
         pointer += 8
     return monsters
Ejemplo n.º 9
0
 def get_ground_dungeon_tilesets(
         overlay11bin: bytes,
         config: Pmd2Data) -> List[GroundTilesetMapping]:
     """Returns the list."""
     block = config.binaries['overlay/overlay_0011.bin'].blocks[
         'LevelTilemapList']
     lst = []
     for i in range(block.begin, block.end, 8):
         lst.append(
             GroundTilesetMapping(
                 read_uintle(overlay11bin, i, 2),
                 read_uintle(overlay11bin, i + 2, 1),
                 read_uintle(overlay11bin, i + 3, 1),
                 read_uintle(overlay11bin, i + 4, 4),
             ))
     return lst
Ejemplo n.º 10
0
 def get_entity_spawn_table(cls, overlay29: bytes, config: Pmd2Data) -> List[EntitySpawnEntry]:
     """
     Returns the list of entity spawns. Each entry has three references, one to each of
     the other three tables (item spawn, monster spawn, tile type).
     """
     binary = config.binaries['overlay/overlay_0029.bin']
     block = binary.blocks['EntitySpawnTable']
     lst = []
     for i in range(block.begin, block.end, 12):
         lst.append(EntitySpawnEntry(
             binary,
             read_uintle(overlay29, i + 0x00, 4),
             read_uintle(overlay29, i + 0x04, 4),
             read_uintle(overlay29, i + 0x08, 4),
         ))
     return lst
Ejemplo n.º 11
0
    def _look_ahead_byte_sequence(self, cursor_process_multiplier):
        """Look ahead for the next byte sequence until the first repeating pattern starts"""
        seq = bytearray(NRL_LOOKAHEAD_COPY_BYTES_MAX_BYTES)
        seq_len = 0
        # If the repeat counter reaches NRL_MIN_SEQ_LEN, the sequence ends NRL_MIN_SEQ_LEN entries before that
        repeat_counter = 0
        previous_byt_at_pos = 0x100  # Impossible "null" value for now
        nc = self.cursor
        while True:
            byt_at_pos = read_uintle(self.uncompressed_data, nc)
            if byt_at_pos == previous_byt_at_pos:
                repeat_counter += 1
            else:
                repeat_counter = 0
            previous_byt_at_pos = byt_at_pos

            seq[seq_len] = byt_at_pos

            if repeat_counter > NRL_MIN_SEQ_LEN:
                seq_len -= NRL_MIN_SEQ_LEN
                break

            if seq_len + 1 >= NRL_LOOKAHEAD_COPY_BYTES_MAX_BYTES or nc >= self.length_input:
                break

            seq_len += 1
            nc += cursor_process_multiplier

        return seq_len, seq[:seq_len]
Ejemplo n.º 12
0
 def _get_generic(ov11: bytes, config: Pmd2Data, block_name: str,
                  bytelen: int):
     block = config.binaries['overlay/overlay_0011.bin'].blocks[block_name]
     lst = []
     for i in range(block.begin, block.end, bytelen):
         lst.append(read_uintle(ov11, i, bytelen))
     return lst
Ejemplo n.º 13
0
 def _read(self):
     """Read a single byte and increase cursor"""
     if self.cursor >= self.length_input:
         raise ValueError("BMA Collision RLE Compressor: Reached EOF while reading data.")
     oc = self.cursor
     self.cursor += 1
     return 1 if read_uintle(self.uncompressed_data, oc) > 0 else 0
 def get_player_md_ids(overlay13: bytes, config: Pmd2Data) -> List[int]:
     """Returns the monster.md indices of the player starter choices (total index, with gender form!)"""
     block = config.binaries['overlay/overlay_0013.bin'].blocks[
         'StartersHeroIds']
     ids = []
     for i in range(block.begin, block.end, 2):
         ids.append(read_uintle(overlay13, i, 2))
     return ids
Ejemplo n.º 15
0
 def _read(self, cursor_process_multiplier):
     """Read a single byte and increase cursor"""
     if self.cursor >= self.length_input:
         raise ValueError(
             "Generic NRL Compressor: Reached EOF while reading data.")
     oc = self.cursor
     self.cursor += cursor_process_multiplier
     return read_uintle(self.uncompressed_data, oc)
Ejemplo n.º 16
0
 def get_fixed_floor_overrides(cls, overlay29: bytes, config: Pmd2Data) -> List[int]:
     """
     Returns the list of overrides for fixed floors.
     """
     block = config.binaries['overlay/overlay_0029.bin'].blocks['FixedFloorOverrides']
     lst = []
     for i in range(block.begin, block.end):
         lst.append(read_uintle(overlay29, i, 1))
     return lst
Ejemplo n.º 17
0
 def _look_ahead_repeats(self, data):
     """Look how often the byte in the input data repeats, up to RLE_MAX_LOOKAHEAD_SIZE"""
     nc = self.cursor
     repeats = 0
     while read_uintle(self.uncompressed_data, nc) == data and \
             repeats < RLE_MAX_LOOKAHEAD_SIZE and \
             nc < self.length_input:
         repeats += 1
         nc += 1
     return repeats
Ejemplo n.º 18
0
 def _look_ahead_repeats(self, data, cursor_process_multiplier):
     """Look how often the byte in the input data repeats, up to NRL_LOOKAHEAD_MAX_BYTES"""
     nc = self.cursor
     repeats = 0
     while read_uintle(self.uncompressed_data, nc) == data and \
             repeats < NRL_LOOKAHEAD_ZERO_MAX_BYTES and \
             nc < self.length_input:
         repeats += 1
         nc += cursor_process_multiplier
     return repeats
Ejemplo n.º 19
0
 def get_fixed_floor_properties(cls, overlay10: bytes, config: Pmd2Data) -> List[FixedFloorProperties]:
     """
     Returns the list of properties for fixed floors.
     """
     block = config.binaries['overlay/overlay_0010.bin'].blocks['FixedFloorProperties']
     lst = []
     for i in range(block.begin, block.end, 12):
         lst.append(FixedFloorProperties(
             read_uintle(overlay10, i + 0x00, 4),
             bool(read_uintle(overlay10, i + 0x04, 1)),
             bool(read_uintle(overlay10, i + 0x05, 1)),
             bool(read_uintle(overlay10, i + 0x06, 1)),
             bool(read_uintle(overlay10, i + 0x07, 1)),
             bool(read_uintle(overlay10, i + 0x08, 1)),
             bool(read_uintle(overlay10, i + 0x09, 1)),
             bool(read_uintle(overlay10, i + 0x0A, 1)),
             read_uintle(overlay10, i + 0x0B, 1)
         ))
     return lst
Ejemplo n.º 20
0
    def _process(self):
        len_seq, sequence = self._look_ahead_two_int_sequence()
        if DEBUG:
            cursor_before = self.cursor
            wr_before = self.bytes_written
            print(f"Read a sequence of length {len_seq}")
        if len_seq > NRL_MIN_SEQ_LEN:
            # CMD_COPY_BYTES
            if DEBUG:
                print(f"CMD_COPY_BYTES")
            self.cursor += len_seq * 4
            cmd_byte = CMD_COPY_BYTES + (len_seq - 1)
            self._write_cmd(cmd_byte)
            for b in iter_bytes(sequence, 4):
                self._write_pair24(b)
        else:
            current_int_pair = self._read()
            repeats = self._look_ahead_repeats(current_int_pair)
            if DEBUG:
                print(f"Read {repeats} repeats of {current_int_pair:08x}")
            self.cursor += repeats * 4
            if read_uintle(current_int_pair, 0, 4) == 0:
                if DEBUG:
                    print(f"CMD_ZERO_OUT")
                # CMD_ZERO_OUT
                cmd_byte = repeats
                self._write_cmd(cmd_byte)
            else:
                # CMD_FILL_OUT
                if DEBUG:
                    print(f"CMD_FILL_OUT")
                # To big for one cmd, just make it into two.
                if repeats > NRL_LOOKAHEAD_FILL_MAX_BYTES:
                    repeats_byte1 = repeats - NRL_LOOKAHEAD_FILL_MAX_BYTES
                    cmd_byte1 = CMD_FILL_OUT + (repeats_byte1 - 1)
                    cmd_byte2 = CMD_FILL_OUT + (repeats - repeats_byte1)
                    self._write_cmd(cmd_byte1)
                    self._write_pair24(current_int_pair)
                    self._write_cmd(cmd_byte2)
                    self._write_pair24(current_int_pair)
                else:
                    cmd_byte = CMD_FILL_OUT + repeats
                    self._write_cmd(cmd_byte)
                    self._write_pair24(current_int_pair)

        if DEBUG:
            print(
                f"-- cursor advancement: {self.cursor - cursor_before} -- write advancement: {self.bytes_written - wr_before}"
            )
Ejemplo n.º 21
0
def corrupt341():
    """Corrupt 341: Dungeon tiles Beach cave 2? -- No? Tiles -> Chunk mappings or similar?"""
    img341 = dungeon_bin[341].decompress()
    img341new = bytearray(img341)

    # Decode XOR
    #XOR_ROW_LEN = 7200#18 * 7
    #rows_decoded = []
    #row_before = bytes(XOR_ROW_LEN)
    #for chunk in iter_bytes(img341, XOR_ROW_LEN):
    #    xored = bytearray(a ^ b for (a, b) in zip(chunk, row_before))
    #    row_before = xored
    #    rows_decoded.append(xored)

    dummy_map = [
        TilemapEntry(10, False, False, 0),
        TilemapEntry(10, True, False, 0),
        TilemapEntry(10, False, True, 0),
        TilemapEntry(5, False, False, 0),
        TilemapEntry(5, True, False, 0),
        TilemapEntry(5, False, True, 0),
        TilemapEntry(10, False, False, 6),
        TilemapEntry(10, True, False, 6),
        TilemapEntry(10, False, True, 6)
    ]

    for j in range(1, 300):
        for i, m in enumerate(dummy_map):
            write_uintle(img341new, m.to_int(), (j * 18) + 2 * i, 2)

    all_tilemaps = []
    for bytes2 in iter_bytes(img341new, 2):
        all_tilemaps.append(TilemapEntry.from_int(read_uintle(bytes2, 0, 2)))

    # Encode XOR
    #rows_encoded = []
    #row_before = bytes(XOR_ROW_LEN)
    #for row in rows_decoded:
    #    xored = bytes(a ^ b for (a, b) in zip(row, row_before))
    #    row_before = row
    #    rows_encoded.append(xored)
    #img341new = bytes(itertools.chain.from_iterable(rows_encoded))
    #assert img341 == img341new

    with open('/tmp/corrupt.bin', 'wb') as f:
        f.write(img341new)
    dungeon_bin[341] = FileType.AT4PX.compress(img341new)
Ejemplo n.º 22
0
 def get_monster_spawn_stats_table(cls, overlay10: bytes, config: Pmd2Data) -> List[MonsterSpawnStats]:
     """
     Returns the list of monsters that can be spawned in fixed floors.
     """
     block = config.binaries['overlay/overlay_0010.bin'].blocks['MonsterSpawnStatsTable']
     lst = []
     for i in range(block.begin, block.end, 12):
         lst.append(MonsterSpawnStats(
             read_uintle(overlay10, i + 0x00, 2),
             read_uintle(overlay10, i + 0x02, 2),
             read_uintle(overlay10, i + 0x04, 2),
             read_uintle(overlay10, i + 0x06, 1),
             read_uintle(overlay10, i + 0x07, 1),
             read_uintle(overlay10, i + 0x08, 1),
             read_uintle(overlay10, i + 0x09, 1),
             read_uintle(overlay10, i + 0x0A, 2)
         ))
     return lst
Ejemplo n.º 23
0
    def _wrap_sir0(self, full_binary: bytes, table_data: bytes, entry_len: int,
                   string_offs_per_entry: List[int], write_subheader) -> bytes:
        table_data = bytearray(table_data)
        out_data = bytearray()
        pointer_offsets = []

        # 1. Write strings
        number_entries = 0
        for i in range(0, len(table_data), entry_len):
            for string_off in string_offs_per_entry:
                new_pointer = self._push_string(
                    full_binary, out_data,
                    read_uintle(table_data, i + string_off, 4) -
                    self._binary.loadaddress)
                pointer_offsets.append(i + string_off)
                write_uintle(table_data, new_pointer, i + string_off, 4)
            number_entries += 1
        # Padding
        self._pad(out_data)

        # 2. Correct string pointer offsets
        pointer_offsets = [off + len(out_data) for off in pointer_offsets]

        # 3. Append table
        pointer_data_block = len(out_data)
        out_data += table_data
        # Padding
        self._pad(out_data)

        # 4. Write sub-header
        if write_subheader:
            data_pointer = len(out_data)
            pointer_offsets.append(len(out_data))
            out_data += pointer_data_block.to_bytes(4,
                                                    byteorder='little',
                                                    signed=False)
            out_data += number_entries.to_bytes(4,
                                                byteorder='little',
                                                signed=False)
        else:
            data_pointer = pointer_data_block

        # 5. Convert into SIR0
        return FileType.SIR0.serialize(
            FileType.SIR0.wrap(out_data, pointer_offsets, data_pointer))
Ejemplo n.º 24
0
    def __init__(self, data: bytes, header_start: int):
        if not isinstance(data, memoryview):
            data = memoryview(data)
        self.list: List[Pmd2ScriptEntity] = []

        pointer_start = read_uintle(data, header_start, 4)
        number_entries = read_uintle(data, header_start + 4, 4)
        for i in range(0, number_entries):
            start = pointer_start + (i * LEN_ACTOR_ENTRY)
            self.list.append(
                Pmd2ScriptEntity(id=i,
                                 type=read_uintle(data, start + 0, 2),
                                 entid=read_uintle(data, start + 2, 2),
                                 name=self._read_string(
                                     data, read_uintle(data, start + 4, 4)),
                                 unk3=read_uintle(data, start + 8, 2),
                                 unk4=read_uintle(data, start + 10, 2)))
Ejemplo n.º 25
0
def main():
    os.makedirs(output_dir, exist_ok=True)

    rom = NintendoDSRom.fromFile(os.path.join(base_dir,
                                              'skyworkcopy_edit.nds'))

    bin_before = rom.getFileByName('SCRIPT/G01P01A/enter.sse')
    ssa_before = SsaHandler.deserialize(bin_before)
    data = Pmd2XmlReader.load_default()
    scriptdata = data.script_data

    ssa_before.layer_list[0].objects = [
        # TODO: 5=Width, 1=Height!
        SsaObject(
            scriptdata, 6, 5, 1,
            SsaPosition(scriptdata, 44, 24, 0, 0,
                        scriptdata.directions__by_name['Down'].id), 10, -1)
    ]

    # Write NPC types
    npc_table_start = data.binaries['arm9.bin'].blocks['Entities'].begin
    NPC_TABLE_ENTRY_LEN = 0x0c
    # uint16: type, uint16: entid, uint32: pointer to name, unk3, unk4

    # Shaymin NPC_SHEIMI 534 / V02P06A
    ent_id__shaymin = scriptdata.level_entities__by_name['NPC_SHEIMI'].id
    print(
        read_uintle(
            rom.arm9,
            npc_table_start + ent_id__shaymin * NPC_TABLE_ENTRY_LEN + 0x02, 2))
    write_uintle(
        rom.arm9, 534,
        npc_table_start + ent_id__shaymin * NPC_TABLE_ENTRY_LEN + 0x02, 2)
    # Elekid NPC_SHEIMI1 266 / V02P07A
    ent_id__elekid = scriptdata.level_entities__by_name['NPC_SHEIMI1'].id
    print(
        read_uintle(
            rom.arm9,
            npc_table_start + ent_id__elekid * NPC_TABLE_ENTRY_LEN + 0x02, 2))
    write_uintle(rom.arm9, 266,
                 npc_table_start + ent_id__elekid * NPC_TABLE_ENTRY_LEN + 0x02,
                 2)
    # Piplup NPC_SHEIMI2 428 / V03P01A
    ent_id__piplup = scriptdata.level_entities__by_name['NPC_SHEIMI2'].id
    print(
        read_uintle(
            rom.arm9,
            npc_table_start + ent_id__piplup * NPC_TABLE_ENTRY_LEN + 0x02, 2))
    write_uintle(rom.arm9, 428,
                 npc_table_start + ent_id__piplup * NPC_TABLE_ENTRY_LEN + 0x02,
                 2)
    # Meowth NPC_SHEIMI3 52 / V03P02A
    ent_id__meowth = scriptdata.level_entities__by_name['NPC_SHEIMI3'].id
    print(
        read_uintle(
            rom.arm9,
            npc_table_start + ent_id__meowth * NPC_TABLE_ENTRY_LEN + 0x02, 2))
    write_uintle(rom.arm9, 52,
                 npc_table_start + ent_id__meowth * NPC_TABLE_ENTRY_LEN + 0x02,
                 2)
    # Buneary NPC_SHEIMI4 469 / V03P03A
    ent_id__buneary = scriptdata.level_entities__by_name['NPC_SHEIMI4'].id
    print(
        read_uintle(
            rom.arm9,
            npc_table_start + ent_id__buneary * NPC_TABLE_ENTRY_LEN + 0x02, 2))
    write_uintle(
        rom.arm9, 469,
        npc_table_start + ent_id__buneary * NPC_TABLE_ENTRY_LEN + 0x02, 2)

    ssa_before.layer_list[0].actors = [
        SsaActor(
            scriptdata, ent_id__shaymin,
            SsaPosition(scriptdata, 14, 24, 2, 0,
                        scriptdata.directions__by_name['Down'].id), 5, -1),
        SsaActor(
            scriptdata, ent_id__elekid,
            SsaPosition(scriptdata, 20, 24, 2, 0,
                        scriptdata.directions__by_name['Down'].id), 6, -1),
        SsaActor(
            scriptdata, ent_id__piplup,
            SsaPosition(scriptdata, 26, 24, 2, 0,
                        scriptdata.directions__by_name['Down'].id), 7, -1),
        SsaActor(
            scriptdata, ent_id__meowth,
            SsaPosition(scriptdata, 32, 24, 2, 0,
                        scriptdata.directions__by_name['Down'].id), 8, -1),
        SsaActor(
            scriptdata, ent_id__buneary,
            SsaPosition(scriptdata, 38, 24, 2, 0,
                        scriptdata.directions__by_name['Down'].id), 9, -1),
        # Mimikyu NPC_PUKURIN 40 / V03P04A
        # Litten NPC_ZUBATTO 41 / V04P02A
        # Zorua NPC_DIGUDA 50  / V03P13A
    ]
    ssa_before.layer_list[0].events = [
        SsaEvent(6, 2, 1, 0, SsaPosition(scriptdata, 27, 0, 0, 0, None),
                 65535),
        SsaEvent(6, 2, 2, 0, SsaPosition(scriptdata, 27, 49, 0, 0, None),
                 65535),
    ]

    # Exit Guild
    ssa_before.layer_list[1].actors = [
        SsaActor(
            scriptdata, 0,
            SsaPosition(scriptdata, 29, 7, 2, 0,
                        scriptdata.directions__by_name['Down'].id), -1, -1),
        SsaActor(
            scriptdata, 10,
            SsaPosition(scriptdata, 29, 4, 2, 0,
                        scriptdata.directions__by_name['Down'].id), -1, -1)
    ]

    # Exit Town
    ssa_before.layer_list[2].actors = [
        SsaActor(
            scriptdata, 0,
            SsaPosition(scriptdata, 29, 44, 2, 0,
                        scriptdata.directions__by_name['Up'].id), -1, -1),
        SsaActor(
            scriptdata, 10,
            SsaPosition(scriptdata, 29, 47, 2, 0,
                        scriptdata.directions__by_name['Up'].id), -1, -1)
    ]

    # Create scripts, if don't exist
    tpl_ssb = rom.getFileByName('SCRIPT/G01P01A/enter01.ssb')
    try:
        rom.getFileByName('SCRIPT/G01P01A/enter05.ssb')
    except ValueError:
        create_file_in_rom(rom, 'SCRIPT/G01P01A/enter05.ssb', tpl_ssb)
    try:
        rom.getFileByName('SCRIPT/G01P01A/enter06.ssb')
    except ValueError:
        create_file_in_rom(rom, 'SCRIPT/G01P01A/enter06.ssb', tpl_ssb)
    try:
        rom.getFileByName('SCRIPT/G01P01A/enter07.ssb')
    except ValueError:
        create_file_in_rom(rom, 'SCRIPT/G01P01A/enter07.ssb', tpl_ssb)
    try:
        rom.getFileByName('SCRIPT/G01P01A/enter08.ssb')
    except ValueError:
        create_file_in_rom(rom, 'SCRIPT/G01P01A/enter08.ssb', tpl_ssb)
    try:
        rom.getFileByName('SCRIPT/G01P01A/enter09.ssb')
    except ValueError:
        create_file_in_rom(rom, 'SCRIPT/G01P01A/enter09.ssb', tpl_ssb)
    try:
        rom.getFileByName('SCRIPT/G01P01A/enter10.ssb')
    except ValueError:
        create_file_in_rom(rom, 'SCRIPT/G01P01A/enter10.ssb', tpl_ssb)

    bin_after = SsaHandler.serialize(ssa_before)
    rom.setFileByName('SCRIPT/G01P01A/enter.sse', bin_after)
    rom.saveToFile(os.path.join(base_dir, 'skyworkcopy_edit.nds'))

    draw_maps_main()
Ejemplo n.º 26
0
 def from_mappa(cls, read: 'MappaBinReadContainer', pointer: int) -> 'MappaTrapList':
     weights = []
     for i in range(pointer, pointer + 50, 2):
         weights.append(read_uintle(read.data, i, 2))
     return MappaTrapList(weights)
Ejemplo n.º 27
0
 def _is_end_of_entries(cls, data: memoryview, pointer):
     return read_uintle(data, pointer + 6, 2) == 0
Ejemplo n.º 28
0
 def __init__(self, data: bytes):
     if not isinstance(data, memoryview):
         data = memoryview(data)
     self.mappings = []
     for pos in range(0, len(data), 2):
         self.mappings.append(read_uintle(data, pos, 2))
Ejemplo n.º 29
0
 def from_mappa(cls, read: 'MappaBinReadContainer', pointer: int):
     terrain_settings_bitflag = read_uintle(read.data, pointer + 0x0D)
     terrain_settings = MappaFloorTerrainSettings(
         *(bool(terrain_settings_bitflag >> i & 1) for i in range(8)))
     return cls(
         structure=MappaFloorStructureType(
             read_uintle(read.data, pointer + 0x00)),
         room_density=read_uintle(read.data, pointer + 0x01),
         tileset_id=read_uintle(read.data, pointer + 0x02),
         music_id=read_uintle(read.data, pointer + 0x03),
         weather=MappaFloorWeather(read_uintle(read.data, pointer + 0x04)),
         floor_connectivity=read_uintle(read.data, pointer + 0x05),
         initial_enemy_density=read_uintle(read.data, pointer + 0x06),
         kecleon_shop_chance=read_uintle(read.data, pointer + 0x07),
         monster_house_chance=read_uintle(read.data, pointer + 0x08),
         unusued_chance=read_uintle(read.data, pointer + 0x09),
         sticky_item_chance=read_uintle(read.data, pointer + 0x0A),
         dead_ends=bool(read_uintle(read.data, pointer + 0x0B)),
         secondary_terrain=MappaFloorSecondaryTerrainType(
             read_uintle(read.data, pointer + 0x0C)),
         terrain_settings=terrain_settings,
         unk_e=bool(read_uintle(read.data, pointer + 0x0E)),
         item_density=read_uintle(read.data, pointer + 0x0F),
         trap_density=read_uintle(read.data, pointer + 0x10),
         floor_number=read_uintle(read.data, pointer + 0x11),
         fixed_floor_id=read_uintle(read.data, pointer + 0x12),
         extra_hallway_density=read_uintle(read.data, pointer + 0x13),
         buried_item_density=read_uintle(read.data, pointer + 0x14),
         water_density=read_uintle(read.data, pointer + 0x15),
         darkness_level=MappaFloorDarknessLevel(
             read_uintle(read.data, pointer + 0x16)),
         max_coin_amount=read_uintle(read.data, pointer + 0x17) * 5,
         kecleon_shop_item_positions=read_uintle(read.data, pointer + 0x18),
         empty_monster_house_chance=read_uintle(read.data, pointer + 0x19),
         unk_hidden_stairs=read_uintle(read.data, pointer + 0x1A),
         hidden_stairs_spawn_chance=read_uintle(read.data, pointer + 0x1B),
         enemy_iq=read_uintle(read.data, pointer + 0x1C, 2),
         iq_booster_allowed=bool(read_uintle(read.data, pointer + 0x1E)))
Ejemplo n.º 30
0
def validate_mappa_sir0(data: bytes, header_start: int,
                        content_pointer_offsets: List[int]):
    """
    Reads through the mappa file, collects all known possible pointers and checks if all of them are in the
    pointer list, and no more.
    """
    # The 5 header pointer
    count_pointers = 5
    dungeon_list_index_start = read_uintle(data, header_start + 0x00, 4)
    assert header_start + 0x00 in content_pointer_offsets
    floor_layout_data_start = read_uintle(data, header_start + 0x04, 4)
    assert header_start + 0x04 in content_pointer_offsets
    item_spawn_list_index_start = read_uintle(data, header_start + 0x08, 4)
    assert header_start + 0x08 in content_pointer_offsets
    monster_spawn_list_index_start = read_uintle(data, header_start + 0x0C, 4)
    assert header_start + 0x0C in content_pointer_offsets
    trap_spawn_list_index_start = read_uintle(data, header_start + 0x10, 4)
    assert header_start + 0x10 in content_pointer_offsets
    # Read floor list list
    start = dungeon_list_index_start
    end = floor_layout_data_start
    dungeons = []
    for i in range(start, end, 4):
        pnt_floor_index_entry = read_uintle(data, i, 4)
        assert i in content_pointer_offsets
        count_pointers += 1
        # Read floor list
        assert not any(
            x in content_pointer_offsets
            for x in range(pnt_floor_index_entry, pnt_floor_index_entry + 18))
        floor_data_pos = floor_layout_data_start + 32 * read_uintle(
            data, pnt_floor_index_entry + 0x00, 2)
        assert floor_data_pos not in content_pointer_offsets
        pokemon_spawn_pnt = monster_spawn_list_index_start + 4 * read_uintle(
            data, pnt_floor_index_entry + 0x02, 2)
        assert pokemon_spawn_pnt in content_pointer_offsets
        trap_spawn_pnt = trap_spawn_list_index_start + 4 * read_uintle(
            data, pnt_floor_index_entry + 0x04, 2)
        assert trap_spawn_pnt in content_pointer_offsets
        item_spawn_pnt = item_spawn_list_index_start + 4 * read_uintle(
            data, pnt_floor_index_entry + 0x06, 2)
        assert item_spawn_pnt in content_pointer_offsets
        item_shop_spawn_pnt = item_spawn_list_index_start + 4 * read_uintle(
            data, pnt_floor_index_entry + 0x08, 2)
        assert item_shop_spawn_pnt in content_pointer_offsets
        item_mhouse_spawn_pnt = item_spawn_list_index_start + 4 * read_uintle(
            data, pnt_floor_index_entry + 0x0A, 2)
        assert item_mhouse_spawn_pnt in content_pointer_offsets
        item_buried_spawn_pnt = item_spawn_list_index_start + 4 * read_uintle(
            data, pnt_floor_index_entry + 0x0C, 2)
        assert item_buried_spawn_pnt in content_pointer_offsets
        item_unk1_spawn_pnt = item_spawn_list_index_start + 4 * read_uintle(
            data, pnt_floor_index_entry + 0x0E, 2)
        assert item_unk1_spawn_pnt in content_pointer_offsets
        item_unk2_spawn_pnt = item_spawn_list_index_start + 4 * read_uintle(
            data, pnt_floor_index_entry + 0x10, 2)
        assert item_unk2_spawn_pnt in content_pointer_offsets
    return dungeons