diff --git a/src/content/Content.cpp b/src/content/Content.cpp index 5ee68859..c0093491 100644 --- a/src/content/Content.cpp +++ b/src/content/Content.cpp @@ -35,13 +35,15 @@ Content::Content( UptrsMap blockMaterials, UptrsMap skeletons, ResourceIndicesSet resourceIndices, - dv::value defaults + dv::value defaults, + std::unordered_map tags ) : indices(std::move(indices)), packs(std::move(packs)), blockMaterials(std::move(blockMaterials)), skeletons(std::move(skeletons)), defaults(std::move(defaults)), + tags(std::move(tags)), blocks(std::move(blocks)), items(std::move(items)), entities(std::move(entities)), diff --git a/src/content/Content.hpp b/src/content/Content.hpp index 81e816b6..599d50fe 100644 --- a/src/content/Content.hpp +++ b/src/content/Content.hpp @@ -176,6 +176,7 @@ class Content { UptrsMap blockMaterials; UptrsMap skeletons; dv::value defaults = nullptr; + std::unordered_map tags; public: ContentUnitDefs blocks; ContentUnitDefs items; @@ -195,7 +196,8 @@ public: UptrsMap blockMaterials, UptrsMap skeletons, ResourceIndicesSet resourceIndices, - dv::value defaults + dv::value defaults, + std::unordered_map tags ); ~Content(); @@ -211,6 +213,14 @@ public: return defaults; } + int getTagIndex(const std::string& tag) const { + const auto& found = tags.find(tag); + if (found == tags.end()) { + return -1; + } + return found->second; + } + const rigging::SkeletonConfig* getSkeleton(const std::string& id) const; const rigging::SkeletonConfig& requireSkeleton(const std::string& id) const; const BlockMaterial* findBlockMaterial(const std::string& id) const; diff --git a/src/content/ContentBuilder.cpp b/src/content/ContentBuilder.cpp index 448adc27..84f2e688 100644 --- a/src/content/ContentBuilder.cpp +++ b/src/content/ContentBuilder.cpp @@ -29,7 +29,7 @@ std::unique_ptr ContentBuilder::build() { def.rt.id = blockDefsIndices.size(); def.rt.emissive = *reinterpret_cast(def.emission); for (const auto& tag : def.tags) { - def.rt.tags.push_back(tags.add(tag)); + def.rt.tags.insert(tags.add(tag)); } if (def.variants) { @@ -96,7 +96,8 @@ std::unique_ptr ContentBuilder::build() { std::move(blockMaterials), std::move(skeletons), std::move(resourceIndices), - std::move(defaults) + std::move(defaults), + std::move(tags.map) ); // Now, it's time to resolve foreign keys diff --git a/src/items/ItemDef.hpp b/src/items/ItemDef.hpp index 52ebd835..40e052b9 100644 --- a/src/items/ItemDef.hpp +++ b/src/items/ItemDef.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "data/dv.hpp" #include "typedefs.hpp" @@ -73,7 +74,7 @@ struct ItemDef { ItemFuncsSet funcsset {}; bool emissive = false; - std::vector tags; + std::set tags; } rt {}; ItemDef(const std::string& name); diff --git a/src/logic/scripting/lua/libs/libblock.cpp b/src/logic/scripting/lua/libs/libblock.cpp index 52e2931c..fd0496fe 100644 --- a/src/logic/scripting/lua/libs/libblock.cpp +++ b/src/logic/scripting/lua/libs/libblock.cpp @@ -698,6 +698,15 @@ static int l_reload_script(lua::State* L) { return 0; } +static int l_has_tag(lua::State* L) { + if (auto def = require_block(L)) { + auto tag = lua::require_string(L, 2); + const auto& tags = def->rt.tags; + return lua::pushboolean(L, tags.find(content->getTagIndex(tag)) != tags.end()); + } + return 0; +} + const luaL_Reg blocklib[] = { {"index", lua::wrap}, {"name", lua::wrap}, @@ -737,5 +746,6 @@ const luaL_Reg blocklib[] = { {"get_field", lua::wrap}, {"set_field", lua::wrap}, {"reload_script", lua::wrap}, + {"has_tag", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libs/libitem.cpp b/src/logic/scripting/lua/libs/libitem.cpp index d70a7211..b26e524c 100644 --- a/src/logic/scripting/lua/libs/libitem.cpp +++ b/src/logic/scripting/lua/libs/libitem.cpp @@ -108,6 +108,15 @@ static int l_reload_script(lua::State* L) { return 0; } +static int l_has_tag(lua::State* L) { + if (auto def = get_item_def(L, 1)) { + auto tag = lua::require_string(L, 2); + const auto& tags = def->rt.tags; + return lua::pushboolean(L, tags.find(content->getTagIndex(tag)) != tags.end()); + } + return 0; +} + const luaL_Reg itemlib[] = { {"index", lua::wrap}, {"name", lua::wrap}, @@ -121,5 +130,6 @@ const luaL_Reg itemlib[] = { {"emission", lua::wrap}, {"uses", lua::wrap}, {"reload_script", lua::wrap}, + {"has_tag", lua::wrap}, {NULL, NULL} }; diff --git a/src/voxels/Block.hpp b/src/voxels/Block.hpp index 3d5a86a9..707f6b8b 100644 --- a/src/voxels/Block.hpp +++ b/src/voxels/Block.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "data/dv.hpp" #include "maths/UVRegion.hpp" @@ -288,7 +289,7 @@ public: blockid_t surfaceReplacement = 0; - std::vector tags; + std::set tags; } rt {}; Block(const std::string& name);