boost::optional<reaction_task_t> find_automatic_reaction_task(const settler_ai_t &ai) { if (automatic_reactions.empty()) return boost::optional<reaction_task_t>{}; boost::optional<reaction_task_t> result; // Iterate through available reactions for (auto outerit=automatic_reactions.begin(); outerit != automatic_reactions.end(); ++outerit) { // Is the workshop busy? auto busy_finder = workshop_claimed.find(outerit->first); if (busy_finder == workshop_claimed.end()) { // Iterate available automatic reactions for (const std::string &reaction_name : outerit->second) { auto reaction = reaction_defs.find(reaction_name); if (reaction != reaction_defs.end()) { // Is the settler allowed to do this? int target_category = -1; if (reaction->second.skill == "Carpentry") { target_category = JOB_CARPENTRY; } else if (reaction->second.skill == "Masonry") { target_category = JOB_MASONRY; } if (target_category == -1 || ai.permitted_work[target_category]) { // Are the inputs available? bool available = true; std::vector<std::pair<std::size_t,bool>> components; for (auto &input : reaction->second.inputs) { const int n_available = available_items_by_reaction_input(input); if (n_available < input.quantity) { available = false; } else { // Claim an item and push its # to the list std::size_t item_id = claim_item_by_reaction_input(input); components.push_back(std::make_pair(item_id,false)); } } if (available) { // Components are available, build job and return it result = reaction_task_t{outerit->first, reaction->second.name, reaction->second.tag, components}; workshop_claimed.insert(outerit->first); return result; } else { for (auto comp : components) { unclaim_by_id(comp.first); } } } } } } } return result; }
Variant ini_get(boost::container::flat_set<std::string>& p) { ArrayInit ret(p.size(), ArrayInit::Map{}); auto idx = 0; for (auto& s : p) { ret.add(idx++, s); } return ret.toArray(); }
bool ini_on_update(const Variant& value, boost::container::flat_set<std::string>& p) { INI_ASSERT_ARR(value); for (ArrayIter iter(value.toArray()); iter; ++iter) { p.insert(iter.second().toString().toCppString()); } return true; }
bool ini_on_update(const folly::dynamic& value, boost::container::flat_set<std::string>& p) { INI_ASSERT_ARR(value); for (auto& v : value.values()) { p.insert(v.data()); } return true; }
void Hdf::configGet(boost::container::flat_set<std::string> &values) const { values.clear(); for (Hdf hdf = firstChild(); hdf.exists(); hdf = hdf.next()) { values.insert(hdf.configGetString("")); } }
void free_workshop(const std::size_t &id) { workshop_claimed.erase(id); }
boost::optional<reaction_task_t> find_queued_reaction_task(const settler_ai_t &ai) { if (designations->build_orders.empty()) return boost::optional<reaction_task_t>{}; boost::optional<reaction_task_t> result; // Iterate through queued jobs for (std::pair<uint8_t,std::string> &order : designations->build_orders) { auto reaction = reaction_defs.find(order.second); // Is there an available workshop of the right type? bool possible = false; std::size_t workshop_id; each<building_t>([&possible, &reaction, &workshop_id] (entity_t &e, building_t &b) { if (b.complete && b.tag == reaction->second.workshop) { auto busy_finder = workshop_claimed.find(e.id); if (busy_finder == workshop_claimed.end()) { workshop_id = e.id; possible = true; } } }); if (!possible) break; // Is the settler allowed to do this? int target_category = -1; if (reaction->second.skill == "Carpentry") { target_category = JOB_CARPENTRY; } else if (reaction->second.skill == "Masonry") { target_category = JOB_MASONRY; } if (target_category == -1 || ai.permitted_work[target_category]) { bool available = true; std::vector<std::pair<std::size_t,bool>> components; for (auto &input : reaction->second.inputs) { const int n_available = available_items_by_reaction_input(input); if (n_available < input.quantity) { available = false; } else { // Claim an item and push its # to the list std::size_t item_id = claim_item_by_reaction_input(input); components.push_back(std::make_pair(item_id,false)); } } if (available) { // Components are available, build job and return it result = reaction_task_t{workshop_id, reaction->second.name, reaction->second.tag, components}; workshop_claimed.insert(workshop_id); --order.first; emit(update_workflow_message{}); return result; } else { for (auto comp : components) { unclaim_by_id(comp.first); } } } } return result; }