static command_result workflow_cmd(color_ostream &out, vector <string> & parameters) { CoreSuspender suspend; if (!Core::getInstance().isWorldLoaded()) { out.printerr("World is not loaded: please load a game first.\n"); return CR_FAILURE; } if (enabled) { check_lost_jobs(out, 0); recover_jobs(out); update_job_data(out); map_job_constraints(out); map_job_items(out); } df::building *workshop = NULL; //FIXME: unused variable! //df::job *job = NULL; if (Gui::dwarfmode_hotkey(Core::getTopViewscreen()) && ui->main.mode == ui_sidebar_mode::QueryBuilding) { workshop = world->selected_building; //job = Gui::getSelectedWorkshopJob(out, true); } std::string cmd = parameters.empty() ? "list" : parameters[0]; if (cmd == "enable" || cmd == "disable") { bool enable = (cmd == "enable"); if (enable && !enabled) { enable_plugin(out); } else if (!enable && parameters.size() == 1) { if (enabled) { enabled = false; setOptionEnabled(CF_ENABLED, false); stop_protect(out); } out << "The plugin is disabled." << endl; return CR_OK; } for (size_t i = 1; i < parameters.size(); i++) { if (parameters[i] == "drybuckets") setOptionEnabled(CF_DRYBUCKETS, enable); else if (parameters[i] == "auto-melt") setOptionEnabled(CF_AUTOMELT, enable); else return CR_WRONG_USAGE; } if (enabled) out << "The plugin is enabled." << endl; else out << "The plugin is disabled." << endl; if (isOptionEnabled(CF_DRYBUCKETS)) out << "Option drybuckets is enabled." << endl; if (isOptionEnabled(CF_AUTOMELT)) out << "Option auto-melt is enabled." << endl; return CR_OK; } else if (cmd == "count" || cmd == "amount") { if (!enabled) enable_plugin(out); } if (!enabled) out << "Note: the plugin is not enabled." << endl; if (cmd == "jobs") { if (workshop) { for (size_t i = 0; i < workshop->jobs.size(); i++) print_job(out, get_known(workshop->jobs[i]->id)); } else { for (TKnownJobs::iterator it = known_jobs.begin(); it != known_jobs.end(); ++it) if (it->second->isLive()) print_job(out, it->second); } bool pending = false; for (size_t i = 0; i < pending_recover.size(); i++) { if (!workshop || pending_recover[i]->holder == workshop) { if (!pending) { out.print("\nPending recovery:\n"); pending = true; } Job::printJobDetails(out, pending_recover[i]->job_copy); } } return CR_OK; } else if (cmd == "list") { for (size_t i = 0; i < constraints.size(); i++) print_constraint(out, constraints[i]); return CR_OK; } else if (cmd == "list-commands") { for (size_t i = 0; i < constraints.size(); i++) { auto cv = constraints[i]; out << "workflow " << (cv->goalByCount() ? "count " : "amount ") << cv->config.val() << " " << cv->goalCount() << " " << cv->goalGap() << endl; } return CR_OK; } else if (cmd == "count" || cmd == "amount") { if (parameters.size() < 3) return CR_WRONG_USAGE; int limit = atoi(parameters[2].c_str()); if (limit <= 0) { out.printerr("Invalid limit value.\n"); return CR_FAILURE; } ItemConstraint *icv = get_constraint(out, parameters[1]); if (!icv) return CR_FAILURE; icv->setGoalByCount(cmd == "count"); icv->setGoalCount(limit); if (parameters.size() >= 4) icv->setGoalGap(atoi(parameters[3].c_str())); else icv->setGoalGap(-1); process_constraints(out); print_constraint(out, icv); return CR_OK; } else if (cmd == "unlimit") { if (parameters.size() != 2) return CR_WRONG_USAGE; for (size_t i = 0; i < constraints.size(); i++) { if (constraints[i]->config.val() != parameters[1]) continue; delete_constraint(constraints[i]); return CR_OK; } out.printerr("Constraint not found: %s\n", parameters[1].c_str()); return CR_FAILURE; } else if (cmd == "unlimit-all") { if (parameters.size() != 1) return CR_WRONG_USAGE; while (!constraints.empty()) delete_constraint(constraints[0]); out.print("Removed all constraints.\n"); return CR_OK; } else return CR_WRONG_USAGE; }
static ItemConstraint *get_constraint(color_ostream &out, const std::string &str, PersistentDataItem *cfg) { std::vector<std::string> tokens; split_string(&tokens, str, "/"); if (tokens.size() > 4) return NULL; int weight = 0; bool is_craft = false; ItemTypeInfo item; if (tokens[0] == "ANY_CRAFT" || tokens[0] == "CRAFTS") { is_craft = true; } else if (!item.find(tokens[0]) || !item.isValid()) { out.printerr("Cannot find item type: %s\n", tokens[0].c_str()); return NULL; } if (item.subtype >= 0) weight += 10000; df::dfhack_material_category mat_mask; std::string maskstr = vector_get(tokens,1); if (!maskstr.empty() && !parseJobMaterialCategory(&mat_mask, maskstr)) { out.printerr("Cannot decode material mask: %s\n", maskstr.c_str()); return NULL; } if (mat_mask.whole != 0) weight += 100; MaterialInfo material; std::string matstr = vector_get(tokens,2); if (!matstr.empty() && (!material.find(matstr) || !material.isValid())) { out.printerr("Cannot find material: %s\n", matstr.c_str()); return NULL; } item_quality::item_quality minqual = item_quality::Ordinary; std::string qualstr = vector_get(tokens, 3); if(!qualstr.empty()) { if(qualstr == "ordinary") minqual = item_quality::Ordinary; else if(qualstr == "wellcrafted") minqual = item_quality::WellCrafted; else if(qualstr == "finelycrafted") minqual = item_quality::FinelyCrafted; else if(qualstr == "superior") minqual = item_quality::Superior; else if(qualstr == "exceptional") minqual = item_quality::Exceptional; else if(qualstr == "masterful") minqual = item_quality::Masterful; else { out.printerr("Cannot find quality: %s\nKnown qualities: ordinary, wellcrafted, finelycrafted, superior, exceptional, masterful\n", qualstr.c_str()); return NULL; } } if (material.type >= 0) weight += (material.index >= 0 ? 5000 : 1000); if (mat_mask.whole && material.isValid() && !material.matches(mat_mask)) { out.printerr("Material %s doesn't match mask %s\n", matstr.c_str(), maskstr.c_str()); return NULL; } for (size_t i = 0; i < constraints.size(); i++) { ItemConstraint *ct = constraints[i]; if (ct->is_craft == is_craft && ct->item == item && ct->material == material && ct->mat_mask.whole == mat_mask.whole && ct->min_quality == minqual) return ct; } ItemConstraint *nct = new ItemConstraint; nct->is_craft = is_craft; nct->item = item; nct->material = material; nct->mat_mask = mat_mask; nct->min_quality = minqual; nct->weight = weight; if (cfg) nct->config = *cfg; else { nct->config = Core::getInstance().getWorld()->AddPersistentData("workflow/constraints"); nct->init(str); } constraints.push_back(nct); return nct; }
static ItemConstraint *get_constraint(Core *c, const std::string &str, PersistentDataItem *cfg) { std::vector<std::string> tokens; split_string(&tokens, str, "/"); if (tokens.size() > 3) return NULL; int weight = 0; ItemTypeInfo item; if (!item.find(tokens[0]) || !item.isValid()) { c->con.printerr("Cannot find item type: %s\n", tokens[0].c_str()); return NULL; } if (item.subtype >= 0) weight += 10000; df::dfhack_material_category mat_mask; std::string maskstr = vector_get(tokens,1); if (!maskstr.empty() && !parseJobMaterialCategory(&mat_mask, maskstr)) { c->con.printerr("Cannot decode material mask: %s\n", maskstr.c_str()); return NULL; } if (mat_mask.whole != 0) weight += 100; MaterialInfo material; std::string matstr = vector_get(tokens,2); if (!matstr.empty() && (!material.find(matstr) || !material.isValid())) { c->con.printerr("Cannot find material: %s\n", matstr.c_str()); return NULL; } if (material.type >= 0) weight += (material.index >= 0 ? 5000 : 1000); if (mat_mask.whole && material.isValid() && !material.matches(mat_mask)) { c->con.printerr("Material %s doesn't match mask %s\n", matstr.c_str(), maskstr.c_str()); return NULL; } for (size_t i = 0; i < constraints.size(); i++) { ItemConstraint *ct = constraints[i]; if (ct->item == item && ct->material == material && ct->mat_mask.whole == mat_mask.whole) return ct; } ItemConstraint *nct = new ItemConstraint; nct->item = item; nct->material = material; nct->mat_mask = mat_mask; nct->weight = weight; if (cfg) nct->config = *cfg; else { nct->config = c->getWorld()->AddPersistentData("workflow/constraints"); nct->init(str); } constraints.push_back(nct); return nct; }