Beispiel #1
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('levels', type=int,
                        metavar=('PC1_Level', 'PC2_Level', 'PC3_Level', 'PC4_Level'),
                        nargs=4, help='Party levels')
    parser.add_argument('projDir', metavar='ProjectDirectory', nargs=1,
                        help='CoilSnake project directory')
    parser.add_argument('--enemy', action='store', nargs=1,
                        metavar='Enemy_ID', type=int,
                        dest="enemyInfo", help="Enemy number")
    args = parser.parse_args()

    proj = Project.Project()
    proj.load(args.projDir[0] + os.sep + Project.PROJECT_FILENAME)

    partyStats = [None, None, None, None]
    with proj.get_resource("eb", "stats_growth_vars", "yml", "r") as f:
        growthVars = yml_load(f)
        for i in range(4):
            partyStats[i] = calcStats(growthVars[i], args.levels[i])
    
    print "*** Party Stats ***"
    print '\t'.join(map(str, ['', 'HP', 'PP', 'Off', 'Def', 'Speed', 'Guts', 'Vit', 'IQ', "Luck"]))
    for i in range(4):
        print i, '\t', '\t'.join(map(str, partyStats[i]))
            
    if args.enemyInfo is not None:
        with proj.get_resource("eb", "enemy_configuration_table", "yml", "r") as f:
            enemyData = (yml_load(f))[args.enemyInfo[0]]
            print "\n*** Enemy Stats:", enemyData["Name"], "***"
            print '\t'.join(map(str, ['', 'HP', 'PP', 'Off', 'Def', 'Speed', 'Guts', "Luck"]))
            print '\t%d\t%d\t%d\t%d\t%d\t%d\t%d' % (enemyData["HP"], enemyData["PP"],
                                                    enemyData["Offense"], enemyData["Defense"],
                                                    enemyData["Speed"], enemyData["Guts"], enemyData["Luck"])
            print "\n*** Damage Dealt by Enemy to Party ***"
            print "Level\tTarget\tMinDmg\tMaxDmg\tSMASH\tSmash%"
            for i in range(1, 5):
                for j in range(0, 4):
                    damage = i * enemyData["Offense"] - partyStats[j][3]
                    smashDamage = 4 * enemyData["Offense"] - partyStats[j][3]
                    smashOdds = enemyData["Guts"] / 5.0
                    print "%d\t%d\t%d\t%d\t%d\t%.2f%%" % (i, j, damage*0.75, damage*1.25, smashDamage, smashOdds)
                print
            
            print "*** Damage Dealt by Party to Enemy ***"
            print "PC\tMinDmg\tMaxDmg\tSMASH\tSmash%"
            for i in range(0, 4):
                damage = 2 * partyStats[i][2] - enemyData["Defense"]
                smashDamage = 4 * partyStats[i][2] - enemyData["Defense"]
                smashOdds = max(partyStats[i][5] / 5.0, 5.0)
                print "%d\t%d\t%d\t%d\t%d" % (i, damage * 0.75, damage * 1.25, smashDamage, smashOdds)
Beispiel #2
0
    def upgrade_project(self, old_version, new_version, rom, resource_open_r,
                        resource_open_w, resource_delete):
        if old_version == 1:
            self.read_from_rom(rom)
            self.write_to_project(resource_open_w)
        elif old_version < new_version:
            self.read_from_project(resource_open_r)

            # Remove all patches that should not exist
            if rom.type in REMOVED_PATCHES:
                for patch_name in REMOVED_PATCHES[rom.type]:
                    if patch_name in self.patches:
                        del self.patches[patch_name]

            # Add in all the new patches
            for ip_desc_filename in [
                    s for s in os.listdir(get_ips_directory(rom.type))
                    if s.lower().endswith(".yml")
            ]:
                with open(
                        os.path.join(get_ips_directory(rom.type),
                                     ip_desc_filename)) as ips_desc_file:
                    ips_desc = yml_load(ips_desc_file)
                    ips_desc_title = ips_desc["Title"]
                    ips_is_hidden = ("Hidden"
                                     in ips_desc) and ips_desc["Hidden"]

                    if (not ips_is_hidden) and (ips_desc_title
                                                not in self.patches):
                        self.patches[ips_desc_title] = "disabled"

            self.write_to_project(resource_open_w)
Beispiel #3
0
    def upgrade_project(self, old_version, new_version, rom, resource_open_r, resource_open_w, resource_delete):
        if old_version == new_version:
            return
        elif old_version < 5:
            with resource_open_r("map_changes", "yml") as f:
                data = yml_load(f)

            for i in data:
                if data[i] is None:
                    data[i] = []
                else:
                    for entry in data[i]:
                        entry["Tile Changes"] = entry["Changes"]
                        del entry["Changes"]

                        for j, change in enumerate(entry["Tile Changes"]):
                            entry["Tile Changes"][j] = MapEventSubTableEntry.to_yml_rep(change)

            with resource_open_w("map_changes", "yml") as f:
                yml_dump(data, f)

            convert_values_to_hex_repr_in_yml_file("map_changes", resource_open_r, resource_open_w, ["Event Flag"],
                                                   default_flow_style=None)

            self.upgrade_project(5, new_version, rom, resource_open_r, resource_open_w, resource_delete)
        else:
            self.upgrade_project(old_version + 1, new_version, rom, resource_open_r, resource_open_w, resource_delete)
Beispiel #4
0
    def load(self, f, romtype=None):
        if isinstance(f, str):
            self._dir_name = os.path.dirname(f)
        else:
            self._dir_name = os.path.dirname(f.name)

        try:
            if isinstance(f, str):
                f = open(f, 'r')
            data = yml_load(f)
            if (romtype is None) or (romtype == data["romtype"]):
                self.romtype = data["romtype"]
                self._resources = data["resources"]
                if "version" in data:
                    self.version = data["version"]
                else:
                    self.version = 1

                if self._resources is None:
                    self._resources = {}
            else:  # Loading a project of the wrong romtype
                self.romtype = romtype
                self._resources = {}
        except IOError:
            # Project file doesn't exist
            if not os.path.exists(self._dir_name):
                os.makedirs(self._dir_name)
            if romtype is None:
                self.romtype = "Unknown"
            else:
                self.romtype = romtype
            self._resources = {}
Beispiel #5
0
 def read_from_project(self, resource_open):
     for table in self.tables.itervalues():
         with resource_open(table.name.lower(), "yml") as f:
             yml_rep = yml_load(f)
             num_rows = len(yml_rep)
             table.recreate(num_rows=num_rows)
             table.from_yml_rep(yml_rep)
