Beispiel #1
0
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);
    }
}
Beispiel #3
0
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);
        }
    }
}
Beispiel #4
0
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);
    }
}