Exemple #1
0
 def from_block(self, block, offset):
     super(EscalatorOrStairwayDoor, self).from_block(block, offset)
     self.type = block[offset + 2]
     if not DoorType.is_valid(self.type):
         raise InvalidUserDataError("Door had invalid type of %#x" % self.type)
     self.direction = block.read_multi(offset + 3, 2)
     if not StairDirection.is_valid(self.direction):
         raise InvalidUserDataError("Door had invalid escalator/stairs direction of %#x" % self.direction)
Exemple #2
0
 def yml_rep(self):
     out = super(EscalatorOrStairwayDoor, self).yml_rep()
     try:
         out["Type"] = DoorType.tostring(self.type)
     except InvalidArgumentError:
         raise InvalidUserDataError("Door had invalid type of %#x" % self.type)
     try:
         out["Direction"] = StairDirection.tostring(self.direction)
     except InvalidArgumentError:
         raise InvalidUserDataError("Door had invalid escalator/stairs direction of %#x" % self.direction)
     return out
Exemple #3
0
def get_enum_from_user_dict(yml_rep, key, enum_class):
    try:
        value = yml_rep[key]
    except KeyError:
        raise MissingUserDataError("Attribute \"%s\" was not provided" % key)

    if not isinstance(value, str):
        raise InvalidUserDataError("Attribute \"%s\" was not a string" % key)

    try:
        return enum_class.fromstring(value)
    except InvalidArgumentError:
        raise InvalidUserDataError(
            "Attribute \"%s\" had unknown value \"%s\"" % (key, value))
    def read_staff_text_from_project(self, resource_open):
        with resource_open(STAFF_TEXT_FILE_NAME, 'md', True) as f:
            line = f.readline()

            while line:
                line = line.strip()

                if not line:
                    line = f.readline()
                    continue

                text = line[1:].lstrip()
                mark = line[0]
                line = f.readline()

                if mark == '>':
                    self.read_space_from_project(int(text))
                elif mark not in ['#', '-']:
                    self.read_keyword_from_project(mark + text)
                elif len(text) > SCREEN_WIDTH_IN_TILES:
                    raise InvalidUserDataError(
                        'Text \'{}\' is too long - must have at most {} characters'
                        .format(text, SCREEN_WIDTH_IN_TILES))
                elif mark == '#':
                    self.read_small_line_from_project(text)
                else:
                    self.read_big_line_from_project(text)

        self.data.append(CONTROL_END_OF_STAFF)
Exemple #5
0
 def from_block(self, block, offset):
     super(NpcDoor, self).from_block(block, offset)
     self.type = block[offset + 2]
     if not DoorType.is_valid(self.type):
         raise InvalidUserDataError("Door had invalid type of %#x" % self.type)
     destination_offset = block.read_multi(offset + 3, 2) | 0xF0000
     self.text_pointer.from_block(block, destination_offset)
Exemple #6
0
 def yml_rep(self):
     out = super(RopeOrLadderDoor, self).yml_rep()
     try:
         out["Type"] = ClimbableType.tostring(self.climbable_type)
     except InvalidArgumentError:
         raise InvalidUserDataError("Door had invalid climbability setting of %#x" % self.climbable_type)
     return out
Exemple #7
0
 def yml_rep(self):
     out = super(NpcDoor, self).yml_rep()
     try:
         out["Type"] = DoorType.tostring(self.type)
     except InvalidArgumentError:
         raise InvalidUserDataError("Door had invalid type of %#x" % self.type)
     out["Text Pointer"] = self.text_pointer.yml_rep()
     return out