Beispiel #6
0
    def read_from_project(self, resource_open):
        with resource_open("sprite_group_palettes", "yml") as f:
            self.palette_table.from_yml_file(f)

        with resource_open("sprite_groups", "yml") as f:
            input = yml_load(f)
            num_groups = len(input)
            self.groups = []
            for i in range(num_groups):
                group = SpriteGroup(16)
                group.from_yml_rep(input[i])

                palette = EbPalette(1, 16)

                with resource_open("SpriteGroups/" + str(i).zfill(3),
                                   "png") as f2:
                    image = open_indexed_image(f2)
                    group.from_image(image)
                    palette.from_image(image)
                    del image

                self.groups.append(group)

                # Assign the palette number to the sprite
                for j in range(8):
                    if palette.list()[3:] == self.palette_table[j][0].list(
                    )[3:]:
                        group.palette = j
                        break
                else:
                    raise CoilSnakeError("Sprite Group #" + str(i).zfill(3) +
                                         " uses an invalid palette")
Beispiel #7
0
    def upgrade_project(self, old_version, new_version, rom, resource_open_r, resource_open_w, resource_delete):
        if old_version == new_version:
            return
        elif old_version <= 2:
            replace_field_in_yml(resource_name="map_sectors",
                                 resource_open_r=resource_open_r,
                                 resource_open_w=resource_open_w,
                                 key="Town Map",
                                 value_map={"scummers": "summers"})

            self.read_from_rom(rom)

            with resource_open_r("map_sectors", 'yml') as f:
                data = yml_load(f)
                for i in data:
                    data[i]["Town Map Image"] = TOWNMAP_IMAGE_ENTRY.to_yml_rep(self.sector_town_map_table[i][0] & 0xf)
                    data[i]["Town Map Arrow"] = TOWNMAP_ARROW_ENTRY.to_yml_rep(self.sector_town_map_table[i][0] >> 4)
                    data[i]["Town Map X"] = TOWNMAP_X.to_yml_rep(self.sector_town_map_table[i][1])
                    data[i]["Town Map Y"] = TOWNMAP_Y.to_yml_rep(self.sector_town_map_table[i][2])
            with resource_open_w("map_sectors", 'yml') as f:
                yaml.dump(data, f, Dumper=yaml.CSafeDumper, default_flow_style=False)

            self.upgrade_project(3, new_version, rom, resource_open_r, resource_open_w, resource_delete)
        else:
            self.upgrade_project(old_version + 1, new_version, rom, resource_open_r, resource_open_w, resource_delete)
Beispiel #8
0
    def load(self, f, romtype=None):
        if isinstance(f, str):
            self._dir_name = os.path.dirname(f)
        else:
            self._dir_name = os.path.dirname(f.name)

        try:
            if isinstance(f, str):
                f = open(f, 'r')
            data = yml_load(f)
            if (romtype is None) or (romtype == data["romtype"]):
                self.romtype = data["romtype"]
                self._resources = data["resources"]
                if "version" in data:
                    self.version = data["version"]
                else:
                    self.version = 1

                if self._resources is None:
                    self._resources = {}
            else:  # Loading a project of the wrong romtype
                self.romtype = romtype
                self._resources = {}
        except IOError:
            # Project file doesn't exist
            if not os.path.exists(self._dir_name):
                os.makedirs(self._dir_name)
            if romtype is None:
                self.romtype = "Unknown"
            else:
                self.romtype = romtype
            self._resources = {}
Beispiel #9
0
    def write_to_rom(self, rom):
        for ips_desc_filename in [s for s in os.listdir(get_ips_directory(rom.type)) if s.lower().endswith(".yml")]:
            patch_name = ips_desc_filename[:-4]
            with open(os.path.join(get_ips_directory(rom.type), ips_desc_filename)) as ips_desc_file:
                ips_desc = yml_load(ips_desc_file)
                if "Hidden" in ips_desc and ips_desc["Hidden"]:
                    continue
                elif (ips_desc["Title"] in self.patches) and (self.patches[ips_desc["Title"]].lower() == "enabled"):
                    # First, check that we can apply this
                    ranges = map(lambda y: tuple(map(lambda z: int(z, 0), y[1:-1].split(','))), ips_desc["Ranges"])
                    for range in ranges:
                        if not rom.is_unallocated(range):
                            raise CoilSnakeError(
                                "Can't apply patch \"{}\" because range ({:#x},{:#x}) is not unallocated".format(
                                    ips_desc["Title"], range[0], range[1]))

                    # Now apply the patch
                    ips = IpsPatch()
                    offset = 0
                    if "Header" in ips_desc:
                        offset = ips_desc["Header"]
                    ips.load(get_ips_filename(rom.type, patch_name), offset)
                    ips.apply(rom)

                    # Mark the used ranges as used
                    for range in ranges:
                        rom.mark_allocated(range)
    def upgrade_project(self, old_version, new_version, rom, resource_open_r,
                        resource_open_w, resource_delete):
        if old_version == new_version:
            return
        elif old_version < 5:
            with resource_open_r("map_changes", "yml", True) as f:
                data = yml_load(f)

            for i in data:
                if data[i] is None:
                    data[i] = []
                else:
                    for entry in data[i]:
                        entry["Tile Changes"] = entry["Changes"]
                        del entry["Changes"]

                        for j, change in enumerate(entry["Tile Changes"]):
                            entry["Tile Changes"][
                                j] = MapEventSubTableEntry.to_yml_rep(change)

            with resource_open_w("map_changes", "yml", True) as f:
                yml_dump(data, f)

            convert_values_to_hex_repr_in_yml_file("map_changes",
                                                   resource_open_r,
                                                   resource_open_w,
                                                   ["Event Flag"],
                                                   default_flow_style=None)

            self.upgrade_project(5, new_version, rom, resource_open_r,
                                 resource_open_w, resource_delete)
        else:
            self.upgrade_project(old_version + 1, new_version, rom,
                                 resource_open_r, resource_open_w,
                                 resource_delete)
Beispiel #11
0
    def write_to_rom(self, rom):
        for ips_desc_filename in [s for s in os.listdir(get_ips_directory(rom.type)) if s.lower().endswith(".yml")]:
            patch_name = ips_desc_filename[:-4]
            with open(os.path.join(get_ips_directory(rom.type), ips_desc_filename)) as ips_desc_file:
                ips_desc = yml_load(ips_desc_file)
                if (ips_desc["Title"] in self.patches) and (self.patches[ips_desc["Title"]].lower() == "enabled"):
                    # First, check that we can apply this
                    ranges = map(lambda y: tuple(map(lambda z: int(z, 0), y[1:-1].split(','))), ips_desc["Ranges"])
                    for range in ranges:
                        if not rom.is_unallocated(range):
                            raise CoilSnakeError(
                                "Can't apply patch \"{}\" because range ({:#x},{:#x}) is not unallocated".format(
                                    ips_desc["Title"], range[0], range[1]))

                    # Now apply the patch
                    ips = IpsPatch()
                    offset = 0
                    if "Header" in ips_desc:
                        offset = ips_desc["Header"]
                    ips.load(get_ips_filename(rom.type, patch_name), offset)
                    ips.apply(rom)

                    # Mark the used ranges as used
                    for range in ranges:
                        rom.mark_allocated(range)
