From 02a86d761aa51e6ec54d179f931fc57b073a2765 Mon Sep 17 00:00:00 2001 From: myk002 Date: Thu, 12 Nov 2020 19:10:06 -0800 Subject: [PATCH 1/7] identify bars as non_economic items allows Job::isSuitableMaterial() to match metal bars as a building material --- library/include/modules/Job.h | 2 +- library/include/modules/Materials.h | 5 +++-- library/modules/Job.cpp | 5 +++-- library/modules/Materials.cpp | 9 ++++++--- plugins/buildingplan-planner.cpp | 3 ++- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/library/include/modules/Job.h b/library/include/modules/Job.h index cde5c64dd..4312b7b4e 100644 --- a/library/include/modules/Job.h +++ b/library/include/modules/Job.h @@ -102,7 +102,7 @@ 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 = df::item_type::NONE); DFHACK_EXPORT std::string getName(df::job *job); } diff --git a/library/include/modules/Materials.h b/library/include/modules/Materials.h index a3b4204e5..b438a0cdb 100644 --- a/library/include/modules/Materials.h +++ b/library/include/modules/Materials.h @@ -78,6 +78,7 @@ namespace DFHack int16_t type; int32_t index; + df::item_type itype; df::material *material; @@ -98,7 +99,7 @@ namespace DFHack df::historical_figure *figure; public: - MaterialInfo(int16_t type = -1, int32_t index = -1) { decode(type, index); } + MaterialInfo(int16_t type = -1, int32_t index = -1, df::item_type itype = df::item_type::NONE) { decode(type, index, itype); } MaterialInfo(const t_matpair &mp) { decode(mp.mat_type, mp.mat_index); } template MaterialInfo(T *ptr) { decode(ptr); } @@ -113,7 +114,7 @@ namespace DFHack bool isAnyInorganic() const { return type == 0; } bool isInorganicWildcard() const { return isAnyInorganic() && isBuiltin(); } - bool decode(int16_t type, int32_t index = -1); + bool decode(int16_t type, int32_t index = -1, df::item_type itype = df::item_type::NONE); bool decode(df::item *item); bool decode(const df::material_vec_ref &vr, int idx); bool decode(const t_matpair &mp) { return decode(mp.mat_type, mp.mat_index); } diff --git a/library/modules/Job.cpp b/library/modules/Job.cpp index 0aa01af95..9e04e1a30 100644 --- a/library/modules/Job.cpp +++ b/library/modules/Job.cpp @@ -608,7 +608,8 @@ bool Job::isSuitableItem(df::job_item *item, df::item_type itype, int isubtype) return iinfo.isValid() && iinfo.matches(*item, &minfo); } -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); @@ -616,7 +617,7 @@ bool Job::isSuitableMaterial(df::job_item *item, int mat_type, int mat_index) return true; ItemTypeInfo iinfo(item); - MaterialInfo minfo(mat_type, mat_index); + MaterialInfo minfo(mat_type, mat_index, itype); return minfo.isValid() && iinfo.matches(*item, &minfo); } diff --git a/library/modules/Materials.cpp b/library/modules/Materials.cpp index 909fa56f9..e3a4bf23f 100644 --- a/library/modules/Materials.cpp +++ b/library/modules/Materials.cpp @@ -75,7 +75,9 @@ bool MaterialInfo::decode(df::item *item) if (!item) return decode(-1); else - return decode(item->getActualMaterial(), item->getActualMaterialIndex()); + return decode(item->getActualMaterial(), + item->getActualMaterialIndex(), + item->getType()); } bool MaterialInfo::decode(const df::material_vec_ref &vr, int idx) @@ -86,10 +88,11 @@ bool MaterialInfo::decode(const df::material_vec_ref &vr, int idx) return decode(vr.mat_type[idx], vr.mat_index[idx]); } -bool MaterialInfo::decode(int16_t type, int32_t index) +bool MaterialInfo::decode(int16_t type, int32_t index, df::item_type itype) { this->type = type; this->index = index; + this->itype = itype; material = NULL; mode = Builtin; subtype = 0; @@ -513,7 +516,7 @@ void MaterialInfo::getMatchBits(df::job_item_flags2 &ok, df::job_item_flags2 &ma TEST(fire_safe, material->heat.melting_point > 11000); TEST(magma_safe, material->heat.melting_point > 12000); TEST(deep_material, FLAG(inorganic, inorganic_flags::SPECIAL)); - TEST(non_economic, !inorganic || !(ui && vector_get(ui->economic_stone, index))); + TEST(non_economic, !inorganic || !(ui && vector_get(ui->economic_stone, index)) || itype == df::item_type::BAR); TEST(plant, plant); TEST(silk, MAT_FLAG(SILK)); 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); } From 6b14a92385535027dc15983ba37ca402d3ded066 Mon Sep 17 00:00:00 2001 From: myk002 Date: Thu, 12 Nov 2020 19:54:00 -0800 Subject: [PATCH 2/7] allow buildingplan to match metal bars --- plugins/buildingplan-planner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/buildingplan-planner.cpp b/plugins/buildingplan-planner.cpp index 7aad342e5..b06ce7f84 100644 --- a/plugins/buildingplan-planner.cpp +++ b/plugins/buildingplan-planner.cpp @@ -224,7 +224,7 @@ bool ItemFilter::matches(df::item *item) const auto imattype = item->getActualMaterial(); auto imatindex = item->getActualMaterialIndex(); - auto item_mat = DFHack::MaterialInfo(imattype, imatindex); + auto item_mat = DFHack::MaterialInfo(imattype, imatindex, item->getType()); return (materials.size() == 0) ? matchesMask(item_mat) : matches(item_mat); } From 10616a387fcc8b5351e7cb24fbb5ee11caed99a0 Mon Sep 17 00:00:00 2001 From: myk002 Date: Thu, 12 Nov 2020 22:44:38 -0800 Subject: [PATCH 3/7] cleaner mask-based implementation --- library/include/modules/Items.h | 4 +++- library/include/modules/Job.h | 4 +++- library/include/modules/Materials.h | 8 ++++---- library/modules/Items.cpp | 5 +++-- library/modules/Job.cpp | 6 +++--- library/modules/Materials.cpp | 16 ++++++++-------- plugins/buildingplan-planner.cpp | 2 +- 7 files changed, 25 insertions(+), 20 deletions(-) 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 4312b7b4e..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, df::item_type itype = df::item_type::NONE); + 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 b438a0cdb..3217b30ad 100644 --- a/library/include/modules/Materials.h +++ b/library/include/modules/Materials.h @@ -78,7 +78,6 @@ namespace DFHack int16_t type; int32_t index; - df::item_type itype; df::material *material; @@ -99,7 +98,7 @@ namespace DFHack df::historical_figure *figure; public: - MaterialInfo(int16_t type = -1, int32_t index = -1, df::item_type itype = df::item_type::NONE) { decode(type, index, itype); } + MaterialInfo(int16_t type = -1, int32_t index = -1) { decode(type, index); } MaterialInfo(const t_matpair &mp) { decode(mp.mat_type, mp.mat_index); } template MaterialInfo(T *ptr) { decode(ptr); } @@ -114,7 +113,7 @@ namespace DFHack bool isAnyInorganic() const { return type == 0; } bool isInorganicWildcard() const { return isAnyInorganic() && isBuiltin(); } - bool decode(int16_t type, int32_t index = -1, df::item_type itype = df::item_type::NONE); + bool decode(int16_t type, int32_t index = -1); bool decode(df::item *item); bool decode(const df::material_vec_ref &vr, int idx); bool decode(const t_matpair &mp) { return decode(mp.mat_type, mp.mat_index); } @@ -157,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 9e04e1a30..366384fd2 100644 --- a/library/modules/Job.cpp +++ b/library/modules/Job.cpp @@ -605,7 +605,7 @@ 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, true, itype); } bool Job::isSuitableMaterial( @@ -617,9 +617,9 @@ bool Job::isSuitableMaterial( return true; ItemTypeInfo iinfo(item); - MaterialInfo minfo(mat_type, mat_index, itype); + MaterialInfo minfo(mat_type, mat_index); - return minfo.isValid() && iinfo.matches(*item, &minfo); + return minfo.isValid() && iinfo.matches(*item, &minfo, true, itype); } std::string Job::getName(df::job *job) diff --git a/library/modules/Materials.cpp b/library/modules/Materials.cpp index e3a4bf23f..56a13fbe2 100644 --- a/library/modules/Materials.cpp +++ b/library/modules/Materials.cpp @@ -76,8 +76,7 @@ bool MaterialInfo::decode(df::item *item) return decode(-1); else return decode(item->getActualMaterial(), - item->getActualMaterialIndex(), - item->getType()); + item->getActualMaterialIndex()); } bool MaterialInfo::decode(const df::material_vec_ref &vr, int idx) @@ -88,11 +87,10 @@ bool MaterialInfo::decode(const df::material_vec_ref &vr, int idx) return decode(vr.mat_type[idx], vr.mat_index[idx]); } -bool MaterialInfo::decode(int16_t type, int32_t index, df::item_type itype) +bool MaterialInfo::decode(int16_t type, int32_t index) { this->type = type; this->index = index; - this->itype = itype; material = NULL; mode = Builtin; subtype = 0; @@ -447,19 +445,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); @@ -516,8 +517,7 @@ void MaterialInfo::getMatchBits(df::job_item_flags2 &ok, df::job_item_flags2 &ma TEST(fire_safe, material->heat.melting_point > 11000); TEST(magma_safe, material->heat.melting_point > 12000); TEST(deep_material, FLAG(inorganic, inorganic_flags::SPECIAL)); - TEST(non_economic, !inorganic || !(ui && vector_get(ui->economic_stone, index)) || itype == df::item_type::BAR); - + TEST(non_economic, !inorganic || !(ui && vector_get(ui->economic_stone, index))); TEST(plant, plant); TEST(silk, MAT_FLAG(SILK)); TEST(leather, MAT_FLAG(LEATHER)); diff --git a/plugins/buildingplan-planner.cpp b/plugins/buildingplan-planner.cpp index b06ce7f84..7aad342e5 100644 --- a/plugins/buildingplan-planner.cpp +++ b/plugins/buildingplan-planner.cpp @@ -224,7 +224,7 @@ bool ItemFilter::matches(df::item *item) const auto imattype = item->getActualMaterial(); auto imatindex = item->getActualMaterialIndex(); - auto item_mat = DFHack::MaterialInfo(imattype, imatindex, item->getType()); + auto item_mat = DFHack::MaterialInfo(imattype, imatindex); return (materials.size() == 0) ? matchesMask(item_mat) : matches(item_mat); } From fa126af1fda83a3aa04c73857f0407506cd121bb Mon Sep 17 00:00:00 2001 From: myk002 Date: Thu, 12 Nov 2020 22:49:06 -0800 Subject: [PATCH 4/7] undo unnecessary edits --- library/modules/Materials.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/modules/Materials.cpp b/library/modules/Materials.cpp index 56a13fbe2..91bb5dc36 100644 --- a/library/modules/Materials.cpp +++ b/library/modules/Materials.cpp @@ -75,8 +75,7 @@ bool MaterialInfo::decode(df::item *item) if (!item) return decode(-1); else - return decode(item->getActualMaterial(), - item->getActualMaterialIndex()); + return decode(item->getActualMaterial(), item->getActualMaterialIndex()); } bool MaterialInfo::decode(const df::material_vec_ref &vr, int idx) @@ -518,6 +517,7 @@ void MaterialInfo::getMatchBits(df::job_item_flags2 &ok, df::job_item_flags2 &ma TEST(magma_safe, material->heat.melting_point > 12000); TEST(deep_material, FLAG(inorganic, inorganic_flags::SPECIAL)); TEST(non_economic, !inorganic || !(ui && vector_get(ui->economic_stone, index))); + TEST(plant, plant); TEST(silk, MAT_FLAG(SILK)); TEST(leather, MAT_FLAG(LEATHER)); From 93d9ac76be4d50654c0bc98a4869e8eef9a4d6eb Mon Sep 17 00:00:00 2001 From: myk002 Date: Thu, 12 Nov 2020 23:08:22 -0800 Subject: [PATCH 5/7] update docs --- docs/Lua API.rst | 2 +- docs/changelog.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index e017e0a8c..24887cd58 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 79179ce5e..ac2e6b55f 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -50,6 +50,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## API - `buildingplan`: added Lua interface API +- `job-module`: 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 From 54eec5d47fa4e0bf962bba92ffec0dd3957be523 Mon Sep 17 00:00:00 2001 From: myk002 Date: Thu, 12 Nov 2020 23:11:55 -0800 Subject: [PATCH 6/7] there is no job-module -- it's just an html anchor --- docs/changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index ac2e6b55f..4cb325f49 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -50,7 +50,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## API - `buildingplan`: added Lua interface API -- `job-module`: 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) +- 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 From 76e8c495fe3c487f1cc32e35b36b701f981953a8 Mon Sep 17 00:00:00 2001 From: myk002 Date: Fri, 13 Nov 2020 10:45:53 -0800 Subject: [PATCH 7/7] revert skip_vector=true for now --- library/modules/Job.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/modules/Job.cpp b/library/modules/Job.cpp index 366384fd2..4feb33bad 100644 --- a/library/modules/Job.cpp +++ b/library/modules/Job.cpp @@ -605,7 +605,7 @@ 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, true, itype); + return iinfo.isValid() && iinfo.matches(*item, &minfo, false, itype); } bool Job::isSuitableMaterial( @@ -619,7 +619,7 @@ bool Job::isSuitableMaterial( ItemTypeInfo iinfo(item); MaterialInfo minfo(mat_type, mat_index); - return minfo.isValid() && iinfo.matches(*item, &minfo, true, itype); + return minfo.isValid() && iinfo.matches(*item, &minfo, false, itype); } std::string Job::getName(df::job *job)