| 375 | // |
| 376 | |
| 377 | static string getBucket(const df::job_item & ji, const PlannedBuilding & pb, int idx) { |
| 378 | if (idx < 0 || (size_t)idx >= pb.item_filters.size()) |
| 379 | return "INVALID"; |
| 380 | |
| 381 | std::ostringstream ser; |
| 382 | |
| 383 | // put elements in front that significantly affect the difficulty of matching |
| 384 | // the filter. ensure the lexicographically "less" value is the pickier value. |
| 385 | const ItemFilter & item_filter = pb.item_filters[idx]; |
| 386 | |
| 387 | if (item_filter.getDecoratedOnly()) |
| 388 | ser << "Da"; |
| 389 | else |
| 390 | ser << "Db"; |
| 391 | |
| 392 | if (ji.flags2.bits.magma_safe || pb.heat_safety == HEAT_SAFETY_MAGMA) |
| 393 | ser << "Ha"; |
| 394 | else if (ji.flags2.bits.fire_safe || pb.heat_safety == HEAT_SAFETY_FIRE) |
| 395 | ser << "Hb"; |
| 396 | else |
| 397 | ser << "Hc"; |
| 398 | |
| 399 | size_t num_materials = item_filter.getMaterials().size(); |
| 400 | if (num_materials == 0 || num_materials >= 9 || !item_filter.getMaterialMask().whole) |
| 401 | ser << "M9"; |
| 402 | else |
| 403 | ser << "M" << num_materials; |
| 404 | |
| 405 | // pull out and serialize only known relevant fields. if we miss a few, then |
| 406 | // the filter bucket will be slighly less specific than it could be, but |
| 407 | // that's probably ok. we'll just end up bucketing slightly different items |
| 408 | // together. this is only a problem if the different filter at the front of |
| 409 | // the queue doesn't match any available items and blocks filters behind it |
| 410 | // that could be matched. |
| 411 | ser << ji.item_type << ':' << ji.item_subtype << ':' << ji.mat_type << ':' |
| 412 | << ji.mat_index << ':' << ji.flags1.whole << ':' << ji.flags2.whole |
| 413 | << ':' << ji.flags3.whole << ':' << ji.flags4 << ':' << ji.flags5 << ':' |
| 414 | << ji.metal_ore << ':' << ji.has_tool_use; |
| 415 | |
| 416 | ser << ':' << item_filter.serialize(); |
| 417 | |
| 418 | for (auto &special : pb.specials) |
| 419 | ser << ':' << special; |
| 420 | |
| 421 | return ser.str(); |
| 422 | } |
| 423 | |
| 424 | // get a list of item vectors that we should search for matches |
| 425 | vector<df::job_item_vector_id> getVectorIds(color_ostream &out, const df::job_item *job_item, bool ignore_filters) { |
no test coverage detected