Beispiel #12
0
    def upgrade_project(self, old_version, new_version, rom, resource_open_r,
                        resource_open_w, resource_delete):
        if old_version == new_version:
            return
        elif old_version == 4:
            with resource_open_r("TownMaps/icon_positions", "yml", True) as f:
                data = yml_load(f)

                for i in range(6):
                    old_key = TownMapEnum.tostring(i).lower()
                    data[i] = data[old_key]
                    del data[old_key]
            with resource_open_w("TownMaps/icon_positions", "yml", True) as f:
                yml_dump(data, f, default_flow_style=False)

            convert_values_to_hex_repr_in_yml_file("TownMaps/icon_positions",
                                                   resource_open_r,
                                                   resource_open_w,
                                                   ["Event Flag"])

            self.upgrade_project(5, new_version, rom, resource_open_r,
                                 resource_open_w, resource_delete)
        elif old_version <= 2:
            self.read_from_rom(rom)
            self.write_to_project(resource_open_w)
            self.upgrade_project(new_version, new_version, rom,
                                 resource_open_r, resource_open_w,
                                 resource_delete)
        else:
            self.upgrade_project(old_version + 1, new_version, rom,
                                 resource_open_r, resource_open_w,
                                 resource_delete)
    def read_from_project(self, resource_open):
        with resource_open("sprite_group_palettes", "yml", True) as f:
            self.palette_table.from_yml_file(f)

        with resource_open("sprite_groups", "yml", True) as f:
            input = yml_load(f)
            num_groups = len(input)
            self.groups = []
            for i in range(num_groups):
                group = SpriteGroup(16)
                group.from_yml_rep(input[i])

                palette = EbPalette(1, 16)

                with resource_open("SpriteGroups/" + str(i).zfill(3), "png") as f2:
                    image = open_indexed_image(f2)
                    group.from_image(image)
                    palette.from_image(image)
                    del image

                self.groups.append(group)

                # Assign the palette number to the sprite
                for j in range(8):
                    if palette.list() == self.palette_table[j][0].list():
                        group.palette = j
                        break
                else:
                    raise CoilSnakeError("Sprite Group #" + str(i).zfill(3) + " uses an invalid palette")
 def upgrade_project(self, old_version, new_version, rom, resource_open_r, resource_open_w, resource_delete):
     if old_version == new_version:
         return
     elif old_version == 4:
         with resource_open_r("sprite_groups", "yml", True) as f:
             data = yml_load(f)
             for i in data:
                 entry = data[i]
                 collision_settings = entry["Collision Settings"]
                 entry["North/South Collision Width"] = collision_settings[0]
                 entry["North/South Collision Height"] = collision_settings[1]
                 entry["East/West Collision Width"] = collision_settings[2]
                 entry["East/West Collision Height"] = collision_settings[3]
                 del entry["Collision Settings"]
         with resource_open_w("sprite_groups", "yml", True) as f:
             yml_dump(data, f)
         self.upgrade_project(old_version + 1, new_version, rom, resource_open_r, resource_open_w, resource_delete)
     elif old_version == 2:
         replace_field_in_yml(resource_name="sprite_groups",
                              resource_open_r=resource_open_r,
                              resource_open_w=resource_open_w,
                              key="Unknown A",
                              new_key="Size",
                              value_map=dict(enumerate(SPRITE_SIZES)))
         replace_field_in_yml(resource_name="sprite_groups",
                              resource_open_r=resource_open_r,
                              resource_open_w=resource_open_w,
                              key="Unknown B",
                              new_key="Collision Settings")
         self.upgrade_project(old_version + 1, new_version, rom, resource_open_r, resource_open_w, resource_delete)
     else:
         self.upgrade_project(old_version + 1, new_version, rom, resource_open_r, resource_open_w, resource_delete)
Beispiel #15
0
    def from_files(self, image_file, widths_file, image_format="png", widths_format="yml"):
        image = open_indexed_image(image_file)
        self.tileset.from_image(image, _FONT_IMAGE_ARRANGEMENT, _FONT_IMAGE_PALETTE)
        del image

        if widths_format == "yml":
            widths_dict = yml_load(widths_file)
            self.character_widths = map(lambda i: widths_dict[i], range(self.tileset.num_tiles_maximum))
 def read_from_project(self, resource_open):
     with resource_open(DEATH_SCREEN_PATH, "png") as f:
         image = open_indexed_image(f)
         self.arrangement.from_image(image, self.tileset, self.palette)
     with resource_open(DEATH_SCREEN_SUBPALETTES_PATH, "yml", True) as f:
         subpalettes = yml_load(f)
         for subpalette, tiles in subpalettes.items():
             for x, y in tiles:
                 self.arrangement[x, y].subpalette = subpalette
 def read_from_project(self, resource_open):
     with resource_open(DEATH_SCREEN_PATH, "png") as f:
         image = open_indexed_image(f)
         self.arrangement.from_image(image, self.tileset, self.palette)
     with resource_open(DEATH_SCREEN_SUBPALETTES_PATH, "yml") as f:
         subpalettes = yml_load(f)
         for subpalette, tiles in subpalettes.items():
             for x, y in tiles:
                 self.arrangement[x, y].subpalette = subpalette
Beispiel #18
0
    def from_files(self, image_file, widths_file, image_format="png", widths_format="yml"):
        image = open_indexed_image(image_file)

        if self.num_characters == 96:
            self.tileset.from_image(image, _FONT_IMAGE_ARRANGEMENT_96, FONT_IMAGE_PALETTE)
        elif self.num_characters == 128:
            self.tileset.from_image(image, _FONT_IMAGE_ARRANGEMENT_128, FONT_IMAGE_PALETTE)
        del image

        if widths_format == "yml":
            widths_dict = yml_load(widths_file)
            self.character_widths = [widths_dict[i] for i in range(self.tileset.num_tiles_maximum)]
Beispiel #19
0
    def read_from_rom(self, rom):
        self.patches = dict()
        # Loop through all the patches for this romtype
        for ip_desc_filename in [s for s in os.listdir(get_ips_directory(rom.type)) if s.lower().endswith(".yml")]:
            with open(os.path.join(get_ips_directory(rom.type), ip_desc_filename)) as ips_desc_file:
                ips_desc = yml_load(ips_desc_file)
                ips_desc_title = ips_desc["Title"]

                if ips_desc["Auto-Apply"]:
                    self.patches[ips_desc_title] = "enabled"
                else:
                    self.patches[ips_desc_title] = "disabled"
Beispiel #20
0
    def read_from_rom(self, rom):
        self.patches = dict()
        # Loop through all the patches for this romtype
        for ip_desc_filename in [s for s in os.listdir(get_ips_directory(rom.type)) if s.lower().endswith(".yml")]:
            with open(os.path.join(get_ips_directory(rom.type), ip_desc_filename)) as ips_desc_file:
                ips_desc = yml_load(ips_desc_file)
                ips_desc_title = ips_desc["Title"]

                if "Hidden" in ips_desc and ips_desc["Hidden"]:
                    continue
                elif ips_desc["Auto-Apply"]:
                    self.patches[ips_desc_title] = "enabled"
                else:
                    self.patches[ips_desc_title] = "disabled"
    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
