| 137 | } |
| 138 | |
| 139 | bool matchesFilters(df::item * item, const df::job_item * jitem, HeatSafety heat, const ItemFilter &item_filter, const std::set<string> &specials) { |
| 140 | // check the properties that are not checked by Job::isSuitableItem() |
| 141 | if (jitem->item_type > -1 && jitem->item_type != item->getType()) |
| 142 | return false; |
| 143 | |
| 144 | if (jitem->item_subtype > -1 && |
| 145 | jitem->item_subtype != item->getSubtype()) |
| 146 | return false; |
| 147 | |
| 148 | if (jitem->flags2.bits.building_material && !item->isBuildMat()) |
| 149 | return false; |
| 150 | |
| 151 | if ((jitem->flags1.bits.empty || jitem->flags2.bits.lye_milk_free)) { |
| 152 | auto gref = Items::getGeneralRef(item, df::general_ref_type::CONTAINS_ITEM); |
| 153 | if (gref) { |
| 154 | if (jitem->flags1.bits.empty) |
| 155 | return false; |
| 156 | if (auto contained_item = gref->getItem(); contained_item) { |
| 157 | MaterialInfo mi; |
| 158 | mi.decode(contained_item); |
| 159 | if (mi.getToken() != "WATER") |
| 160 | return false; |
| 161 | } |
| 162 | } |
| 163 | } |
| 164 | |
| 165 | if (jitem->metal_ore > -1 && !item->isMetalOre(jitem->metal_ore)) |
| 166 | return false; |
| 167 | |
| 168 | if (jitem->has_tool_use > df::tool_uses::NONE |
| 169 | && !item->hasToolUse(jitem->has_tool_use)) |
| 170 | return false; |
| 171 | |
| 172 | auto itype = item->getType(); |
| 173 | |
| 174 | if (itype == df::item_type::SLAB && specials.count("engraved") |
| 175 | && static_cast<df::item_slabst *>(item)->engraving_type != df::slab_engraving_type::Memorial) |
| 176 | return false; |
| 177 | |
| 178 | if (itype == df::item_type::CAGE && specials.count("empty") |
| 179 | && (Items::getGeneralRef(item, df::general_ref_type::CONTAINS_UNIT) |
| 180 | || Items::getGeneralRef(item, df::general_ref_type::CONTAINS_ITEM))) |
| 181 | return false; |
| 182 | |
| 183 | if (!matchesHeatSafety(item->getMaterial(), item->getMaterialIndex(), heat)) |
| 184 | return false; |
| 185 | |
| 186 | return Job::isSuitableItem(jitem, itype, item->getSubtype()) |
| 187 | && Job::isSuitableMaterial(jitem, item->getMaterial(), item->getMaterialIndex(), itype) |
| 188 | && item_filter.matches(item); |
| 189 | } |
| 190 | |
| 191 | bool isJobReady(color_ostream &out, const std::vector<df::job_item *> &jitems) { |
| 192 | int needed_items = 0; |