Porytiles
Loading...
Searching...
No Matches
tileset_artifact_key_provider.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <set>
4#include <string>
5
8
9namespace porytiles2 {
10
29 public:
30 virtual ~TilesetArtifactKeyProvider() = default;
31
44 [[nodiscard]] virtual ArtifactKey
45 key_for(const std::string &tileset_name, const TilesetArtifact &artifact) const = 0;
46
57 [[nodiscard]] virtual bool artifact_exists(const ArtifactKey &key) const = 0;
58
65 [[nodiscard]] virtual bool tileset_exists(const std::string &tileset_name) const = 0;
66
77 [[nodiscard]] virtual std::set<std::string> discover_porytiles_anims(const std::string &tileset_name) const = 0;
78
91 [[nodiscard]] virtual std::set<int>
92 discover_porytiles_anim_frames(const std::string &tileset_name, const std::string &anim_name) const = 0;
93
104 [[nodiscard]] virtual std::set<std::string> discover_porymap_anims(const std::string &tileset_name) const = 0;
105
118 [[nodiscard]] virtual std::set<int>
119 discover_porymap_anim_frames(const std::string &tileset_name, const std::string &anim_name) const = 0;
120
131 [[nodiscard]] virtual std::vector<ArtifactKey> get_porytiles_artifact_keys(const std::string &tileset_name) const
132 {
133 /*
134 * TODO: it feels like the discovery logic here and in tileset_repo.cpp is duplicated. Is there some way to
135 * massage these two classes so we don't need to duplicate the logic in two places? Perhaps ArtifactKey should
136 * also store a std::variant<TilesetArtifact, LayoutArtifact> as metadata. Then, tileset_repo.cpp could call
137 * get_all_artifact_keys directly. And then search the output for the metadata it needs and throw if essential
138 * items are missing?
139 */
140
141 using enum TilesetArtifact::Type;
142 std::vector<ArtifactKey> result;
143
144 const auto bottom_png_key = key_for(tileset_name, TilesetArtifact{bottom_png});
145 if (artifact_exists(bottom_png_key)) {
146 result.push_back(bottom_png_key);
147 }
148
149 const auto middle_png_key = key_for(tileset_name, TilesetArtifact{middle_png});
150 if (artifact_exists(middle_png_key)) {
151 result.push_back(middle_png_key);
152 }
153
154 const auto top_png_key = key_for(tileset_name, TilesetArtifact{top_png});
155 if (artifact_exists(top_png_key)) {
156 result.push_back(top_png_key);
157 }
158
159 const auto attr_csv_key = key_for(tileset_name, TilesetArtifact{attributes_csv});
160 if (artifact_exists(attr_csv_key)) {
161 result.push_back(attr_csv_key);
162 }
163
164 // TODO: don't hardcode 16 here
165 // TODO: warn user if we found overrides like 1.pal, these won't work they have to be 01.pal
166 constexpr int num_pals = 16;
167 for (unsigned int i = 0; i < num_pals; i++) {
168 const auto override_key = key_for(tileset_name, TilesetArtifact{pal_override_n, i});
169 if (artifact_exists(override_key)) {
170 result.push_back(override_key);
171 }
172 }
173
174 const auto porytiles_anims = discover_porytiles_anims(tileset_name);
175 for (const auto &anim : porytiles_anims) {
176 const auto frame_00_key = key_for(tileset_name, TilesetArtifact{porytiles_anim_frame, anim, 0});
177 if (artifact_exists(frame_00_key)) {
178 result.push_back(frame_00_key);
179 }
180 const auto frames = discover_porytiles_anim_frames(tileset_name, anim);
181 for (const auto &frame : frames) {
182 const auto frame_n_key = key_for(tileset_name, TilesetArtifact{porymap_anim_frame, anim, frame});
183 if (artifact_exists(frame_n_key)) {
184 result.push_back(frame_n_key);
185 }
186 }
187 }
188
189 return result;
190 }
191
202 [[nodiscard]] virtual std::vector<ArtifactKey> get_porymap_artifact_keys(const std::string &tileset_name) const
203 {
204 using enum TilesetArtifact::Type;
205 std::vector<ArtifactKey> result;
206
207 const auto metatiles_key = key_for(tileset_name, TilesetArtifact{metatiles_bin});
208 if (artifact_exists(metatiles_key)) {
209 result.push_back(metatiles_key);
210 }
211
212 const auto attr_key = key_for(tileset_name, TilesetArtifact{metatile_attributes_bin});
213 if (artifact_exists(attr_key)) {
214 result.push_back(attr_key);
215 }
216
217 const auto tiles_png_key = key_for(tileset_name, TilesetArtifact{tiles_png});
218 if (artifact_exists(tiles_png_key)) {
219 result.push_back(tiles_png_key);
220 }
221
222 // TODO: don't hardcode this num_pals value
223 // TODO: warn user if we found pals like 1.pal, these won't work they have to be 01.pal
224 constexpr int num_pals = 16;
225 for (unsigned int i = 0; i < num_pals; i++) {
226 const auto pal_key = key_for(tileset_name, TilesetArtifact{pal_n, i});
227 if (artifact_exists(pal_key)) {
228 result.push_back(pal_key);
229 }
230 }
231
232 const auto porymap_anims = discover_porymap_anims(tileset_name);
233 for (const auto &anim : porymap_anims) {
234 const auto frame_00_key = key_for(tileset_name, TilesetArtifact{porymap_anim_frame, anim, 0});
235 if (artifact_exists(frame_00_key)) {
236 result.push_back(frame_00_key);
237 }
238 const auto frames = discover_porymap_anim_frames(tileset_name, anim);
239 for (const auto &frame : frames) {
240 const auto frame_n_key = key_for(tileset_name, TilesetArtifact{porymap_anim_frame, anim, frame});
241 if (artifact_exists(frame_n_key)) {
242 result.push_back(frame_n_key);
243 }
244 }
245 }
246
247 return result;
248 }
249
261 [[nodiscard]] virtual std::vector<ArtifactKey> get_all_artifact_keys(const std::string &tileset_name) const
262 {
263 const auto porytiles_keys = get_porytiles_artifact_keys(tileset_name);
264 const auto porymap_keys = get_porymap_artifact_keys(tileset_name);
265
266 std::vector<ArtifactKey> result;
267 result.reserve(porytiles_keys.size() + porymap_keys.size());
268 result.insert(result.end(), porytiles_keys.begin(), porytiles_keys.end());
269 result.insert(result.end(), porymap_keys.begin(), porymap_keys.end());
270
271 return result;
272 }
273};
274
275} // namespace porytiles2
A type-safe wrapper for artifact keys.
Abstract interface for generating keys and discovering tileset artifacts in a backing store.
virtual std::vector< ArtifactKey > get_porymap_artifact_keys(const std::string &tileset_name) const
Gets the keys for all Porymap artifacts present in the given Tileset.
virtual std::set< int > discover_porytiles_anim_frames(const std::string &tileset_name, const std::string &anim_name) const =0
Discovers the frame indices for a specific Porytiles animation.
virtual ArtifactKey key_for(const std::string &tileset_name, const TilesetArtifact &artifact) const =0
Constructs a key for a given tileset artifact.
virtual std::vector< ArtifactKey > get_all_artifact_keys(const std::string &tileset_name) const
Gets the keys for all tileset artifacts (both Porytiles and Porymap) present in the given Tileset.
virtual bool artifact_exists(const ArtifactKey &key) const =0
Checks whether an artifact exists in the backing store for the given key.
virtual std::set< int > discover_porymap_anim_frames(const std::string &tileset_name, const std::string &anim_name) const =0
Discovers the frame indices for a specific Porymap animation.
virtual bool tileset_exists(const std::string &tileset_name) const =0
Checks whether a tileset exists in the backing store for the given tileset name.
virtual std::vector< ArtifactKey > get_porytiles_artifact_keys(const std::string &tileset_name) const
Gets the keys for all Porytiles artifacts present in the given Tileset.
virtual ~TilesetArtifactKeyProvider()=default
virtual std::set< std::string > discover_porymap_anims(const std::string &tileset_name) const =0
Discovers the names of all Porymap animations available for a tileset.
virtual std::set< std::string > discover_porytiles_anims(const std::string &tileset_name) const =0
Discovers the names of all Porytiles animations available for a tileset.
Represents a Pokémon Generation III decomp tileset artifact with type and optional metadata.
Type
Enumeration of all supported tileset artifact types.
constexpr std::size_t num_pals