Beispiel #22
0
 def read_from_project(self, resource_open):
     """
         Reads a user-written list of ranges that shouldn't be touched.
     """
     with resource_open(self.FILE, 'yml') as f:
         ranges = yml_load(f)
         if not ranges:
             self.ranges = []
         elif type(ranges) != list:
             raise InvalidYmlRepresentationError("used_range files is invalid. Must be a list of ranges.")
         else:
             self.ranges = []
             for entry in ranges:
                 self.ranges.append(range_from_string(entry))
Beispiel #23
0
 def read_from_project(self, resourceOpener):
     self.door_areas = []
     with resourceOpener("map_doors", "yml", True) as f:
         input = yml_load(f)
         for y in input:
             row = input[y]
             for x in row:
                 if row[x] is None:
                     self.door_areas.append(None)
                 else:
                     entry = []
                     for door in row[x]:
                         d = door_from_yml_rep(door)
                         entry.append(d)
                     self.door_areas.append(entry)
Beispiel #24
0
 def read_from_project(self, resourceOpener):
     self.door_areas = []
     with resourceOpener("map_doors", "yml", True) as f:
         input = sort_yml_doors(yml_load(f))
         for y in input:
             row = input[y]
             for x in row:
                 if row[x] is None:
                     self.door_areas.append(None)
                 else:
                     entry = []
                     for door in row[x]:
                         d = door_from_yml_rep(door)
                         entry.append(d)
                     self.door_areas.append(entry)
Beispiel #25
0
    def upgrade_project(self, old_version, new_version, rom, resource_open_r, resource_open_w, resource_delete):
        if old_version == new_version:
            return
        elif old_version == 5:
            # Expand all the fonts from 96 characters to 128 characters
            for i, font in enumerate(self.fonts):
                log.debug("Expanding font #{}".format(FONT_FILENAMES[i]))
                image_resource_name = "Fonts/" + FONT_FILENAMES[i]
                widths_resource_name = "Fonts/" + FONT_FILENAMES[i] + "_widths"
                new_image_w, new_image_h = font.image_size()

                # Expand the image

                with resource_open_r(image_resource_name, 'png') as image_file:
                    image = open_indexed_image(image_file)

                    expanded_image = Image.new("P", (new_image_w, new_image_h), None)
                    for y in range(new_image_h):
                        for x in range(new_image_w):
                            expanded_image.putpixel((x, y), 1)
                    FONT_IMAGE_PALETTE.to_image(expanded_image)
                    expanded_image.paste(image, (0, 0))

                    with resource_open_w(image_resource_name, 'png') as image_file2:
                        expanded_image.save(image_file2, "png")

                # Expand the widths

                with resource_open_r(widths_resource_name, "yml", True) as widths_file:
                    widths_dict = yml_load(widths_file)

                for character_id in range(96, 128):
                    if character_id not in widths_dict:
                        widths_dict[character_id] = 0

                with resource_open_w(widths_resource_name, "yml", True) as widths_file:
                    yml_dump(widths_dict, widths_file, default_flow_style=False)

            self.upgrade_project(6, new_version, rom, resource_open_r, resource_open_w, resource_delete)
        elif old_version <= 2:
            # The credits font was a new feature in version 3

            self.read_credits_font_from_rom(rom)
            self.write_credits_font_to_project(resource_open_w)
            self.upgrade_project(3, new_version, rom, resource_open_r, resource_open_w, resource_delete)
        else:
            self.upgrade_project(old_version + 1, new_version, rom, resource_open_r, resource_open_w, resource_delete)
Beispiel #26
0
    def upgrade_project(self, old_version, new_version, rom, resource_open_r, resource_open_w, resource_delete):
        if old_version == new_version:
            return
        elif old_version == 5:
            # Expand all the fonts from 96 characters to 128 characters
            for i, font in enumerate(self.fonts):
                log.debug("Expanding font #{}".format(FONT_FILENAMES[i]))
                image_resource_name = "Fonts/" + FONT_FILENAMES[i]
                widths_resource_name = "Fonts/" + FONT_FILENAMES[i] + "_widths"
                new_image_w, new_image_h = font.image_size()

                # Expand the image

                with resource_open_r(image_resource_name, 'png') as image_file:
                    image = open_indexed_image(image_file)

                    expanded_image = Image.new("P", (new_image_w, new_image_h), None)
                    for y in xrange(new_image_h):
                        for x in xrange(new_image_w):
                            expanded_image.putpixel((x, y), 1)
                    FONT_IMAGE_PALETTE.to_image(expanded_image)
                    expanded_image.paste(image, (0, 0))

                    with resource_open_w(image_resource_name, 'png') as image_file2:
                        expanded_image.save(image_file2, "png")

                # Expand the widths

                with resource_open_r(widths_resource_name, "yml") as widths_file:
                    widths_dict = yml_load(widths_file)

                for character_id in xrange(96, 128):
                    if character_id not in widths_dict:
                        widths_dict[character_id] = 0

                with resource_open_w(widths_resource_name, "yml") as widths_file:
                    yml_dump(widths_dict, widths_file, default_flow_style=False)

            self.upgrade_project(6, new_version, rom, resource_open_r, resource_open_w, resource_delete)
        elif old_version <= 2:
            # The credits font was a new feature in version 3

            self.read_credits_font_from_rom(rom)
            self.write_credits_font_to_project(resource_open_w)
            self.upgrade_project(3, new_version, rom, resource_open_r, resource_open_w, resource_delete)
        else:
            self.upgrade_project(old_version + 1, new_version, rom, resource_open_r, resource_open_w, resource_delete)
Beispiel #27
0
    def read_from_project(self, resource_open):
        formatting_data = {}

        with resource_open(CAST_FORMATTING_FILE_NAME, 'yml', True) as f:
            formatting_data = yml_load(f)

        for fmt_entry in formatting_data:
            entry = EbCastEntry()
            entry.set_values(formatting_data[fmt_entry]['begin'],
                             formatting_data[fmt_entry]['size'],
                             formatting_data[fmt_entry]['misc'])
            self.entries.append(entry)

            if entry.size == 0:
                raise InvalidArgumentError(
                    'Cast graphics entry number {} has size 0 - would crash the cast screen.'
                    .format(fmt_entry))
Beispiel #28
0
    def upgrade_project(self, old_version, new_version, rom, resource_open_r, resource_open_w, resource_delete):
        if old_version == 1:
            self.read_from_rom(rom)
            self.write_to_project(resource_open_w)
        elif old_version < new_version:
            self.read_from_project(resource_open_r)

            # Add in all the new patches
            for ip_desc_filename in [s for s in os.listdir(get_ips_directory(rom.type)) if s.lower().endswith(".yml")]:
                with open(os.path.join(get_ips_directory(rom.type), ip_desc_filename)) as ips_desc_file:
                    ips_desc = yml_load(ips_desc_file)
                    ips_desc_title = ips_desc["Title"]

                    if ips_desc_title not in self.patches:
                        self.patches[ips_desc_title] = "disabled"

            self.write_to_project(resource_open_w)
