feat: add resolveItemId and resolveBlockId to DataPack
This commit is contained in:
1 parent
570172c86d
commit
4423e6c2b3
1 file changed
+159
@@ -157,3 +157,162 @@ bool readCountRange(const JsonValue& owner, const std::string& key, int& minOut,
|
||||
|
||||
} // namespace
|
||||
|
||||
ResourceId::ResourceId(std::string space, std::string path)
|
||||
: space(std::move(space)), path(std::move(path)) {}
|
||||
|
||||
bool ResourceId::validSpace(const std::string& text) {
|
||||
if (text.empty()) return false;
|
||||
for (char c : text) {
|
||||
bool ok = (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_' || c == '-' ||
|
||||
c == '.';
|
||||
if (!ok) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ResourceId::validPath(const std::string& text) {
|
||||
if (text.empty()) return false;
|
||||
if (text.front() == '/' || text.back() == '/') return false;
|
||||
for (char c : text) {
|
||||
bool ok = (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_' || c == '-' ||
|
||||
c == '.' || c == '/';
|
||||
if (!ok) return false;
|
||||
}
|
||||
return text.find("//") == std::string::npos;
|
||||
}
|
||||
|
||||
bool ResourceId::parse(const std::string& text, const std::string& defaultSpace, ResourceId& out) {
|
||||
std::size_t colon = text.find(':');
|
||||
if (colon == std::string::npos) {
|
||||
out = ResourceId(defaultSpace, text);
|
||||
} else {
|
||||
if (text.find(':', colon + 1u) != std::string::npos) return false;
|
||||
out = ResourceId(text.substr(0, colon), text.substr(colon + 1u));
|
||||
}
|
||||
return out.valid();
|
||||
}
|
||||
|
||||
bool resolveItemId(const ResourceId& id, ItemId& out) {
|
||||
if (!id.valid()) return false;
|
||||
return parseItemName(loweredWithoutSeparators(id.path), out);
|
||||
}
|
||||
|
||||
bool resolveBlockId(const ResourceId& id, Block& out) {
|
||||
if (!id.valid()) return false;
|
||||
return parseBlockName(loweredWithoutSeparators(id.path), out);
|
||||
}
|
||||
|
||||
bool DataPackMeta::fromJson(const JsonValue& root, DataPackMeta& out, std::string& problem) {
|
||||
if (!root.isObject()) {
|
||||
problem = "pack metadata must be an object";
|
||||
return false;
|
||||
}
|
||||
const JsonValue* name = root.find("name");
|
||||
if (name == nullptr || !name->isString() || name->stringValue().empty()) {
|
||||
problem = "\"name\" must be a non empty string";
|
||||
return false;
|
||||
}
|
||||
DataPackMeta parsed;
|
||||
parsed.name = name->stringValue();
|
||||
parsed.description = root.stringOr("description", "");
|
||||
parsed.formatVersion = static_cast<int>(root.intOr("formatVersion", 1));
|
||||
parsed.priority = static_cast<int>(root.intOr("priority", 0));
|
||||
parsed.defaultSpace = root.stringOr("defaultSpace", "voxelforge");
|
||||
if (parsed.formatVersion < 1) {
|
||||
problem = "\"formatVersion\" must be at least 1";
|
||||
return false;
|
||||
}
|
||||
if (!ResourceId::validSpace(parsed.defaultSpace)) {
|
||||
problem = "\"defaultSpace\" is not a valid namespace: " + parsed.defaultSpace;
|
||||
return false;
|
||||
}
|
||||
out = parsed;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string DataPackError::text() const {
|
||||
std::string out = pack.empty() ? file : pack + "/" + file;
|
||||
if (line > 0) out += ":" + std::to_string(line) + ":" + std::to_string(column);
|
||||
return out + ": " + reason;
|
||||
}
|
||||
|
||||
void DataPack::addFile(const std::string& path, std::string contents) {
|
||||
files[path] = std::move(contents);
|
||||
}
|
||||
|
||||
bool DataPack::removeFile(const std::string& path) { return files.erase(path) > 0u; }
|
||||
|
||||
bool DataPack::hasFile(const std::string& path) const { return files.count(path) > 0u; }
|
||||
|
||||
const std::string* DataPack::fileContents(const std::string& path) const {
|
||||
auto found = files.find(path);
|
||||
return found == files.end() ? nullptr : &found->second;
|
||||
}
|
||||
|
||||
std::vector<std::string> DataPack::filesUnder(const std::string& prefix) const {
|
||||
std::vector<std::string> out;
|
||||
for (const auto& entry : files)
|
||||
if (entry.first.compare(0, prefix.size(), prefix) == 0) out.push_back(entry.first);
|
||||
return out;
|
||||
}
|
||||
|
||||
std::vector<std::string> DataPack::allFiles() const {
|
||||
std::vector<std::string> out;
|
||||
out.reserve(files.size());
|
||||
for (const auto& entry : files) out.push_back(entry.first);
|
||||
return out;
|
||||
}
|
||||
|
||||
ShapedRecipe RecipeData::toShaped() const {
|
||||
ShapedRecipe out;
|
||||
out.width = width;
|
||||
out.height = height;
|
||||
out.pattern = pattern;
|
||||
out.allowMirror = allowMirror;
|
||||
out.result.item = resultItem;
|
||||
out.result.count = resultCount;
|
||||
return out;
|
||||
}
|
||||
|
||||
ShapelessRecipe RecipeData::toShapeless() const {
|
||||
ShapelessRecipe out;
|
||||
out.ingredients = ingredients;
|
||||
out.result.item = resultItem;
|
||||
out.result.count = resultCount;
|
||||
return out;
|
||||
}
|
||||
|
||||
SmeltingRecipe RecipeData::toSmelting() const {
|
||||
SmeltingRecipe out;
|
||||
out.input = smeltInput;
|
||||
out.smeltSeconds = smeltSeconds;
|
||||
out.result.item = resultItem;
|
||||
out.result.count = resultCount;
|
||||
return out;
|
||||
}
|
||||
|
||||
bool BlockTag::contains(const ResourceId& member) const {
|
||||
for (const Entry& entry : entries)
|
||||
if (!entry.reference && entry.id == member) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void TagRegistry::define(const BlockTag& tag) {
|
||||
auto found = tags.find(tag.id);
|
||||
if (found == tags.end() || tag.replace) {
|
||||
tags[tag.id] = tag;
|
||||
return;
|
||||
}
|
||||
BlockTag& existing = found->second;
|
||||
for (const BlockTag::Entry& entry : tag.entries) {
|
||||
bool already = false;
|
||||
for (const BlockTag::Entry& present : existing.entries)
|
||||
if (present == entry) already = true;
|
||||
if (!already) existing.entries.push_back(entry);
|
||||
}
|
||||
}
|
||||
|
||||
void TagRegistry::clear() { tags.clear(); }
|
||||
|
||||
bool TagRegistry::has(const ResourceId& id) const { return tags.count(id) > 0u; }
|
||||
|
||||
Reference in new issue
Block a user