dfhack
dfhack copied to clipboard
dig-now neglects "active" jobs
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.