Digging invaders: fixed a few problems involving digging and stairs, added a way to debug path cost, added a way to set the cost of each type of invasion job, made invaders only pathfind to one local instead of all of them.

develop
expwnent 2013-01-04 21:02:09 -05:00
parent fd05d30733
commit a7d6cf5157
4 changed files with 106 additions and 19 deletions

@ -118,31 +118,55 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
Job::linkIntoWorld(job); Job::linkIntoWorld(job);
jobId = job->id; jobId = job->id;
} else { } else {
bool walkable_low1 = shape1 == df::tiletype_shape::STAIR_DOWN || shape1 == df::tiletype_shape::STAIR_UPDOWN;
bool walkable_low2 = shape2 == df::tiletype_shape::STAIR_DOWN || shape2 == df::tiletype_shape::STAIR_UPDOWN;
bool walkable_high1 = shape1 == df::tiletype_shape::STAIR_UP || shape1 == df::tiletype_shape::STAIR_UPDOWN;
bool walkable_high2 = shape2 == df::tiletype_shape::STAIR_UP || shape2 == df::tiletype_shape::STAIR_UPDOWN;
//must be a dig job //must be a dig job
bool up = requiresZPos.find(pt2) != requiresZPos.end(); bool up1 = !walkable_high1 && requiresZPos.find(pt1) != requiresZPos.end();
bool down = requiresZNeg.find(pt2) != requiresZNeg.end(); bool up2 = !walkable_high2 && requiresZPos.find(pt2) != requiresZPos.end();
bool down1 = !walkable_low1 && requiresZNeg.find(pt1) != requiresZNeg.end();
bool down2 = !walkable_low2 && requiresZNeg.find(pt2) != requiresZNeg.end();
bool up;
bool down;
df::coord goHere;
df::coord workHere;
if ( pt1.z == pt2.z ) {
up = up2;
down = down2;
goHere = pt1;
workHere = pt2;
} else {
if ( up1 || down1 ) {
up = up1;
down = down1;
goHere = pt1;
workHere = pt1;
} else {
up = up2;
down = down2;
goHere = pt1;
workHere = pt2;
}
}
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;
job->pos = pt2; out.print("%s, line %d: type = up/down\n", __FILE__, __LINE__);
firstInvader->path.dest = pt2;
location = pt2;
} else if ( up && !down ) { } else if ( up && !down ) {
job->job_type = df::enums::job_type::CarveUpwardStaircase; job->job_type = df::enums::job_type::CarveUpwardStaircase;
job->pos = pt2; out.print("%s, line %d: type = up\n", __FILE__, __LINE__);
firstInvader->path.dest = pt2;
location = pt2;
} else if ( !up && down ) { } else if ( !up && down ) {
job->job_type = df::enums::job_type::CarveDownwardStaircase; job->job_type = df::enums::job_type::CarveDownwardStaircase;
job->pos = pt2; out.print("%s, line %d: type = down\n", __FILE__, __LINE__);
firstInvader->path.dest = pt2;
location = pt2;
} else { } else {
job->job_type = df::enums::job_type::Dig; job->job_type = df::enums::job_type::Dig;
job->pos = pt2; out.print("%s, line %d: type = dig\n", __FILE__, __LINE__);
firstInvader->path.dest = pt1;
location = pt1;
} }
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;
firstInvader->path.dest = goHere;
location = goHere;
df::general_ref_unit_workerst* ref = new df::general_ref_unit_workerst; df::general_ref_unit_workerst* ref = new df::general_ref_unit_workerst;
ref->unit_id = firstInvader->id; ref->unit_id = firstInvader->id;
job->general_refs.push_back(ref); job->general_refs.push_back(ref);