Beispiel #29
0
    def read_from_project(self, resource_open):
        log.debug('Reading dynamic cast names')
        yml_data = {}

        with resource_open(CAST_DYNAMIC_NAMES_FILE_NAME, 'yml', True) as f:
            yml_data = yml_load(f)

        for n in self.dynamic_names:
            n.read_from_yml_data(yml_data)

        log.debug('Reading cast formatting data')
        self.formatting.read_from_project(resource_open)

        log.debug('Reading cast name graphics')
        self.read_gfx_from_project(self.name_gfx, resource_open)

        log.debug('Reading miscellaneous cast graphics')
        self.read_gfx_from_project(self.misc_gfx, resource_open)
Beispiel #30
0
    def read_from_project(self, resource_open):
        with resource_open("Swirls/swirls", "yml") as f:
            swirl_data = yml_load(f)

        self.swirls = [Swirl() for i in xrange(self.swirl_table.num_rows)]
        for swirl_id, swirl in enumerate(self.swirls):
            log.debug("Reading Swirl #{}".format(swirl_id))
            speed = swirl_data[swirl_id]["speed"]
            num_frames = swirl_data[swirl_id]["frames"]

            swirl.speed = speed
            for frame_id in range(num_frames):
                with resource_open("Swirls/{}/{}".format(swirl_id, str(frame_id).zfill(3)), "png") as f:
                    image = open_indexed_image(f)
                    try:
                        swirl.add_frame_from_image(image)
                    except Exception as e:
                        message = "Encountered error while reading frame #{} of swirl #{}".format(frame_id, swirl_id)
                        raise CoilSnakeTraceableError(message, e)
    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
Beispiel #32
0
 def upgrade_project(self, old_version, new_version, rom, resource_open_r,
                     resource_open_w, resource_delete):
     if old_version == new_version:
         return
     elif old_version == 4:
         with resource_open_r("sprite_groups", "yml") as f:
             data = yml_load(f)
             for i in data:
                 entry = data[i]
                 collision_settings = entry["Collision Settings"]
                 entry["North/South Collision Width"] = collision_settings[
                     0]
                 entry["North/South Collision Height"] = collision_settings[
                     1]
                 entry["East/West Collision Width"] = collision_settings[2]
                 entry["East/West Collision Height"] = collision_settings[3]
                 del entry["Collision Settings"]
         with resource_open_w("sprite_groups", "yml") as f:
             yml_dump(data, f)
         self.upgrade_project(old_version + 1, new_version, rom,
                              resource_open_r, resource_open_w,
                              resource_delete)
     elif old_version == 2:
         replace_field_in_yml(resource_name="sprite_groups",
                              resource_open_r=resource_open_r,
                              resource_open_w=resource_open_w,
                              key="Unknown A",
                              new_key="Size",
                              value_map=dict(enumerate(SPRITE_SIZES)))
         replace_field_in_yml(resource_name="sprite_groups",
                              resource_open_r=resource_open_r,
                              resource_open_w=resource_open_w,
                              key="Unknown B",
                              new_key="Collision Settings")
         self.upgrade_project(old_version + 1, new_version, rom,
                              resource_open_r, resource_open_w,
                              resource_delete)
     else:
         self.upgrade_project(old_version + 1, new_version, rom,
                              resource_open_r, resource_open_w,
                              resource_delete)
Beispiel #33
0
    def read_from_project(self, resource_open):
        for i, tileset in enumerate(self.tilesets):
            log.debug("Reading tileset #{}".format(i))
            with resource_open("Tilesets/" + str(i).zfill(2), "fts") as f:
                tileset.from_file(f)

        log.debug("Reading palette settings")
        with resource_open("map_palette_settings", "yml") as f:
            yml_rep = yml_load(f)
            for map_tileset in yml_rep:
                # Get the draw (normal) tileset
                tileset = None
                for ts in self.tilesets:
                    if ts.has_map_tileset(map_tileset):
                        tileset = ts
                        break

                # For each map palette
                palettes = tileset.get_palettes_by_map_tileset(map_tileset)
                for palette_id, palette in palettes:
                    entry = yml_rep[map_tileset][palette_id]
                    palette.settings_from_yml_rep(entry)
Beispiel #34
0
    def read_from_project(self, resource_open):
        with resource_open('Animations/animations', 'yml', True) as f:
            animation_data = yml_load(f)

        for animation_id in animation_data:
            frames = animation_data[animation_id]['frames']
            unknown = animation_data[animation_id]['unknown']
            animation = Animation(frames=frames, unknown=unknown)
            self.animations.append(animation)

            for frame_id in range(frames):
                with resource_open(
                        'Animations/{}/{}'.format(animation_id,
                                                  str(frame_id).zfill(3)),
                        'png') as f:
                    image = open_indexed_image(f)
                    try:
                        animation.add_frame_from_image(image, frame_id)
                    except Exception as e:
                        message = 'Encountered error while reading frame #{} of Animation #{}'.format(
                            frame_id, animation_id)
                        raise CoilSnakeTraceableError(message, e)
Beispiel #35
0
    def upgrade_project(self, old_version, new_version, rom, resource_open_r, resource_open_w, resource_delete):
        if old_version == new_version:
            return
        elif old_version <= 6:
            with resource_open_r("map_palette_settings", "yml") as f:
                yml_rep = yml_load(f)
                for map_tileset in yml_rep.itervalues():
                    for map_palette in map_tileset.itervalues():
                        if "Event Palette" in map_palette:
                            map_palette["Event Palette"] = {
                                "Colors": map_palette["Event Palette"],
                                "Event Flag": 0,
                                "Flash Effect": 0,
                                "Sprite Palette": map_palette["Sprite Palette"]
                            }
            self.write_map_palette_settings(yml_rep, resource_open_w)

            self.upgrade_project(
                7, new_version, rom, resource_open_r, resource_open_w, resource_delete)
        else:
            self.upgrade_project(
                old_version + 1, new_version, rom, resource_open_r, resource_open_w, resource_delete)
