Пример #1
0
 def _fix_error(self, dungeons: List[DungeonDefinition], e: DungeonValidatorError):
     mappa = self.module.get_mappa()
     if isinstance(e, DungeonTotalFloorCountInvalidError):
         dungeons[e.dungeon_id].number_floors_in_group = e.expected_floor_count_in_group
     elif isinstance(e, InvalidFloorListReferencedError) or isinstance(e, FloorReusedError):
         dungeons[e.dungeon_id].mappa_index = self.module.mappa_generate_and_insert_new_floor_list()
         dungeons[e.dungeon_id].start_after = u8(0)
         dungeons[e.dungeon_id].number_floors = u8(1)
         dungeons[e.dungeon_id].number_floors_in_group = u8(1)
     elif isinstance(e, InvalidFloorReferencedError):
         valid_floors = len(mappa.floor_lists[e.dungeon.mappa_index]) - e.dungeon.start_after
         if valid_floors > 0:
             dungeons[e.dungeon_id].number_floors = u8_checked(valid_floors)
         else:
             mappa.floor_lists[e.dungeon.mappa_index].append(self.module.mappa_generate_new_floor())
             dungeons[e.dungeon_id].number_floors = u8(1)
     elif isinstance(e, DungeonMissingFloorError):
         # Special case for Regigigas Chamber
         if self._is_regigias_special_case(dungeons, e):
             # Remove additional floors
             mappa.floor_lists[e.dungeon.mappa_index] = [
                 f for i, f in enumerate(mappa.floor_lists[e.dungeon.mappa_index])
                 if i not in e.floors_in_mappa_not_referenced
             ]
         else:
             # Add additional floors
             # TODO: Raise error or warning if we can't fix it? It should really always be consecutive.
             if min(e.floors_in_mappa_not_referenced) == e.dungeon.start_after + e.dungeon.number_floors:
                 if check_consecutive(e.floors_in_mappa_not_referenced):
                     max_floor_id = max(e.floors_in_mappa_not_referenced)
                     dungeons[e.dungeon_id].number_floors = u8_checked(max_floor_id - dungeons[e.dungeon_id].start_after + 1)
Пример #2
0
 def _rebuild_stats(self):
     assert self._level_bin_entry is not None
     store: Gtk.ListStore = self.builder.get_object('stats_store')
     for row in store:
         level, exp, hp, atk, sp_atk, defense, sp_def = (int(x)
                                                         for x in row)
         level_entry = self._level_bin_entry.levels[level - 1]
         level_entry.experience_required = i32(exp)
         level_entry.hp_growth = u16(hp)
         level_entry.attack_growth = u8(atk)
         level_entry.special_attack_growth = u8(sp_atk)
         level_entry.defense_growth = u8(defense)
         level_entry.special_defense_growth = u8(sp_def)
     self.queue_render_graph()
     self._mark_stats_as_modified()
Пример #3
0
 def kind(self) -> Pmd2ScriptObject:
     kind_id = self.emu_thread.emu.memory.unsigned.read_short(self.pnt +
                                                              0x06)
     try:
         return self.rom_data.script_data.objects__by_id[kind_id]
     except KeyError:
         return Pmd2ScriptObject(u16(kind_id), u16(0), u16(0), u8(0),
                                 'UNKNOWN')
Пример #4
0
 def on_btn_add_clicked(self, *args):
     self._list_store.append([len(self._list.list), "NULL", 0, 0, 0, False])
     self._list.list.append(
         Pmd2ScriptObject(id=u16(len(self._list.list)),
                          unk1=u16(0),
                          unk2=u16(0),
                          unk3=u8(0),
                          name="NULL"))
     self.module.mark_objects_as_modified()
Пример #5
0
 def __init__(self, scriptdata: Pmd2ScriptData, object_id: u16, htibox_w: i16, hitbox_h: i16, pos: SsaPosition, script_id: i16, unk12: i16):
     try:
         self.object = scriptdata.objects__by_id[object_id]
     except KeyError:
         logger.warning(f"Unknown object id: {object_id}")
         self.object = Pmd2ScriptObject(object_id, u16(0), u16(0), u8(0), 'UNKNOWN')
     self.hitbox_w = htibox_w
     self.hitbox_h = hitbox_h
     self.pos = pos
     self.script_id = script_id
     self.unk12 = unk12
Пример #6
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(
             u8(read_u16(read.data, pointer + 0) // LEVEL_MULTIPLIER),
             read_u16(read.data, pointer + 2),
             read_u16(read.data, pointer + 4),
             read_u16(read.data, pointer + 6),
         ))
         pointer += 8
     return monsters
Пример #7
0
 def _save_td(self):
     self._dungeon_tilesets.clear()
     for row in self.builder.get_object('dungeon_tileset_store'):
         self._dungeon_tilesets.append(
             GroundTilesetMapping(
                 row[1],
                 row[2],
                 u8(int(row[5])),
                 u32(0),
             ))
     self.module.save_dungeon_tilesets(self._dungeon_tilesets)
