dfhack icon indicating copy to clipboard operation
dfhack copied to clipboard

dig-now neglects "active" jobs

Open cppcooper opened this issue 1 year ago • 0 comments

Active here does not mean the job necessarily has a worker. It means there is a job for the designation, which means the game has removed the designation information from the tile/block and moved it to the job*.

I wrote this as a means of checking if a designation is on the job list

class DigJobs {
private:
    std::unordered_map<df::coord, df::tile_dig_designation> designations;
    std::unordered_map<df::coord, df::job*> jobs;
public:
    void load() {
        designations.clear();
        df::job_list_link* node = df::global::world->jobs.list.next;
        while (node) {
            df::job* job = node->item;
            jobs.emplace(job->pos, job);
            node = node->next;
            switch (job->job_type){
                case df::enums::job_type::Dig:
                    designations.emplace(job->pos, df::tile_dig_designation::Default);
                    break;
                case df::enums::job_type::DigChannel:
                    designations.emplace(job->pos, df::tile_dig_designation::Channel);
                    break;
                case df::enums::job_type::CarveRamp:
                    designations.emplace(job->pos, df::tile_dig_designation::Ramp);
                    break;
                case df::enums::job_type::CarveUpwardStaircase:
                    designations.emplace(job->pos, df::tile_dig_designation::UpStair);
                    break;
                case df::enums::job_type::CarveDownwardStaircase:
                    designations.emplace(job->pos, df::tile_dig_designation::DownStair);
                    break;
                case df::enums::job_type::CarveUpDownStaircase:
                    designations.emplace(job->pos, df::tile_dig_designation::UpDownStair);
                    break;
                default:
                    break;
            }
        }
    }
    void remove(const df::coord &pos) {
        if(jobs.count(pos)) {
            Job::removeJob(jobs[pos]);
            auto block = Maps::getTileBlock(pos);
            auto local(pos);
            local.x %= 16;
            local.y %= 16;
#define Coord(id) id.x][id.y
            block->designation[Coord(local)].bits.dig = df::enums::tile_dig_designation::Default;
            block->flags.bits.designated = true;
        }
    }
    df::tile_dig_designation get(const df::coord &pos) {
        if (designations.count(pos)) {
            return designations[pos];
        }
        return df::enums::tile_dig_designation::No;
    }
};

With the following integration:

                if (jobs.get(pos) || (td.bits.dig != df::tile_dig_designation::No &&
                        !to.bits.dig_marked)) {
                    std::vector<dug_tile_info> dug_tiles;
                    auto designation = jobs.get(pos);
                    jobs.remove(pos);
                    if (designation == df::enums::tile_dig_designation::No) {
                        designation = td.bits.dig;
                    }
                    if (dig_tile(out, map, pos, designation, dug_tiles)) {

NOTE: this is only a partial solution, the tile still shows as designated after all is said and done.

cppcooper avatar Dec 05 '22 22:12 cppcooper