diggingInvaders: made it only do a little work each frame instead of all at once with the pathfinding.

develop
expwnent 2013-06-09 23:07:51 -04:00
parent c4533dcb0c
commit 4e715ca44b
3 changed files with 212 additions and 99 deletions

@ -47,8 +47,11 @@ void getRidOfOldJob(df::unit* unit) {
//delete job; //delete job;
} }
int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df::coord,df::coord,PointHash> parentMap, unordered_map<df::coord,int64_t,PointHash>& costMap, vector<df::unit*>& invaders, unordered_set<df::coord,PointHash>& requiresZNeg, unordered_set<df::coord,PointHash>& requiresZPos, MapExtras::MapCache& cache, unordered_set<int32_t>& diggingRaces) { int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df::coord,df::coord,PointHash> parentMap, unordered_map<df::coord,int64_t,PointHash>& costMap, vector<int32_t>& invaders, unordered_set<df::coord,PointHash>& requiresZNeg, unordered_set<df::coord,PointHash>& requiresZPos, MapExtras::MapCache& cache) {
df::unit* firstInvader = invaders[0]; df::unit* firstInvader = df::unit::find(invaders[0]);
if ( !firstInvader ) {
return -1;
}
//do whatever you need to do at the first important edge //do whatever you need to do at the first important edge
df::coord pt1 = firstImportantEdge.p1; df::coord pt1 = firstImportantEdge.p1;
@ -58,7 +61,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
pt1 = pt2; pt1 = pt2;
pt2 = temp; pt2 = temp;
} }
//out.print("first important edge: (%d,%d,%d) -> (%d,%d,%d)\n", pt1.x,pt1.y,pt1.z, pt2.x,pt2.y,pt2.z); out.print("first important edge: (%d,%d,%d) -> (%d,%d,%d)\n", pt1.x,pt1.y,pt1.z, pt2.x,pt2.y,pt2.z);
int32_t jobId = -1; int32_t jobId = -1;
@ -163,18 +166,18 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
df::job* job = new df::job; df::job* job = new df::job;
if ( up && down ) { if ( up && down ) {
job->job_type = df::enums::job_type::CarveUpDownStaircase; job->job_type = df::enums::job_type::CarveUpDownStaircase;
//out.print("%s, line %d: type = up/down\n", __FILE__, __LINE__); out.print("%s, line %d: type = up/down\n", __FILE__, __LINE__);
} else if ( up && !down ) { } else if ( up && !down ) {
job->job_type = df::enums::job_type::CarveUpwardStaircase; job->job_type = df::enums::job_type::CarveUpwardStaircase;
//out.print("%s, line %d: type = up\n", __FILE__, __LINE__); out.print("%s, line %d: type = up\n", __FILE__, __LINE__);
} else if ( !up && down ) { } else if ( !up && down ) {
job->job_type = df::enums::job_type::CarveDownwardStaircase; job->job_type = df::enums::job_type::CarveDownwardStaircase;
//out.print("%s, line %d: type = down\n", __FILE__, __LINE__); out.print("%s, line %d: type = down\n", __FILE__, __LINE__);
} else { } else {
job->job_type = df::enums::job_type::Dig; job->job_type = df::enums::job_type::Dig;
//out.print("%s, line %d: type = dig\n", __FILE__, __LINE__); out.print("%s, line %d: type = dig\n", __FILE__, __LINE__);
} }
//out.print("%s, line %d: up=%d,up1=%d,up2=%d, down=%d,down1=%d,down2=%d\n", __FILE__, __LINE__, up,up1,up2, down,down1,down2); out.print("%s, line %d: up=%d,up1=%d,up2=%d, down=%d,down1=%d,down2=%d\n", __FILE__, __LINE__, up,up1,up2, down,down1,down2);
job->pos = workHere; job->pos = workHere;
firstInvader->path.dest = goHere; firstInvader->path.dest = goHere;
location = goHere; location = goHere;
@ -230,7 +233,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
} }
DFHack::MaterialInfo material; DFHack::MaterialInfo material;
if ( !material.find("WATER") ) { if ( !material.find("OBSIDIAN") ) {
out.print("%s, %d: no water.\n", __FILE__, __LINE__); out.print("%s, %d: no water.\n", __FILE__, __LINE__);
return -1; return -1;
} }