Beispiel #36
0
    def read_from_project(self, resource_open):
        with resource_open("Swirls/swirls", "yml") as f:
            swirl_data = yml_load(f)

        self.swirls = [Swirl() for i in xrange(self.swirl_table.num_rows)]
        for swirl_id, swirl in enumerate(self.swirls):
            log.debug("Reading Swirl #{}".format(swirl_id))
            speed = swirl_data[swirl_id]["speed"]
            num_frames = swirl_data[swirl_id]["frames"]

            swirl.speed = speed
            for frame_id in range(num_frames):
                with resource_open(
                        "Swirls/{}/{}".format(swirl_id,
                                              str(frame_id).zfill(3)),
                        "png") as f:
                    image = open_indexed_image(f)
                    try:
                        swirl.add_frame_from_image(image)
                    except Exception as e:
                        message = "Encountered error while reading frame #{} of swirl #{}".format(
                            frame_id, swirl_id)
                        raise CoilSnakeTraceableError(message, e)
    def upgrade_project(self, old_version, new_version, rom, resource_open_r, resource_open_w, resource_delete):
        if old_version == new_version:
            return
        elif old_version == 4:
            with resource_open_r("TownMaps/icon_positions", "yml") as f:
                data = yml_load(f)

                for i in range(6):
                    old_key = TownMapEnum.tostring(i).lower()
                    data[i] = data[old_key]
                    del data[old_key]
            with resource_open_w("TownMaps/icon_positions", "yml") as f:
                yml_dump(data, f, default_flow_style=False)

            convert_values_to_hex_repr_in_yml_file("TownMaps/icon_positions", resource_open_r, resource_open_w,
                                                   ["Event Flag"])

            self.upgrade_project(5, new_version, rom, resource_open_r, resource_open_w, resource_delete)
        elif old_version <= 2:
            self.read_from_rom(rom)
            self.write_to_project(resource_open_w)
            self.upgrade_project(new_version, new_version, rom, resource_open_r, resource_open_w, resource_delete)
        else:
            self.upgrade_project(old_version + 1, new_version, rom, resource_open_r, resource_open_w, resource_delete)
Beispiel #38
0
    def upgrade_project(self, old_version, new_version, rom, resource_open_r, resource_open_w, resource_delete):
        if old_version == 1:
            self.read_from_rom(rom)
            self.write_to_project(resource_open_w)
        elif old_version < new_version:
            self.read_from_project(resource_open_r)

            # Remove all patches that should not exist
            if rom.type in REMOVED_PATCHES:
                for patch_name in REMOVED_PATCHES[rom.type]:
                    if patch_name in self.patches:
                        del self.patches[patch_name]

            # Add in all the new patches
            for ip_desc_filename in [s for s in os.listdir(get_ips_directory(rom.type)) if s.lower().endswith(".yml")]:
                with open(os.path.join(get_ips_directory(rom.type), ip_desc_filename)) as ips_desc_file:
                    ips_desc = yml_load(ips_desc_file)
                    ips_desc_title = ips_desc["Title"]
                    ips_is_hidden = ("Hidden" in ips_desc) and ips_desc["Hidden"]

                    if (not ips_is_hidden) and (ips_desc_title not in self.patches):
                        self.patches[ips_desc_title] = "disabled"

            self.write_to_project(resource_open_w)
Beispiel #39
0
 def read_from_project(self, resource_open):
     with resource_open("patches", "yml") as f:
         self.patches = yml_load(f)
Beispiel #40
0
 def read_from_project(self, resource_open):
     with resource_open("text_misc", "yml") as f:
         self.data = yml_load(f)
Beispiel #41
0
 def from_yml_file(self, f):
     yml_rep = yml_load(f)
     self.from_yml_rep(yml_rep)
Beispiel #42
0
    def read_staff_chars_from_assets(self):
        with open_asset('structures', 'eb_staff_chars.yml') as f:
            yml_data = yml_load(f)

        self.read_staff_chars(yml_data)
