static void mark_all_in_stockpiles(vector<PersistentStockpileInfo> &stockpiles) { // Precompute a bitmask with the bad flags df::item_flags bad_flags; bad_flags.whole = 0; #define F(x) bad_flags.bits.x = true; F(dump); F(forbid); F(garbage_collect); F(hostile); F(on_fire); F(rotten); F(trader); F(in_building); F(construction); F(artifact); F(spider_web); F(owned); F(in_job); #undef F size_t marked_count = 0; for (auto it = stockpiles.begin(); it != stockpiles.end(); it++) { if (!it->isValid()) continue; auto spid = it->getId(); Buildings::StockpileIterator stored; for (stored.begin(it->getStockpile()); !stored.done(); ++stored) { marked_count += mark_item(*stored, bad_flags, spid); } } if (marked_count) Gui::showAnnouncement("Marked " + int_to_string(marked_count) + " items to melt", COLOR_GREEN, false); }
void Buildings::getStockpileContents(df::building_stockpilest *stockpile, std::vector<df::item*> *items) { CHECK_NULL_POINTER(stockpile); items->clear(); Buildings::StockpileIterator stored; for (stored.begin(stockpile); !stored.done(); ++stored) { df::item *item = *stored; items->push_back(item); } }
void create_jobs() { // Creates jobs in Jeweler's Workshops as necessary. // Todo: Consider path availability? std::set<item_id> stockpiled; std::set<df::building_workshopst*> unlinked; gem_map available; auto workshops = &world->buildings.other[df::buildings_other_id::WORKSHOP_JEWELER]; for (auto w = workshops->begin(); w != workshops->end(); ++w) { auto workshop = virtual_cast<df::building_workshopst>(*w); auto links = workshop->links.take_from_pile; if (workshop->construction_stage < 3) { // Construction in progress. continue; } if (workshop->jobs.size() == 1 && workshop->jobs[0]->job_type == df::job_type::DestroyBuilding) { // Queued for destruction. continue; } if (links.size() > 0) { for (auto l = links.begin(); l != links.end() && workshop->jobs.size() <= MAX_WORKSHOP_JOBS; ++l) { auto stockpile = virtual_cast<df::building_stockpilest>(*l); gem_map piled; Buildings::StockpileIterator stored; for (stored.begin(stockpile); !stored.done(); ++stored) { auto item = *stored; if (valid_gem(item)) { stockpiled.insert(item->id); piled[item->getMaterialIndex()] += 1; } } // Decrement current jobs from all linked workshops, not just this one. auto outbound = stockpile->links.give_to_workshop; for (auto ws = outbound.begin(); ws != outbound.end(); ++ws) { auto shop = virtual_cast<df::building_workshopst>(*ws); for (auto j = shop->jobs.begin(); j != shop->jobs.end(); ++j) { auto job = *j; if (job->job_type == df::job_type::CutGems) { if (job->flags.bits.repeat) { piled[job->mat_index] = 0; } else { piled[job->mat_index] -= 1; } } } } add_tasks(piled, workshop); } } else { // Note which gem types have already been ordered to be cut. for (auto j = workshop->jobs.begin(); j != workshop->jobs.end(); ++j) { auto job = *j; if (job->job_type == df::job_type::CutGems) { available[job->mat_index] -= job->flags.bits.repeat? 100: 1; } } if (workshop->jobs.size() <= MAX_WORKSHOP_JOBS) { unlinked.insert(workshop); } } } if (unlinked.size() > 0) { // Count how many gems of each type are available to be cut. // Gems in stockpiles linked to specific workshops don't count. auto gems = world->items.other[items_other_id::ROUGH]; for (auto g = gems.begin(); g != gems.end(); ++g) { auto item = *g; if (valid_gem(item) && !stockpiled.count(item->id)) { available[item->getMaterialIndex()] += 1; } } for (auto w = unlinked.begin(); w != unlinked.end(); ++w) { add_tasks(available, *w); } } }
static void mark_all_in_stockpiles(vector<PersistentStockpileInfo> &stockpiles) { if (!depot_info.findDepot()) return; // Precompute a bitmask with the bad flags df::item_flags bad_flags; bad_flags.whole = 0; #define F(x) bad_flags.bits.x = true; F(dump); F(forbid); F(garbage_collect); F(hostile); F(on_fire); F(rotten); F(trader); F(in_building); F(construction); F(artifact); F(spider_web); F(owned); F(in_job); #undef F size_t marked_count = 0; size_t error_count = 0; for (auto it = stockpiles.begin(); it != stockpiles.end(); it++) { if (!it->isValid()) continue; Buildings::StockpileIterator stored; for (stored.begin(it->getStockpile()); !stored.done(); ++stored) { df::item *item = *stored; if (item->flags.whole & bad_flags.whole) continue; if (!is_valid_item(item)) continue; // In case of container, check contained items for mandates bool mandates_ok = true; vector<df::item*> contained_items; Items::getContainedItems(item, &contained_items); for (df::item *cit : contained_items) { if (!Items::checkMandates(cit)) { mandates_ok = false; break; } } if (!mandates_ok) continue; if (depot_info.assignItem(item)) { ++marked_count; } else { if (++error_count < 5) { Gui::showZoomAnnouncement(df::announcement_type::CANCEL_JOB, item->pos, "Cannot trade item from stockpile " + int_to_string(it->getId()), COLOR_RED, true); } } } } if (marked_count) Gui::showAnnouncement("Marked " + int_to_string(marked_count) + " items for trade", COLOR_GREEN, false); if (error_count >= 5) { Gui::showAnnouncement(int_to_string(error_count) + " items were not marked", COLOR_RED, true); } }