@ -9,5 +9,5 @@
using namespace std; using namespace std;
int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df::coord,df::coord,PointHash> parentMap, unordered_map<df::coord,int64_t,PointHash>& costMap, vector<df::unit*>& invaders, unordered_set<df::coord,PointHash>& requiresZNeg, unordered_set<df::coord,PointHash>& requiresZPos, MapExtras::MapCache& cache, unordered_set<int32_t>& diggingRaces); int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df::coord,df::coord,PointHash> parentMap, unordered_map<df::coord,int64_t,PointHash>& costMap, vector<int32_t>& invaders, unordered_set<df::coord,PointHash>& requiresZNeg, unordered_set<df::coord,PointHash>& requiresZPos, MapExtras::MapCache& cache);

@ -36,6 +36,7 @@
#include "df/item_weaponst.h" #include "df/item_weaponst.h"
#include "df/inorganic_raw.h" #include "df/inorganic_raw.h"
#include "df/job.h" #include "df/job.h"
#include "df/job_list_link.h"
#include "df/job_skill.h" #include "df/job_skill.h"
#include "df/job_type.h" #include "df/job_type.h"
#include "df/map_block.h" #include "df/map_block.h"
@ -67,28 +68,31 @@ using namespace std;
using namespace DFHack; using namespace DFHack;
using namespace df::enums; using namespace df::enums;
command_result diggingInvadersFunc(color_ostream &out, std::vector <std::string> & parameters); command_result diggingInvadersCommand(color_ostream &out, std::vector <std::string> & parameters);
void watchForJobComplete(color_ostream& out, void* ptr); void watchForJobComplete(color_ostream& out, void* ptr);
void initiateDigging(color_ostream& out, void* ptr); void newInvasionHandler(color_ostream& out, void* ptr);
int32_t manageInvasion(color_ostream& out); //int32_t manageInvasion(color_ostream& out);
DFHACK_PLUGIN("diggingInvaders"); DFHACK_PLUGIN("diggingInvaders");
//TODO: when world unloads //TODO: when world unloads
static int32_t lastInvasionJob=-1; static int32_t lastInvasionJob=-1;
static int32_t lastInvasionDigger = -1; static int32_t lastInvasionDigger = -1;
static EventManager::EventHandler jobCompleteHandler(watchForJobComplete, 5); //static EventManager::EventHandler jobCompleteHandler(watchForJobComplete, 5);
static bool enabled=false; static bool enabled=false;
static unordered_set<int32_t> diggingRaces; static bool activeDigging=false;
static unordered_set<string> diggingRaces;
static unordered_set<int32_t> invaderJobs;
static df::coord lastDebugEdgeCostPoint;
DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands)
{ {
EventManager::EventHandler invasionHandler(initiateDigging, 1000); EventManager::EventHandler handler(newInvasionHandler, 1000);
EventManager::registerListener(EventManager::EventType::INVASION, invasionHandler, plugin_self); EventManager::registerListener(EventManager::EventType::INVASION, handler, plugin_self);
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"diggingInvaders", "Makes invaders dig to your dwarves.", "diggingInvaders", "Makes invaders dig to your dwarves.",
diggingInvadersFunc, false, /* true means that the command can't be used from non-interactive user interface */ diggingInvadersCommand, false, /* true means that the command can't be used from non-interactive user interface */
" diggingInvaders enable\n enables the plugin\n" " diggingInvaders enable\n enables the plugin\n"
" diggingInvaders disable\n disables the plugin\n" " diggingInvaders disable\n disables the plugin\n"
" diggingInvaders add GOBLIN\n registers the race GOBLIN as a digging invader\n" " diggingInvaders add GOBLIN\n registers the race GOBLIN as a digging invader\n"
@ -96,6 +100,7 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
" diggingInvaders\n Makes invaders try to dig now.\n" " diggingInvaders\n Makes invaders try to dig now.\n"
)); ));
*df::global::debug_showambush = true;
return CR_OK; return CR_OK;
} }
@ -106,7 +111,7 @@ DFhackCExport command_result plugin_shutdown ( color_ostream &out )
DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event) DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event)
{ {
EventManager::EventHandler invasionHandler(initiateDigging, 1000); EventManager::EventHandler invasionHandler(newInvasionHandler, 1000);
switch (event) { switch (event) {
case DFHack::SC_WORLD_LOADED: case DFHack::SC_WORLD_LOADED:
//TODO: check game mode //TODO: check game mode
@ -151,9 +156,15 @@ public:
}; };
//bool important(df::coord pos, map<df::coord, set<Edge> >& edges, df::coord prev, set<df::coord>& importantPoints, set<Edge>& importantEdges); //bool important(df::coord pos, map<df::coord, set<Edge> >& edges, df::coord prev, set<df::coord>& importantPoints, set<Edge>& importantEdges);
int32_t findAndAssignInvasionJob(color_ostream& out); void findAndAssignInvasionJob(color_ostream& out, void*);
void initiateDigging(color_ostream& out, void* ptr) { void newInvasionHandler(color_ostream& out, void* ptr) {
if ( activeDigging )
return;
activeDigging = true;
EventManager::EventHandler handler(findAndAssignInvasionJob, 1);
EventManager::registerTick(handler, 1, plugin_self);
#if 0
//called when there's a new invasion //called when there's a new invasion
//TODO: check if invaders can dig //TODO: check if invaders can dig
if ( manageInvasion(out) == -2 ) if ( manageInvasion(out) == -2 )
@ -164,10 +175,12 @@ void initiateDigging(color_ostream& out, void* ptr) {
tick = tick % 1000; tick = tick % 1000;
tick = 1000 - tick; tick = 1000 - tick;
EventManager::EventHandler handle(initiateDigging, 1000); EventManager::EventHandler handle(newInvasionHandler, 1000);
EventManager::registerTick(handle, tick, plugin_self); EventManager::registerTick(handle, tick, plugin_self);
#endif
} }
#if 0
void watchForJobComplete(color_ostream& out, void* ptr) { void watchForJobComplete(color_ostream& out, void* ptr) {
/* /*
df::job* job = (df::job*)ptr; df::job* job = (df::job*)ptr;
@ -180,7 +193,9 @@ void watchForJobComplete(color_ostream& out, void* ptr) {
manageInvasion(out); manageInvasion(out);
} }
#endif
#if 0
int32_t manageInvasion(color_ostream& out) { int32_t manageInvasion(color_ostream& out) {
//EventManager::unregisterAll(plugin_self); //EventManager::unregisterAll(plugin_self);
if ( !enabled ) { if ( !enabled ) {
@ -233,9 +248,9 @@ int32_t manageInvasion(color_ostream& out) {
*df::global::pause_state = true; *df::global::pause_state = true;
return 0; //did something return 0; //did something
} }
#endif
static df::coord lastDebugEdgeCostPoint; command_result diggingInvadersCommand(color_ostream& out, std::vector<std::string>& parameters) {
command_result diggingInvadersFunc(color_ostream& out, std::vector<std::string>& parameters) {
for ( size_t a = 0; a < parameters.size(); a++ ) { for ( size_t a = 0; a < parameters.size(); a++ ) {
if ( parameters[a] == "enable" ) { if ( parameters[a] == "enable" ) {
enabled = true; enabled = true;
@ -245,7 +260,12 @@ command_result diggingInvadersFunc(color_ostream& out, std::vector<std::string>&
if ( a+1 >= parameters.size() ) if ( a+1 >= parameters.size() )
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
string race = parameters[a+1]; string race = parameters[a+1];
bool foundIt = false; if ( parameters[a] == "add" ) {
diggingRaces.insert(race);
} else {
diggingRaces.erase(race);
}
/*bool foundIt = false;
for ( size_t b = 0; b < df::global::world->raws.creatures.all.size(); b++ ) { for ( size_t b = 0; b < df::global::world->raws.creatures.all.size(); b++ ) {
df::creature_raw* raw = df::global::world->raws.creatures.all[b]; df::creature_raw* raw = df::global::world->raws.creatures.all[b];
if ( race == raw->creature_id ) { if ( race == raw->creature_id ) {
@ -262,7 +282,7 @@ command_result diggingInvadersFunc(color_ostream& out, std::vector<std::string>&
if ( !foundIt ) { if ( !foundIt ) {
out.print("Couldn't find \"%s\"\n", race.c_str()); out.print("Couldn't find \"%s\"\n", race.c_str());
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }*/
a++; a++;
} else if ( parameters[a] == "setCost" ) { } else if ( parameters[a] == "setCost" ) {
if ( a+2 >= parameters.size() ) if ( a+2 >= parameters.size() )
@ -297,16 +317,16 @@ command_result diggingInvadersFunc(color_ostream& out, std::vector<std::string>&
} }
} }
if ( parameters.size() == 0 ) if ( parameters.size() == 0 ) {
manageInvasion(out); //manageInvasion(out);
newInvasionHandler(out, (void*)0);
}
return CR_OK; return CR_OK;
} }
int32_t findAndAssignInvasionJob(color_ostream& out) { /////////////////////////////////////////////////////////////////////////////////////////
//returns the worker id of the job created //dijkstra globals
vector<int32_t> invaders;
//CoreSuspender suspend;
unordered_set<df::coord, PointHash> invaderPts; unordered_set<df::coord, PointHash> invaderPts;
unordered_set<df::coord, PointHash> localPts; unordered_set<df::coord, PointHash> localPts;
unordered_map<df::coord,df::coord,PointHash> parentMap; unordered_map<df::coord,df::coord,PointHash> parentMap;
@ -314,13 +334,51 @@ int32_t findAndAssignInvasionJob(color_ostream& out) {
PointComp comp(&costMap); PointComp comp(&costMap);
set<df::coord, PointComp> fringe(comp); set<df::coord, PointComp> fringe(comp);
uint32_t xMax, yMax, zMax; EventManager::EventHandler findJobTickHandler(findAndAssignInvasionJob, 1);
Maps::getSize(xMax,yMax,zMax); const int32_t edgesPerFrame = 1000;
xMax *= 16;
yMax *= 16;
MapExtras::MapCache cache;
vector<df::unit*> invaders;
int32_t localPtsFound = 0;
unordered_set<df::coord,PointHash> closedSet;
unordered_map<df::coord,int32_t,PointHash> workNeeded; //non-walking work needed to get there
bool foundTarget = false;
int32_t edgeCount = 0;
void clearDijkstra() {
invaders.clear();
invaderPts.clear();
localPts.clear();
parentMap.clear();
costMap.clear();
comp = PointComp(&costMap);
fringe = set<df::coord,PointComp>(comp);
localPtsFound = edgeCount = 0;
foundTarget = false;
closedSet.clear();
workNeeded.clear();
}
/////////////////////////////////////////////////////////////////////////////////////////
void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
CoreSuspender suspend;
//returns the worker id of the job created //used to
//out.print("%s, %d: %d\n", __FILE__, __LINE__, (int32_t)tickTime);
if ( !activeDigging ) {
clearDijkstra();
return;
}
EventManager::unregister(EventManager::EventType::TICK, findJobTickHandler, plugin_self);
EventManager::registerTick(findJobTickHandler, 1, plugin_self);
if ( fringe.empty() ) {
df::unit* lastDigger = df::unit::find(lastInvasionDigger);
if ( lastDigger && lastDigger->job.current_job && lastDigger->job.current_job->id == lastInvasionJob ) {
return;
}
//out.print("%s,%d: lastDigger = %d, last job = %d, last digger's job = %d\n", __FILE__, __LINE__, lastInvasionDigger, lastInvasionJob, !lastDigger ? -1 : (!lastDigger->job.current_job ? -1 : lastDigger->job.current_job->id));
lastInvasionDigger = lastInvasionJob = -1;
clearDijkstra();
unordered_set<uint16_t> invaderConnectivity; unordered_set<uint16_t> invaderConnectivity;
unordered_set<uint16_t> localConnectivity; unordered_set<uint16_t> localConnectivity;
@ -336,10 +394,18 @@ int32_t findAndAssignInvasionJob(color_ostream& out) {
df::map_block* block = Maps::getTileBlock(unit->pos); df::map_block* block = Maps::getTileBlock(unit->pos);
localConnectivity.insert(block->walkable[unit->pos.x&0xF][unit->pos.y&0xF]); localConnectivity.insert(block->walkable[unit->pos.x&0xF][unit->pos.y&0xF]);
} else if ( unit->flags1.bits.active_invader ) { } else if ( unit->flags1.bits.active_invader ) {
if ( diggingRaces.find(unit->race) == diggingRaces.end() ) df::creature_raw* raw = df::creature_raw::find(unit->race);
if ( raw == NULL ) {
out.print("%s,%d: WTF? Couldn't find creature raw.\n", __FILE__, __LINE__);
continue;
}
if ( diggingRaces.find(raw->creature_id) == diggingRaces.end() )
continue; continue;
if ( invaderPts.find(unit->pos) != invaderPts.end() ) if ( invaderPts.find(unit->pos) != invaderPts.end() )
continue; continue;
//must be able to wield a pick: this is overly pessimistic
if ( unit->status2.limbs_grasp_count < unit->status2.limbs_grasp_max )
continue;
df::map_block* block = Maps::getTileBlock(unit->pos); df::map_block* block = Maps::getTileBlock(unit->pos);
invaderConnectivity.insert(block->walkable[unit->pos.x&0xF][unit->pos.y&0xF]); invaderConnectivity.insert(block->walkable[unit->pos.x&0xF][unit->pos.y&0xF]);
if ( invaderPts.size() > 0 ) if ( invaderPts.size() > 0 )
@ -347,14 +413,15 @@ int32_t findAndAssignInvasionJob(color_ostream& out) {
invaderPts.insert(unit->pos); invaderPts.insert(unit->pos);
costMap[unit->pos] = 0; costMap[unit->pos] = 0;
fringe.insert(unit->pos); fringe.insert(unit->pos);
invaders.push_back(unit); invaders.push_back(unit->id);
} else { } else {
continue; continue;
} }
} }
if ( invaders.empty() || localPts.empty() ) { if ( invaders.empty() || localPts.empty() ) {
return -1; activeDigging = false;
return;
} }
//if local connectivity is not disjoint from invader connectivity, no digging required //if local connectivity is not disjoint from invader connectivity, no digging required
@ -367,22 +434,34 @@ int32_t findAndAssignInvasionJob(color_ostream& out) {
break; break;
} }
if ( overlap ) { if ( overlap ) {
return -1; //still keep checking next frame: might kill a few outsiders then dig down
return;
}
}
df::unit* firstInvader = df::unit::find(invaders[0]);
if ( firstInvader == NULL ) {
fringe.clear();
return;
} }
df::unit* firstInvader = invaders[0]; //TODO: check that firstInvader is an appropriate digger
//out << firstInvader->id << endl; //out << firstInvader->id << endl;
//out << firstInvader->pos.x << ", " << firstInvader->pos.y << ", " << firstInvader->pos.z << endl; //out << firstInvader->pos.x << ", " << firstInvader->pos.y << ", " << firstInvader->pos.z << endl;
//out << __LINE__ << endl; //out << __LINE__ << endl;
int32_t localPtsFound = 0; uint32_t xMax, yMax, zMax;
unordered_set<df::coord,PointHash> closedSet; Maps::getSize(xMax,yMax,zMax);
unordered_map<df::coord,int32_t,PointHash> workNeeded; //non-walking work needed to get there xMax *= 16;
bool foundTarget = false; yMax *= 16;
int32_t edgeCount = 0; MapExtras::MapCache cache;
clock_t t0 = clock(); clock_t t0 = clock();
clock_t totalEdgeTime = 0; clock_t totalEdgeTime = 0;
int32_t edgesExpanded = 0;
while(!fringe.empty()) { while(!fringe.empty()) {
if ( edgesExpanded++ >= edgesPerFrame ) {
return;
}
df::coord pt = *(fringe.begin()); df::coord pt = *(fringe.begin());
fringe.erase(fringe.begin()); fringe.erase(fringe.begin());
//out.print("line %d: fringe size = %d, localPtsFound = %d / %d, closedSetSize = %d, pt = %d,%d,%d\n", __LINE__, fringe.size(), localPtsFound, localPts.size(), closedSet.size(), pt.x,pt.y,pt.z); //out.print("line %d: fringe size = %d, localPtsFound = %d / %d, closedSetSize = %d, pt = %d,%d,%d\n", __LINE__, fringe.size(), localPtsFound, localPts.size(), closedSet.size(), pt.x,pt.y,pt.z);
@ -400,7 +479,7 @@ int32_t findAndAssignInvasionJob(color_ostream& out) {
} }
if ( workNeeded.find(pt) == workNeeded.end() || workNeeded[pt] == 0 ) { if ( workNeeded.find(pt) == workNeeded.end() || workNeeded[pt] == 0 ) {
//there are still dwarves to kill that don't require digging to get to //there are still dwarves to kill that don't require digging to get to
return -1; return;
} }
} }
@ -434,27 +513,34 @@ int32_t findAndAssignInvasionJob(color_ostream& out) {
delete myEdges; delete myEdges;
} }
clock_t time = clock() - t0; clock_t time = clock() - t0;
out.print("time = %d, totalEdgeTime = %d, total points = %d, total edges = %d, time per point = %.3f, time per edge = %.3f, clocks/sec = %d\n", time, totalEdgeTime, closedSet.size(), edgeCount, (float)time / closedSet.size(), (float)time / edgeCount, CLOCKS_PER_SEC); //out.print("tickTime = %d, time = %d, totalEdgeTime = %d, total points = %d, total edges = %d, time per point = %.3f, time per edge = %.3f, clocks/sec = %d\n", (int32_t)tickTime, time, totalEdgeTime, closedSet.size(), edgeCount, (float)time / closedSet.size(), (float)time / edgeCount, CLOCKS_PER_SEC);
fringe.clear();
if ( !foundTarget ) if ( !foundTarget )
return -1; return;
unordered_set<df::coord, PointHash> requiresZNeg; unordered_set<df::coord, PointHash> requiresZNeg;
unordered_set<df::coord, PointHash> requiresZPos; unordered_set<df::coord, PointHash> requiresZPos;
//find important edges //find important edges
Edge firstImportantEdge(df::coord(), df::coord(), -1); Edge firstImportantEdge(df::coord(), df::coord(), -1);
df::coord closest;
int64_t closestCostEstimate=0;
int64_t closestCostActual=0;
for ( auto i = localPts.begin(); i != localPts.end(); i++ ) { for ( auto i = localPts.begin(); i != localPts.end(); i++ ) {
df::coord pt = *i; df::coord pt = *i;
if ( costMap.find(pt) == costMap.end() ) if ( costMap.find(pt) == costMap.end() )
continue; continue;
if ( parentMap.find(pt) == parentMap.end() ) if ( parentMap.find(pt) == parentMap.end() )
continue; continue;
closest = pt;
closestCostEstimate = costMap[closest];
//if ( workNeeded[pt] == 0 ) //if ( workNeeded[pt] == 0 )
// continue; // continue;
while ( parentMap.find(pt) != parentMap.end() ) { while ( parentMap.find(pt) != parentMap.end() ) {
//out.print("(%d,%d,%d)\n", pt.x, pt.y, pt.z); //out.print("(%d,%d,%d)\n", pt.x, pt.y, pt.z);
df::coord parent = parentMap[pt]; df::coord parent = parentMap[pt];
closestCostActual += getEdgeCost(out, parent, pt);
if ( Maps::canStepBetween(parent, pt) ) { if ( Maps::canStepBetween(parent, pt) ) {
} else { } else {
@ -477,7 +563,13 @@ int32_t findAndAssignInvasionJob(color_ostream& out) {
} }
break; break;
} }
if ( firstImportantEdge.p1 == df::coord() )
return;
if ( closestCostActual != closestCostEstimate ) {
out.print("%s,%d: closest = (%d,%d,%d), estimate = %lld != actual = %lld\n", __FILE__, __LINE__, closest.x,closest.y,closest.z, closestCostEstimate, closestCostActual);
return;
}
#if 0 #if 0
unordered_set<df::coord,PointHash> toDelete; unordered_set<df::coord,PointHash> toDelete;
for ( auto a = requiresZNeg.begin(); a != requiresZNeg.end(); a++ ) { for ( auto a = requiresZNeg.begin(); a != requiresZNeg.end(); a++ ) {
@ -502,7 +594,25 @@ int32_t findAndAssignInvasionJob(color_ostream& out) {
toDelete.clear(); toDelete.clear();
#endif #endif
return assignJob(out, firstImportantEdge, parentMap, costMap, invaders, requiresZNeg, requiresZPos, cache, diggingRaces); assignJob(out, firstImportantEdge, parentMap, costMap, invaders, requiresZNeg, requiresZPos, cache);
lastInvasionDigger = firstInvader->id;
lastInvasionJob = firstInvader->job.current_job ? firstInvader->job.current_job->id : -1;
invaderJobs.erase(lastInvasionJob);
for ( df::job_list_link* link = &df::global::world->job_list; link != NULL; link = link->next ) {
if ( link->item == NULL )
continue;
df::job* job = link->item;
if ( invaderJobs.find(job->id) == invaderJobs.end() ) {
continue;
}
//cancel it
job->flags.bits.item_lost = 1;
out.print("%s,%d: cancelling job %d.\n", __FILE__,__LINE__, job->id);
//invaderJobs.remove(job->id);
}
invaderJobs.erase(lastInvasionJob);
return;
} }
df::coord getRoot(df::coord point, map<df::coord, df::coord>& rootMap) { df::coord getRoot(df::coord point, map<df::coord, df::coord>& rootMap) {