32 const std::filesystem::path &project_root,
37 auto image_result = loader.
load_from_file((project_root / src_key.
key()).string());
38 if (!image_result.has_value()) {
39 switch (image_result.error().type()) {
40 case ImageLoadError::Type::file_not_found:
41 case ImageLoadError::Type::unsupported_channel_count:
42 case ImageLoadError::Type::other_load_error:
47 panic(
"unhandled ImageLoadError type");
58 const std::filesystem::path &project_root,
62 panic(std::format(
"invalid palette index {}: out of range", index));
70 "Failed to load palette file.");
95template <SupportsTransparency PixelType,
typename LoaderType,
typename ComponentGetter>
99 const std::filesystem::path &project_root,
100 const std::string &anim_name,
101 const std::string &frame_name,
102 const LoaderType &loader,
103 ComponentGetter component_getter,
104 std::string_view error_context)
107 const auto png_path = project_root / src_key.
key();
110 load_animation_frame_from_png<PixelType>(png_path, frame_name, loader),
112 "{}: failed to load {}",
117 auto &component = component_getter(dest);
118 if (!component.has_anim(anim_name)) {
120 component.add_anim(std::move(anim));
123 auto &anim = component.anims().at(anim_name);
125 if (frame_name ==
"key") {
127 anim.
key_frame(std::move(load_result.frame));
131 anim.put_frame(frame_name, std::move(load_result.frame));
135 auto params = anim.params();
136 if (params.width_tiles() == 0 && params.height_tiles() == 0) {
137 params.width_tiles(load_result.width_tiles);
138 params.height_tiles(load_result.height_tiles);
139 anim.params(std::move(params));
154 for (
auto &entry : entries) {
164 const auto path = project_root_ / src_key.
key();
167 for (
auto &attribute : attributes) {
185 panic(std::format(
"invalid palette index {}: out of range", index));
195 const std::string &anim_name,
197 const std::vector<std::pair<std::string, ArtifactKey>> &frame_keys)
const
201 for (
const auto &[frame_name, frame_key] : frame_keys) {
203 (import_anim_frame_impl<IndexPixel>(
209 *png_indexed_loader_,
211 "Porymap animation frame")),
216 std::filesystem::path params_path = project_root_ / params_key.
key();
217 if (!std::filesystem::exists(params_path)) {
230 "{}: Failed to parse animation parameters.",
236 auto existing_params = anim.params();
240 new_params.width_tiles(existing_params.width_tiles());
241 new_params.height_tiles(existing_params.height_tiles());
243 anim.params(std::move(new_params));
295 attributes_csv_loader_->
load((project_root_ / src_key.
key()).string(), *schema_, *provider_map_, dest.
name()),
297 for (
const auto &[metatile_id, attribute] : load_result.attributes) {
302 for (
const auto &[role, present] : load_result.active_pin_column_present) {
312 PT_TRY_CALL_PASS_ERR(import_porytiles_palette(dest, src_key, index, project_root_, *palette_loader_),
void);
318 const std::string &anim_name,
320 const std::optional<ArtifactKey> &key_frame_key,
321 const std::vector<std::pair<std::string, ArtifactKey>> &frame_keys)
const
327 anim_json_parser_->
parse((project_root_ / params_key.
key()).string()),
329 "{}: Failed to parse animation parameters.",
334 if (it == parsed_anim_params.end()) {
336 "{}: Animation '{}' not found in animation parameters file.",
341 const auto ¶ms = it->second;
349 if (key_frame_key.has_value()) {
351 (import_anim_frame_impl<Rgba32>(
353 key_frame_key.value(),
359 "Porytiles animation frame")),
364 for (
const auto &[frame_name, frame_key] : frame_keys) {
366 (import_anim_frame_impl<Rgba32>(
374 "Porytiles animation frame")),
384 const auto json_path = project_root_ / params_key.
key();
390 "{}: Failed to parse primary animation references.",
393 if (parsed_refs.empty()) {
397 std::map<std::string, std::vector<AnimOverrideEntry>> converted;
398 for (
auto &[cased_name, entries] : parsed_refs) {
399 converted[cased_name.to_snake_case()] = std::move(entries);
Shared helper for loading animation frames from PNG files.
#define PT_TRY_ASSIGN_CHAIN_ERR(var, expr, return_type,...)
Unwraps a ChainableResult, chaining a new error message on failure.
#define PT_TRY_CALL_PASS_ERR(expr, return_type)
Unwraps a void ChainableResult, passing through the error chain with an empty FormattableError when t...
#define PT_TRY_ASSIGN_PASS_ERR(var, expr, return_type)
Unwraps a ChainableResult, passing through the error chain with an empty FormattableError when types ...
ChainableResult< std::map< DynamicCasedName, AnimParams > > parse_from_callback(const std::filesystem::path &c_file_path, const std::string &callback_func_name, const DynamicCasedName &tileset_cased_name, bool porytiles_managed) const
Parses animation parameters by following the callback chain.
ChainableResult< std::map< DynamicCasedName, std::vector< AnimOverrideEntry > > > parse_primary_references(const std::filesystem::path &json_path) const
Parses the primary_references section from an anim.json file.
ChainableResult< std::map< DynamicCasedName, AnimParams > > parse(const std::filesystem::path &json_path) const
Parses an anim.json file into a map of animation parameters.
A complete tileset animation with name, configuration, and frame data.
const AnimFrame< PixelType > & key_frame() const
Returns the key frame of this animation.
A type-safe wrapper for artifact keys.
const std::string & key() const
ChainableResult< AttributesCsvLoadResult > load(const std::filesystem::path &path, const Schema &schema, const ProviderMap &providers, const std::string &tileset_name) const
Loads metatile attributes from a CSV file.
A result type that maintains a chainable sequence of errors for debugging and error reporting.
A smart string wrapper that preserves word structure for lossless case format conversion.
A service interface that loads a fixed-length Palette from a given file.
virtual ChainableResult< Palette< Rgba32, palette::max_size > > load_with_wildcards(const std::filesystem::path &path) const =0
A template for two-dimensional images with arbitrarily typed pixel values.
An image loader that reads PNG files to create an Image with an Rgba32 pixel type.
ChainableResult< std::unique_ptr< Image< Rgba32 > >, ImageLoadError > load_from_file(const std::filesystem::path &path) const
const std::map< std::string, Animation< IndexPixel > > & anims() const
void set_palette(std::size_t palette_index, Palette< Rgba32, palette::max_size > palette)
void push_back_tilemap_entry(TilemapEntry entry)
Add a TilemapEntry to the end of the entry vector.
void push_back_attribute(MetatileAttribute attribute)
Add a MetatileAttribute to the end of the attribute vector.
const Image< IndexPixel > & tiles_png() const
const Image< Rgba32 > & bottom() const
void set_palette(std::size_t palette_index, Palette< Rgba32, palette::max_size > palette)
const Image< Rgba32 > & middle() const
PriorPinColumnState prior_pin_column_state(FieldRole role) const
Returns the recorded prior pin-column state for a role, or no_csv when none was recorded.
const Image< Rgba32 > & top() const
void insert_attribute(std::size_t metatile_id, MetatileAttribute attribute)
Insert a MetatileAttribute to the end of the attribute vector.
void add_anim(Animation< Rgba32 > anim)
const std::map< std::string, std::vector< AnimOverrideEntry > > & primary_anim_overrides() const
ChainableResult< void > read_metatile_attributes_bin(Tileset &dest, const ArtifactKey &src_key) const override
ChainableResult< void > read_top_png(Tileset &dest, const ArtifactKey &src_key) const override
ChainableResult< void > read_porymap_palette_n(Tileset &dest, const ArtifactKey &src_key, std::size_t index) const override
ChainableResult< void > read_attributes_csv(Tileset &dest, const ArtifactKey &src_key) const override
ChainableResult< void > read_middle_png(Tileset &dest, const ArtifactKey &src_key) const override
ChainableResult< void > read_porytiles_anim(Tileset &dest, const std::string &anim_name, const ArtifactKey ¶ms_key, const std::optional< ArtifactKey > &key_frame_key, const std::vector< std::pair< std::string, ArtifactKey > > &frame_keys) const override
ChainableResult< void > read_bottom_png(Tileset &dest, const ArtifactKey &src_key) const override
ChainableResult< void > read_porymap_anim(Tileset &dest, const std::string &anim_name, const ArtifactKey ¶ms_key, const std::vector< std::pair< std::string, ArtifactKey > > &frame_keys) const override
ChainableResult< void > read_porytiles_primary_anim_references(Tileset &dest, const ArtifactKey ¶ms_key) const override
ChainableResult< void > read_tiles_png(Tileset &dest, const ArtifactKey &src_key) const override
ChainableResult< void > read_metatiles_bin(Tileset &dest, const ArtifactKey &src_key) const override
ChainableResult< void > read_porytiles_palette_n(Tileset &dest, const ArtifactKey &src_key, std::size_t index) const override
static const Style bold
Bold text formatting.
A complete tileset containing both Porytiles and Porymap components.
const PorytilesTilesetComponent & porytiles_component() const
const PorymapTilesetComponent & porymap_component() const
const std::string & name() const
std::string managed_callback_name(const std::string &tileset_name)
constexpr std::size_t num_palettes
void panic(const StringViewSourceLoc &s)
Unconditionally terminates the program with a panic message.
ChainableResult< Palette< Rgba32, palette::max_size > > load_porymap_palette(const std::filesystem::path &path, const FilePaletteLoader &loader)
Loads a Porymap palette file (e.g., 00.pal).
DynamicCasedName extract_tileset_cased_name(const std::string &tileset_name)
Extracts the tileset short name and wraps it in a DynamicCasedName.
ChainableResult< std::vector< TilemapEntry > > parse_metatiles_bin(const std::filesystem::path &path)
Parses a metatiles.bin file into TilemapEntry objects.
ChainableResult< std::vector< MetatileAttribute > > parse_metatile_attributes(const std::filesystem::path &path, const Schema &schema)
Parses a metatile_attributes.bin file according to a metatile attribute schema.
ChainableResult< std::unique_ptr< Image< IndexPixel > > > load_indexed_png(const std::filesystem::path &path, const PngIndexedImageLoader &loader)
Loads an indexed PNG file (e.g., tiles.png).
Utility functions for string manipulation and formatting.