Beispiel #43
0
 def read_from_project(self, resource_open):
     with resource_open("text_misc", "yml", True) as f:
         self.data = yml_load(f)
    def read_chars_data_from_project(self, resource_open):
        # Read the characters positions
        with resource_open(CHARS_POSITIONS_PATH, "yml", True) as f:
            chars_positions = yml_load(f)

        # Read the characters animated frames
        self.chars_tileset = None
        self.chars_anim_palette = EbPalette(
            CHARS_NUM_ANIM_SUBPALETTES, ANIM_SUBPALETTE_LENGTH
        )
        original_tileset = None
        for p in range(CHARS_NUM_ANIM_SUBPALETTES):
            # Read one of the animation frames
            with resource_open(CHARS_FRAMES_PATH.format(p), "png") as f:
                # Create temporary structures to hold the data
                image = open_indexed_image(f)
                arrangement = EbTileArrangement(
                    image.width // TILE_WIDTH, image.height // TILE_HEIGHT
                )
                tileset = EbGraphicTileset(
                    CHARS_NUM_TILES, TILE_WIDTH, TILE_HEIGHT
                )
                anim_subpalette = EbPalette(
                    NUM_SUBPALETTES, ANIM_SUBPALETTE_LENGTH
                )
                arrangement.from_image(image, tileset, anim_subpalette, True)

            # Add the characters animation subpalette
            for i in range(ANIM_SUBPALETTE_LENGTH):
                self.chars_anim_palette[p, i] = anim_subpalette[0, i]

            # Add the characters tileset if not already set, otherwise
            # ensure that it the current tileset is identical
            if not self.chars_tileset:
                original_tileset = tileset
                self.chars_tileset = EbGraphicTileset(
                    CHARS_NUM_TILES, TILE_WIDTH, TILE_HEIGHT
                )
                self.chars_tileset.tiles = [
                    [[0 for _ in range(TILE_HEIGHT)]
                        for _ in range(TILE_WIDTH)]
                    for _ in range(CHARS_NUM_TILES)
                ]
                unused_tiles = set(range(CHARS_NUM_TILES))

                # Set the new character layouts
                self.chars_layouts = [[] for _ in range(NUM_CHARS)]
                for c, data in chars_positions.items():
                    # Get the data from the YAML file
                    x = int(data['x'] // TILE_WIDTH)
                    y = int(data['y'] // TILE_HEIGHT)
                    width = int(data['width'] // TILE_WIDTH)
                    height = int(data['height'] // TILE_HEIGHT)
                    x_offset = data['top_left_offset']['x']
                    y_offset = data['top_left_offset']['y']
                    unknown = data['unknown']

                    # Generate a list of all tiles must be visited
                    # Where possible, we try to generate a multi tile (4 tiles
                    # stored as one); otherwise, bordering tiles that are
                    # visited will all be single tiles.
                    l = [
                        (i, j) for i in range(0, width, 2)
                        for j in range(0, height, 2)
                    ]
                    if width % 2 == 1:
                        l.extend([(width-1, j) for j in range(1, height, 2)])
                    if height % 2 == 1:
                        l.extend([(i, height-1) for i in range(1, width, 2)])

                    # Generate the new reduced tileset
                    for i, j in l:
                        # Put the tile in the new tileset
                        o_tile = arrangement[x + i, y + j].tile
                        n_tile = unused_tiles.pop()
                        self.chars_tileset.tiles[n_tile] = tileset[o_tile]

                        entry = TitleScreenLayoutEntry(
                            i*8 + x_offset, j*8 + y_offset, n_tile, 0, unknown
                        )

                        # Create a multi entry if possible to save space
                        if i < width - 1 and j < height - 1:
                            entry.set_single(True)
                            o_tile_r = arrangement[x+i+1, y+j].tile
                            o_tile_d = arrangement[x+i, y+j+1].tile
                            o_tile_dr = arrangement[x+i+1, y+j+1].tile
                            n_tile_r = n_tile + 1
                            n_tile_d = n_tile + 16
                            n_tile_dr = n_tile + 17
                            unused_tiles.difference_update(
                                (n_tile_r, n_tile_d, n_tile_dr)
                            )
                            self.chars_tileset.tiles[n_tile_r] = \
                                tileset[o_tile_r]
                            self.chars_tileset.tiles[n_tile_d] = \
                                tileset[o_tile_d]
                            self.chars_tileset.tiles[n_tile_dr] = \
                                tileset[o_tile_dr]

                        self.chars_layouts[c].append(entry)
                    self.chars_layouts[c][-1].set_final(True)

            elif original_tileset != tileset:
                log.warn(
                    "Tileset from characters frame {} does not match "
                    "tileset from characters frame 0.".format(p)
                )

        # Read the initial characters palette
        with resource_open(CHARS_INITIAL_PATH, "png") as f:
            image = open_indexed_image(f)
            arrangement = EbTileArrangement(
                image.width // TILE_WIDTH, image.height // TILE_HEIGHT
            )
            tileset = EbGraphicTileset(
                CHARS_NUM_TILES, TILE_WIDTH, TILE_HEIGHT
            )
            self.chars_palette = EbPalette(
                NUM_SUBPALETTES, ANIM_SUBPALETTE_LENGTH
            )
            arrangement.from_image(image, tileset, self.chars_palette)
 def read_from_project(self, resource_open):
     with resource_open("naming_skip", "yml", True) as f:
         self.data = yml_load(f)
Beispiel #46
0
    def read_staff_chars_from_project(self, resource_open):
        with resource_open(STAFF_CHARS_FILE_NAME, 'yml', True) as f:
            yml_data = yml_load(f)

        self.read_staff_chars(yml_data)
Beispiel #47
0
 def load(self):
     try:
         with open(self.PREFERENCES_FILENAME, 'r') as f:
             self.preferences = yml_load(f)
     except IOError:
         self.preferences = {}
Beispiel #48
0
 def from_yml_file(self, f):
     yml_rep = yml_load(f)
     self.from_yml_rep(yml_rep)
    def read_chars_data_from_project(self, resource_open):
        # Read the characters positions
        with resource_open(CHARS_POSITIONS_PATH, "yml") as f:
            chars_positions = yml_load(f)

        # Read the characters animated frames
        self.chars_tileset = None
        self.chars_anim_palette = EbPalette(CHARS_NUM_ANIM_SUBPALETTES,
                                            ANIM_SUBPALETTE_LENGTH)
        original_tileset = None
        for p in xrange(CHARS_NUM_ANIM_SUBPALETTES):
            # Read one of the animation frames
            with resource_open(CHARS_FRAMES_PATH.format(p), "png") as f:
                # Create temporary structures to hold the data
                image = open_indexed_image(f)
                arrangement = EbTileArrangement(image.width / TILE_WIDTH,
                                                image.height / TILE_HEIGHT)
                tileset = EbGraphicTileset(CHARS_NUM_TILES, TILE_WIDTH,
                                           TILE_HEIGHT)
                anim_subpalette = EbPalette(NUM_SUBPALETTES,
                                            ANIM_SUBPALETTE_LENGTH)
                arrangement.from_image(image, tileset, anim_subpalette, True)

            # Add the characters animation subpalette
            for i in xrange(ANIM_SUBPALETTE_LENGTH):
                self.chars_anim_palette[p, i] = anim_subpalette[0, i]

            # Add the characters tileset if not already set, otherwise
            # ensure that it the current tileset is identical
            if not self.chars_tileset:
                original_tileset = tileset
                self.chars_tileset = EbGraphicTileset(CHARS_NUM_TILES,
                                                      TILE_WIDTH, TILE_HEIGHT)
                self.chars_tileset.tiles = [[[0 for _ in xrange(TILE_HEIGHT)]
                                             for _ in xrange(TILE_WIDTH)]
                                            for _ in xrange(CHARS_NUM_TILES)]
                unused_tiles = set(xrange(CHARS_NUM_TILES))

                # Set the new character layouts
                self.chars_layouts = [[] for _ in xrange(NUM_CHARS)]
                for c, data in chars_positions.items():
                    # Get the data from the YAML file
                    x = int(data['x'] / TILE_WIDTH)
                    y = int(data['y'] / TILE_HEIGHT)
                    width = int(data['width'] / TILE_WIDTH)
                    height = int(data['height'] / TILE_HEIGHT)
                    x_offset = data['top_left_offset']['x']
                    y_offset = data['top_left_offset']['y']
                    unknown = data['unknown']

                    # Generate a list of all tiles must be visited
                    # Where possible, we try to generate a multi tile (4 tiles
                    # stored as one); otherwise, bordering tiles that are
                    # visited will all be single tiles.
                    l = [(i, j) for i in xrange(0, width, 2)
                         for j in xrange(0, height, 2)]
                    if width % 2 == 1:
                        l.extend([(width - 1, j)
                                  for j in xrange(1, height, 2)])
                    if height % 2 == 1:
                        l.extend([(i, height - 1)
                                  for i in xrange(1, width, 2)])

                    # Generate the new reduced tileset
                    for i, j in l:
                        # Put the tile in the new tileset
                        o_tile = arrangement[x + i, y + j].tile
                        n_tile = unused_tiles.pop()
                        self.chars_tileset.tiles[n_tile] = tileset[o_tile]

                        entry = TitleScreenLayoutEntry(i * 8 + x_offset,
                                                       j * 8 + y_offset,
                                                       n_tile, 0, unknown)

                        # Create a multi entry if possible to save space
                        if i < width - 1 and j < height - 1:
                            entry.set_single(True)
                            o_tile_r = arrangement[x + i + 1, y + j].tile
                            o_tile_d = arrangement[x + i, y + j + 1].tile
                            o_tile_dr = arrangement[x + i + 1, y + j + 1].tile
                            n_tile_r = n_tile + 1
                            n_tile_d = n_tile + 16
                            n_tile_dr = n_tile + 17
                            unused_tiles.difference_update(
                                (n_tile_r, n_tile_d, n_tile_dr))
                            self.chars_tileset.tiles[n_tile_r] = \
                                tileset[o_tile_r]
                            self.chars_tileset.tiles[n_tile_d] = \
                                tileset[o_tile_d]
                            self.chars_tileset.tiles[n_tile_dr] = \
                                tileset[o_tile_dr]

                        self.chars_layouts[c].append(entry)
                    self.chars_layouts[c][-1].set_final(True)

            elif original_tileset != tileset:
                log.warn("Tileset from characters frame {} does not match "
                         "tileset from characters frame 0.".format(p))

        # Read the initial characters palette
        with resource_open(CHARS_INITIAL_PATH, "png") as f:
            image = open_indexed_image(f)
            arrangement = EbTileArrangement(image.width / TILE_WIDTH,
                                            image.height / TILE_HEIGHT)
            tileset = EbGraphicTileset(CHARS_NUM_TILES, TILE_WIDTH,
                                       TILE_HEIGHT)
            self.chars_palette = EbPalette(NUM_SUBPALETTES,
                                           ANIM_SUBPALETTE_LENGTH)
            arrangement.from_image(image, tileset, self.chars_palette)
Beispiel #50
0
    def upgrade_project(self, old_version, new_version, rom, resource_open_r, resource_open_w, resource_delete):
        if old_version == new_version:
            return
        elif old_version == 3:
            replace_field_in_yml(resource_name="item_configuration_table",
                                 resource_open_r=resource_open_r,
                                 resource_open_w=resource_open_w,
                                 key="Effect",
                                 new_key="Action")
            replace_field_in_yml(resource_name="psi_ability_table",
                                 resource_open_r=resource_open_r,
                                 resource_open_w=resource_open_w,
                                 key="Effect",
                                 new_key="Action")
            replace_field_in_yml(resource_name="psi_ability_table",
                                 resource_open_r=resource_open_r,
                                 resource_open_w=resource_open_w,
                                 key="PSI Name",
                                 value_map={0: None,
                                            1: 0,
                                            2: 1,
                                            3: 2,
                                            4: 3,
                                            5: 4,
                                            6: 5,
                                            7: 6,
                                            8: 7,
                                            9: 8,
                                            10: 9,
                                            11: 10,
                                            12: 11,
                                            13: 12,
                                            14: 13,
                                            15: 14,
                                            16: 15,
                                            17: 16})

            resource_delete("cmd_window_text")
            resource_delete("psi_anim_palettes")
            resource_delete("sound_stone_palette")

            self.upgrade_project(old_version=old_version + 1,
                                 new_version=new_version,
                                 rom=rom,
                                 resource_open_r=resource_open_r,
                                 resource_open_w=resource_open_w,
                                 resource_delete=resource_delete)
        elif old_version == 2:
            replace_field_in_yml(resource_name="timed_delivery_table",
                                 resource_open_r=resource_open_r,
                                 resource_open_w=resource_open_w,
                                 key="Suitable Area Text Pointer",
                                 new_key="Delivery Success Text Pointer")
            replace_field_in_yml(resource_name="timed_delivery_table",
                                 resource_open_r=resource_open_r,
                                 resource_open_w=resource_open_w,
                                 key="Unsuitable Area Text Pointer",
                                 new_key="Delivery Failure Text Pointer")

            with resource_open_r("timed_delivery_table", "yml") as f:
                out = yml_load(f)
                yml_str_rep = yml_dump(out, default_flow_style=False)

            yml_str_rep = convert_values_to_hex_repr(yml_str_rep, "Event Flag")

            with resource_open_w("timed_delivery_table", "yml") as f:
                f.write(yml_str_rep)

            self.upgrade_project(old_version=old_version + 1,
                                 new_version=new_version,
                                 rom=rom,
                                 resource_open_r=resource_open_r,
                                 resource_open_w=resource_open_w,
                                 resource_delete=resource_delete)
        elif old_version == 1:
            replace_field_in_yml(resource_name="psi_ability_table",
                                 resource_open_r=resource_open_r,
                                 resource_open_w=resource_open_w,
                                 key="Target",
                                 new_key="Usability Outside of Battle",
                                 value_map={"Nobody": "Other",
                                            "Enemies": "Unusable",
                                            "Allies": "Usable"})
            replace_field_in_yml(resource_name="battle_action_table",
                                 resource_open_r=resource_open_r,
                                 resource_open_w=resource_open_w,
                                 key="Direction",
                                 value_map={"Party": "Enemy",
                                            "Enemy": "Party"})

            self.upgrade_project(old_version=old_version + 1,
                                 new_version=new_version,
                                 rom=rom,
                                 resource_open_r=resource_open_r,
                                 resource_open_w=resource_open_w,
                                 resource_delete=resource_delete)
        else:
            self.upgrade_project(old_version + 1, new_version, rom, resource_open_r, resource_open_w, resource_delete)
Beispiel #51
0
        return allocated_range[0]

    def get_largest_unallocated_range(self):
        largest_begin, largest_end = 1, 0
        for begin, end in self.unallocated_ranges:
            if end - begin > largest_end - largest_begin:
                largest_begin = begin
                largest_end = end
        if largest_end - largest_begin <= 0:
            raise NotEnoughUnallocatedSpaceError("Not enough free space left")
        return largest_begin, largest_end


with open_asset("romtypes.yml") as f:
    ROM_TYPE_MAP = yml_load(f)

ROM_TYPE_NAME_UNKNOWN = "Unknown"


class Rom(AllocatableBlock):
    def reset(self, size=0):
        super(Rom, self).reset(size)
        self.type = ROM_TYPE_NAME_UNKNOWN

    def from_file(self, filename):
        super(Rom, self).from_file(filename)
        self._setup_rom_post_load()

    def _setup_rom_post_load(self):
        self.type = self._detect_type()
Beispiel #52
0
    def read_from_project(self, resource_open):
        with resource_open("enemy_configuration_table", "yml") as f:
            self.enemy_config_table.from_yml_file(f)

        # Read the sprites and palettes
        self.battle_sprites = []
        self.palettes = []

        sprite_hashes = dict()
        num_sprites = 0
        palette_hashes = dict()
        num_palettes = 0
        for i in range(self.enemy_config_table.num_rows):
            battle_sprite = EbBattleSprite()
            palette = EbPalette(num_subpalettes=1, subpalette_length=16)

            try:
                with resource_open("BattleSprites/" + str(i).zfill(3), "png") as f:
                    image = open_indexed_image(f)
                    battle_sprite.from_image(image)
                    palette.from_image(image)
                    del image
            except IOError:
                # No battle sprite
                self.enemy_config_table[i][4] = 0
                self.enemy_config_table[i][14] = 0
                continue

            sprite_hash = battle_sprite.hash()
            try:
                self.enemy_config_table[i][4] = sprite_hashes[sprite_hash] + 1
            except KeyError:
                self.enemy_config_table[i][4] = num_sprites + 1
                sprite_hashes[sprite_hash] = num_sprites
                self.battle_sprites.append(battle_sprite)
                num_sprites += 1

            palette_hash = palette.hash()
            try:
                self.enemy_config_table[i][14] = palette_hashes[palette_hash]
            except KeyError:
                self.enemy_config_table[i][14] = num_palettes
                palette_hashes[palette_hash] = num_palettes
                self.palettes.append(palette)
                num_palettes += 1

        # Read the groups
        with resource_open("enemy_groups", "yml") as f:
            self.enemy_group_table.from_yml_file(f)

        with resource_open("enemy_groups", "yml") as f:
            self.enemy_group_bg_table.from_yml_file(f)

        with resource_open("enemy_groups", "yml") as f:
            self.enemy_groups = []
            enemy_groups_yml_rep = yml_load(f)
            for entry in enemy_groups_yml_rep.itervalues():
                enemy_group = entry["Enemies"]
                if type(enemy_group) == dict:
                    enemy_group = [enemy_group[x] for x in sorted(enemy_group.keys())]
                group = [EnemyGroupTableEntry.from_yml_rep(x) for x in enemy_group]
                self.enemy_groups.append(group)