diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 80fd0add6..6c4b7052e 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -1132,7 +1132,7 @@ Job module Does basic sanity checks to verify if the suggested item type matches the flags in the job item. -* ``dfhack.job.isSuitableMaterial(job_item, mat_type, mat_index)`` +* ``dfhack.job.isSuitableMaterial(job_item, mat_type, mat_index, item_type)`` Likewise, if replacing material. diff --git a/docs/changelog.txt b/docs/changelog.txt index 9cbecf9ec..ff74fd80f 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -51,6 +51,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## API - `buildingplan`: added Lua interface API +- add item type param to dfhack.job.isSuitableMaterial() so the non_economic flag can be properly handled (it was being matched for all item types instead of just boulders) # 0.47.04-r3 diff --git a/library/include/modules/Items.h b/library/include/modules/Items.h index 33feea222..66ca9d1cf 100644 --- a/library/include/modules/Items.h +++ b/library/include/modules/Items.h @@ -88,7 +88,9 @@ namespace DFHack bool find(const std::string &token); bool matches(df::job_item_vector_id vec_id); - bool matches(const df::job_item &item, MaterialInfo *mat = NULL, bool skip_vector = false); + bool matches(const df::job_item &item, MaterialInfo *mat = NULL, + bool skip_vector = false, + df::item_type itype = df::item_type::NONE); }; inline bool operator== (const ItemTypeInfo &a, const ItemTypeInfo &b) { diff --git a/library/include/modules/Job.h b/library/include/modules/Job.h index cde5c64dd..e2d7ff162 100644 --- a/library/include/modules/Job.h +++ b/library/include/modules/Job.h @@ -102,7 +102,9 @@ namespace DFHack int filter_idx = -1, int insert_idx = -1); DFHACK_EXPORT bool isSuitableItem(df::job_item *item, df::item_type itype, int isubtype); - DFHACK_EXPORT bool isSuitableMaterial(df::job_item *item, int mat_type, int mat_index); + DFHACK_EXPORT bool isSuitableMaterial(df::job_item *item, int mat_type, + int mat_index, + df::item_type itype); DFHACK_EXPORT std::string getName(df::job *job); } diff --git a/library/include/modules/Materials.h b/library/include/modules/Materials.h index a3b4204e5..3217b30ad 100644 --- a/library/include/modules/Materials.h +++ b/library/include/modules/Materials.h @@ -156,7 +156,8 @@ namespace DFHack bool matches(const df::job_material_category &cat); bool matches(const df::dfhack_material_category &cat); - bool matches(const df::job_item &item); + bool matches(const df::job_item &item, + df::item_type itype = df::item_type::NONE); }; DFHACK_EXPORT bool parseJobMaterialCategory(df::job_material_category *cat, const std::string &token); diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index 3bc468d04..fa8607638 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -279,12 +279,13 @@ bool ItemTypeInfo::matches(df::job_item_vector_id vec_id) return true; } -bool ItemTypeInfo::matches(const df::job_item &item, MaterialInfo *mat, bool skip_vector) +bool ItemTypeInfo::matches(const df::job_item &item, MaterialInfo *mat, + bool skip_vector, df::item_type itype) { using namespace df::enums::item_type; if (!isValid()) - return mat ? mat->matches(item) : false; + return mat ? mat->matches(item, itype) : false; if (Items::isCasteMaterial(type) && mat && !mat->isNone()) return false; diff --git a/library/modules/Job.cpp b/library/modules/Job.cpp index 0aa01af95..4feb33bad 100644 --- a/library/modules/Job.cpp +++ b/library/modules/Job.cpp @@ -605,10 +605,11 @@ bool Job::isSuitableItem(df::job_item *item, df::item_type itype, int isubtype) ItemTypeInfo iinfo(itype, isubtype); MaterialInfo minfo(item); - return iinfo.isValid() && iinfo.matches(*item, &minfo); + return iinfo.isValid() && iinfo.matches(*item, &minfo, false, itype); } -bool Job::isSuitableMaterial(df::job_item *item, int mat_type, int mat_index) +bool Job::isSuitableMaterial( + df::job_item *item, int mat_type, int mat_index, df::item_type itype) { CHECK_NULL_POINTER(item); @@ -618,7 +619,7 @@ bool Job::isSuitableMaterial(df::job_item *item, int mat_type, int mat_index) ItemTypeInfo iinfo(item); MaterialInfo minfo(mat_type, mat_index); - return minfo.isValid() && iinfo.matches(*item, &minfo); + return minfo.isValid() && iinfo.matches(*item, &minfo, false, itype); } std::string Job::getName(df::job *job) diff --git a/library/modules/Materials.cpp b/library/modules/Materials.cpp index 909fa56f9..91bb5dc36 100644 --- a/library/modules/Materials.cpp +++ b/library/modules/Materials.cpp @@ -444,19 +444,22 @@ bool MaterialInfo::matches(const df::dfhack_material_category &cat) #undef TEST -bool MaterialInfo::matches(const df::job_item &item) +bool MaterialInfo::matches(const df::job_item &item, df::item_type itype) { if (!isValid()) return false; df::job_item_flags1 ok1, mask1; getMatchBits(ok1, mask1); - df::job_item_flags2 ok2, mask2; + df::job_item_flags2 ok2, mask2, xmask2; getMatchBits(ok2, mask2); df::job_item_flags3 ok3, mask3; getMatchBits(ok3, mask3); + xmask2.bits.non_economic = itype != df::item_type::BOULDER; + mask2.whole &= ~xmask2.whole; + return bits_match(item.flags1.whole, ok1.whole, mask1.whole) && bits_match(item.flags2.whole, ok2.whole, mask2.whole) && bits_match(item.flags3.whole, ok3.whole, mask3.whole); diff --git a/plugins/buildingplan-planner.cpp b/plugins/buildingplan-planner.cpp index 834465275..7aad342e5 100644 --- a/plugins/buildingplan-planner.cpp +++ b/plugins/buildingplan-planner.cpp @@ -825,7 +825,8 @@ static bool matchesFilters(df::item * item, return DFHack::Job::isSuitableItem( job_item, item->getType(), item->getSubtype()) && DFHack::Job::isSuitableMaterial( - job_item, item->getMaterial(), item->getMaterialIndex()) + job_item, item->getMaterial(), item->getMaterialIndex(), + item->getType()) && item_filter.matches(item); }