Exemple #8
0
    def from_image(self, image, tileset, palette, no_flip=False):
        if palette.num_subpalettes == 1:
            self._from_image_with_single_subpalette(image, tileset, palette,
                                                    no_flip)
        else:
            # Multiple subpalettes, so we have to figure out which tile should use which subpalette
            palette.from_image(image)
            rgb_image = image.convert("RGB")
            del (image)
            rgb_image_data = rgb_image.load()
            del rgb_image

            tile = [
                array('B', [0] * tileset.tile_width)
                for i in xrange(tileset.tile_height)
            ]

            for arrangement_y in xrange(self.height):
                image_y = arrangement_y * tileset.tile_height
                for arrangement_x in xrange(self.width):
                    image_x = arrangement_x * tileset.tile_width

                    tile_colors = set()
                    for tile_y in xrange(tileset.tile_height):
                        image_tile_y = image_y + tile_y
                        for tile_x in xrange(tileset.tile_width):
                            r, g, b = rgb_image_data[image_x + tile_x,
                                                     image_tile_y]
                            tile_colors.add(
                                EbColor(r=r & 0xf8, g=g & 0xf8, b=b & 0xf8))

                    try:
                        subpalette_id = palette.get_subpalette_for_colors(
                            tile_colors)
                    except InvalidArgumentError as e:
                        raise InvalidUserDataError(
                            "Could not fit all colors in {}x{} square at ({},{}) into a single {}-color subpalette\nColors: {}\nPalette: {}"
                            .format(tileset.tile_width, tileset.tile_height,
                                    image_x,
                                    image_y, palette.subpalette_length,
                                    list(tile_colors), palette.subpalettes))

                    for tile_y in xrange(tileset.tile_height):
                        image_tile_y = image_y + tile_y
                        for tile_x in xrange(tileset.tile_width):
                            image_tile_x = image_x + tile_x
                            tile[tile_y][tile_x] = palette.get_color_id(
                                rgb_image_data[image_tile_x, image_tile_y],
                                subpalette_id)

                    tile_id, vflip, hflip = tileset.add_tile(tile, no_flip)
                    arrangement_item = self.arrangement[arrangement_y][
                        arrangement_x]
                    arrangement_item.tile = tile_id
                    arrangement_item.subpalette = subpalette_id
                    arrangement_item.is_vertically_flipped = vflip
                    arrangement_item.is_horizontally_flipped = hflip
                    arrangement_item.is_priority = False
    def read_keyword_from_project(self, keyword):
        if keyword not in KEYWORD_BYTE_HEIGHT:
            raise InvalidUserDataError(
                'Invalid keyword={} in {}.yml - should be one of {}.'.format(
                    keyword, name, KEYWORD_BYTE_HEIGHT.keys()))

        byte, height = KEYWORD_BYTE_HEIGHT[keyword]
        self.data.append(byte)
        self.height += height
    def read_from_project(self, resource_open):
        with resource_open("Fonts/character_substitutions", "yml") as f:
            data = yml_load(f)

        if data is not None:
            for key, value in data.iteritems():
                if not isinstance(key, basestring):
                    raise InvalidUserDataError(
                        "String to be replaced is not actually a string: " +
                        key)
                if len(key) != 1:
                    raise InvalidUserDataError(
                        "String to be replaced must be a 1 character long: " +
                        key)
                if not isinstance(value, basestring):
                    raise InvalidUserDataError(
                        "String to replace with is not actually a string: " +
                        value)

        CharacterSubstitutions.character_substitutions = data
Exemple #11
0
def get_from_user_dict(yml_rep, key, object_type):
    try:
        value = yml_rep[key]
    except KeyError:
        raise MissingUserDataError("Attribute \"%s\" was not provided" % key)

    if not isinstance(value, object_type):
        raise InvalidUserDataError("Attribute \"%s\" was not of type %s" %
                                   (key, object_type.__name__))

    return value
Exemple #12
0
 def from_block(self, block, offset):
     super(Door, self).from_block(block, offset)
     destination_offset = block.read_multi(offset + 3, 2) | 0xF0000
     self.text_pointer.from_block(block, destination_offset)
     self.flag = block.read_multi(destination_offset + 4, 2)
     self.destination_y = block[destination_offset + 6]
     self.destination_y |= (block[destination_offset + 7] & 0x3f) << 8
     self.destination_direction = (block[destination_offset + 7] & 0xc0) >> 6
     if not DestinationDirection.is_valid(self.destination_direction):
         raise InvalidUserDataError("Door had invalid destination direction of %#x" % self.destination_direction)
     self.destination_x = block.read_multi(destination_offset + 8, 2)
     self.destination_style = block[destination_offset + 10]