Пример #8
0
 def reset_bma(self, bma):
     if isinstance(bma, BmaProtocol):
         self.tiling_width = bma.tiling_width
         self.tiling_height = bma.tiling_height
         self.mappings: List[Sequence[int]] = [bma.layer0,
                                               bma.layer1]  # type: ignore
         self.width_in_chunks = bma.map_width_chunks
         self.height_in_chunks = bma.map_height_chunks
         self.width_in_tiles: Optional[u8] = bma.map_width_camera
         self.height_in_tiles: Optional[u8] = bma.map_height_camera
         self.collision1 = bma.collision
         self.collision2 = bma.collision2
         self.data_layer = bma.unknown_data_block
     else:
         self.tiling_width = u8(3)
         self.tiling_height = u8(3)
         self.mappings = [[], []]
         self.width_in_chunks = u8(1)
         self.height_in_chunks = u8(1)
         self.width_in_tiles = None
         self.height_in_tiles = None
         self.collision1 = None
         self.collision2 = None
         self.data_layer = None
Пример #9
0
    def on_list_store_row_changed(self, store, path, l_iter):
        """Propagate changes to list store entries to the lists."""
        if self._loading:
            return
        a_id, level, location_id, ent_icon, entid, location_name, ent_name = store[
            path][:]
        a_id = int(a_id)
        self._species[a_id] = u16(int(entid))
        self._levels[a_id] = u16(int(level))
        self._locations[a_id] = u8(int(location_id))
        logger.debug(
            f"Updated list entry {a_id}: {entid}, {level}, {location_id}")

        self.module.set_recruitment_list(self._species, self._levels,
                                         self._locations)
Пример #10
0
 def _switch_table(self):
     cb_store: Gtk.ListStore = self.builder.get_object('table_store')
     cb: Gtk.ComboBoxText = self.builder.get_object('cb_table_select')
     if cb.get_active_iter() is not None:
         assert self.font is not None
         v: int = cb_store[cb.get_active_iter()][0]
         self.entries = self.font.get_entries_from_table(u8(v))
         
         entry_tree: Gtk.TreeView = self.builder.get_object('entry_tree')
         store: Gtk.ListStore = entry_tree.get_model()
         store.clear()
         
         for e in self.entries:
             self._add_property_row(store, e)
         surface = self.tables[v].resize((self.tables[v].width*IMAGE_ZOOM, self.tables[v].height*IMAGE_ZOOM))
         self.surface = pil_to_cairo_surface(surface.convert('RGBA'))
         self.builder.get_object('draw').queue_draw()
Пример #11
0
    def on_btn_add_clicked(self, widget):
        dialog: Gtk.Dialog = self.builder.get_object('dialog_choose_char')

        self.builder.get_object('entry_char_id').set_text(str(0))
        self.builder.get_object('entry_char_id').set_increments(1,1)
        self.builder.get_object('entry_char_id').set_range(0, 255)
        
        dialog.set_attached_to(MainController.window())
        dialog.set_transient_for(MainController.window())

        resp = dialog.run()
        dialog.hide()
        if resp == ResponseType.OK:
            cb_store: Gtk.ListStore = self.builder.get_object('table_store')
            cb: Gtk.ComboBoxText = self.builder.get_object('cb_table_select')
            v: int = cb_store[cb.get_active_iter()][0]
            char = int(self.builder.get_object('entry_char_id').get_text())
            try:
                for e in self.entries:
                    if e.get_properties()["char"] == char:
                        raise ValueError(f(_("Character {char} already exists in the table!")))
                assert self.font is not None
                entry = self.font.create_entry_for_table(u8(v))
                entry.set_properties({"char": char})
                self.entries.append(entry)
                
                entry_tree: Gtk.TreeView = self.builder.get_object('entry_tree')
                store: Gtk.ListStore = entry_tree.get_model()
                self._add_property_row(store, entry)
                self.module.mark_font_as_modified(self.spec)
            except Exception as err:
                display_error(
                    sys.exc_info(),
                    str(err),
                    _("Error adding character.")
                )
Пример #12
0
def read_u8(data: ByteReadable, start: int = 0) -> u8:
    """Returns an unsigned 8-bit integer from the bytes-like object at the given position."""
    return u8(data[start])
Пример #13
0
#  You should have received a copy of the GNU General Public License
#  along with SkyTemple.  If not, see <https://www.gnu.org/licenses/>.

from enum import Enum

from range_typed_integers import u8


class FontType(Enum):
    FONT_DAT = 0x00
    FONT_SIR0 = 0x01
    BANNER_FONT = 0x02
    GRAPHIC_FONT = 0x03


FONT_DEFAULT_BPROW = u8(2)
FONT_DEFAULT_CAT = u8(0x02)
FONT_DEFAULT_PADDING = u8(0xFF)

FONT_VALID_TABLES = [0x00, 0x30, 0x81, 0x82, 0x83, 0x84, 0x87, 0xFF]

XML_FONT = "Font"
XML_HEADER = "Header"
XML_HEADER__UNKNOWN = "unknown"
XML_TABLE = "Table"
XML_TABLE__ID = "tableid"
XML_CHAR = "Char"
XML_CHAR__ID = "id"
XML_CHAR__WIDTH = "width"
XML_CHAR__BPROW = "bprow"
XML_CHAR__CAT = "category"