@ -10,6 +10,7 @@
#include "modules/Buildings.h" #include "modules/Buildings.h"
#include "modules/EventManager.h" #include "modules/EventManager.h"
#include "modules/Gui.h"
#include "modules/Job.h" #include "modules/Job.h"
#include "modules/Maps.h" #include "modules/Maps.h"
#include "modules/MapCache.h" #include "modules/MapCache.h"
@ -228,6 +229,7 @@ int32_t manageInvasion(color_ostream& out) {
return 0; //did something return 0; //did something
} }
static df::coord lastDebugEdgeCostPoint;
command_result diggingInvadersFunc(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" ) {
@ -257,6 +259,36 @@ command_result diggingInvadersFunc(color_ostream& out, std::vector<std::string>&
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
a++; a++;
} else if ( parameters[a] == "setCost" ) {
if ( a+2 >= parameters.size() )
return CR_WRONG_USAGE;
string costStr = parameters[a+1];
int32_t costDim = -1;
if ( costStr == "distance" ) {
costDim = CostDimension::Distance;
} else if ( costStr == "destroyBuilding" ) {
costDim = CostDimension::DestroyBuilding;
} else if ( costStr == "dig" ) {
costDim = CostDimension::Dig;
} else if ( costStr == "destroyConstruction" ) {
costDim = CostDimension::DestroyConstruction;
} else {
return CR_WRONG_USAGE;
}
int64_t value;
stringstream asdf(parameters[a+2]);
asdf >> value;
if ( value <= 0 )
return CR_WRONG_USAGE;
costWeight[costDim] = value;
a += 2;
} else if ( parameters[a] == "edgeCost" ) {
df::coord bob = Gui::getCursorPos();
out.print("(%d,%d,%d), (%d,%d,%d): cost = %lld\n", lastDebugEdgeCostPoint.x, lastDebugEdgeCostPoint.y, lastDebugEdgeCostPoint.z, bob.x, bob.y, bob.z, getEdgeCost(out, lastDebugEdgeCostPoint, bob));
lastDebugEdgeCostPoint = bob;
}
else {
return CR_WRONG_USAGE;
} }
} }
@ -354,7 +386,7 @@ int32_t findAndAssignInvasionJob(color_ostream& out) {
if ( localPts.find(pt) != localPts.end() ) { if ( localPts.find(pt) != localPts.end() ) {
localPtsFound++; localPtsFound++;
if ( localPtsFound >= localPts.size() ) { if ( true || localPtsFound >= localPts.size() ) {
foundTarget = true; foundTarget = true;
break; break;
} }
@ -438,6 +470,7 @@ int32_t findAndAssignInvasionJob(color_ostream& out) {
break; break;
} }
#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++ ) {
df::coord pos = *a; df::coord pos = *a;
@ -459,6 +492,7 @@ int32_t findAndAssignInvasionJob(color_ostream& out) {
} }
requiresZPos.erase(toDelete.begin(), toDelete.end()); requiresZPos.erase(toDelete.begin(), toDelete.end());
toDelete.clear(); toDelete.clear();
#endif
return assignJob(out, firstImportantEdge, parentMap, costMap, invaders, requiresZNeg, requiresZPos, cache, diggingRaces); return assignJob(out, firstImportantEdge, parentMap, costMap, invaders, requiresZNeg, requiresZPos, cache, diggingRaces);
} }

@ -14,6 +14,17 @@
#include <iostream> #include <iostream>
int64_t costWeight[] = {
//Distance
1,
//Destroy Building
2,
//Dig
10000,
//DestroyConstruction
100,
};
using namespace std; using namespace std;
int64_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2) { int64_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2) {
@ -59,16 +70,26 @@ int64_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2) {
} }
} else { } else {
if ( dx == 0 && dy == 0 ) { if ( dx == 0 && dy == 0 ) {
df::tiletype* type1 = Maps::getTileType(pt1);
df::tiletype_shape shape1 = ENUM_ATTR(tiletype, shape, *type1);
if ( dz > 0 ) { if ( dz > 0 ) {
bool passable_low2 = ENUM_ATTR(tiletype_shape, passable_low, shape2); bool walkable_low2 = shape2 == df::tiletype_shape::STAIR_DOWN || shape2 == df::tiletype_shape::STAIR_UPDOWN;
if ( !passable_low2 ) { if ( !walkable_low2 ) {
if ( building2 || construction2 ) if ( building2 || construction2 )
return -1; return -1;
cost += costWeight[CostDimension::Dig]; cost += costWeight[CostDimension::Dig];
} }
bool walkable_high1 = shape1 == df::tiletype_shape::STAIR_UP || shape1 == df::tiletype_shape::STAIR_UPDOWN;
if ( !walkable_high1 ) {
if ( shape1 != df::enums::tiletype_shape::WALL ) {
return -1;
}
cost += costWeight[CostDimension::Dig];
}
} else { } else {
bool passable_high2 = ENUM_ATTR(tiletype_shape, passable_high, shape2); bool walkable_high2 = shape2 == df::tiletype_shape::STAIR_UP || shape2 == df::tiletype_shape::STAIR_UPDOWN;
if ( !passable_high2 ) { if ( !walkable_high2 ) {
if ( building2 || construction2 ) if ( building2 || construction2 )
return -1; return -1;
@ -76,6 +97,10 @@ int64_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2) {
return -1; return -1;
cost += costWeight[CostDimension::Dig]; cost += costWeight[CostDimension::Dig];
} }
bool walkable_low1 = shape1 == df::tiletype_shape::STAIR_DOWN || shape1 == df::tiletype_shape::STAIR_UPDOWN;
if ( !walkable_low1 ) {
cost += costWeight[CostDimension::Dig];
}
} }
} else { } else {
//nonvertical //nonvertical

@ -21,6 +21,8 @@ enum CostDimension {
costDim costDim
}; };
extern int64_t costWeight[costDim];
/*
const int64_t costWeight[] = { const int64_t costWeight[] = {
//Distance //Distance
1, 1,
@ -31,6 +33,7 @@ const int64_t costWeight[] = {
//DestroyConstruction //DestroyConstruction
100, 100,
}; };
*/
class Edge { class Edge {
public: public:
@ -79,5 +82,6 @@ struct PointHash {
} }
}; };
int64_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2);
std::vector<Edge>* getEdgeSet(color_ostream &out, df::coord point, MapExtras::MapCache& cache, int32_t xMax, int32_t yMax, int32_t zMax); std::vector<Edge>* getEdgeSet(color_ostream &out, df::coord point, MapExtras::MapCache& cache, int32_t xMax, int32_t yMax, int32_t zMax);