Exemple #13
0
    def from_yml_rep(self, yml_rep):
        self.address = None

        if yml_rep is None:
            raise MissingUserDataError("Pointer was not specified")
        elif isinstance(yml_rep, str):
            try:
                if yml_rep[0] == '$':
                    self.address = int(yml_rep[1:], 16)
            except (IndexError, ValueError):
                raise InvalidUserDataError("Pointer \"%s\" was invalid" %
                                           yml_rep)

            if self.address is None:
                try:
                    self.address = EbPointer.label_address_map[yml_rep]
                except KeyError:
                    raise InvalidUserDataError(
                        "Unknown label \"%s\" provided for pointer" % yml_rep)
        else:
            raise InvalidUserDataError("Pointer \"%s\" was invalid" % yml_rep)
Exemple #14
0
 def yml_rep(self):
     out = super(Door, self).yml_rep()
     out["Type"] = DoorType.tostring(DoorType.DOOR)
     out["Text Pointer"] = self.text_pointer.yml_rep()
     out["Event Flag"] = EbEventFlagTableEntry.to_yml_rep(self.flag)
     out["Destination X"] = self.destination_x
     out["Destination Y"] = self.destination_y
     try:
         out["Direction"] = DestinationDirection.tostring(self.destination_direction)
     except InvalidArgumentError:
         raise InvalidUserDataError("Door had invalid destination direction of %#x" % self.destination_direction)
     out["Style"] = self.destination_style
     return out
Exemple #15
0
def door_from_yml_rep(yml_rep):
    try:
        door_type_yml_rep = yml_rep["Type"]
    except KeyError:
        message = "Door was missing \"Type\" attribute"
        raise MissingUserDataError(message)

    try:
        door = DOOR_TYPE_NAME_TO_CLASS_MAP[door_type_yml_rep]()
    except KeyError:
        message = "Door had unknown \"Type\" of \"%s\"" % door_type_yml_rep
        raise InvalidUserDataError(message)

    door.from_yml_rep(yml_rep)
    return door
    def read_staff_chars(self, yml_data):
        log.debug('Reading staff character-to-code mapping')

        for k, v in yml_data.items():
            vrow = v[ENTRY_ROW]
            vcol = v[ENTRY_COL]
            self.check_row_col_error(ENTRY_ROW, vrow, MAX_ROW)
            self.check_row_col_error(ENTRY_COL, vcol, MAX_COL)
            vtile = (vrow << 4) | vcol
            vtype = v[ENTRY_TYPE]
            vchar = v[ENTRY_CHAR]

            if vtype == 'big':
                self.big[str(vchar)] = vtile + 0x40
            elif vtype == 'small':
                self.small[str(vchar)] = vtile + 0x40
            else:
                raise InvalidUserDataError(
                    'Invalid \'{}\' for entry with \'{}\'={}, \'{}\'={} and \'{}\'={}.'
                    .format(ENTRY_TYPE, ENTRY_ROW, vrow, ENTRY_COL, vcol,
                            ENTRY_CHAR, vchar))
 def check_row_col_error(name, val, max_val):
     if val > max_val:
         raise InvalidUserDataError(
             'Invalid \'{}\'={} - should be between 0 and {}.'.format(
                 name, val, max_val))
Exemple #18
0
 def from_block(self, block, offset):
     super(RopeOrLadderDoor, self).from_block(block, offset)
     self.climbable_type = block.read_multi(offset + 3, 2)
     if not ClimbableType.is_valid(self.climbable_type):
         raise InvalidUserDataError("Door had invalid climbability setting of %#x" % self.climbable_type)