Converted tabs to spaces.

develop
expwnent 2012-08-23 22:25:25 -04:00
parent 6de9049dcc
commit cb24f1e53a
1 changed files with 381 additions and 381 deletions

@ -29,7 +29,7 @@ DFHACK_PLUGIN("diggingInvaders");
// Mandatory init function. If you have some global state, create it here. // Mandatory init function. If you have some global state, create it here.
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
//out.print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!\n\n\n\n\n"); //out.print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!\n\n\n\n\n");
// Fill the command list with your commands. // Fill the command list with your commands.
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"diggingInvaders", "Makes invaders dig to your dwarves.", "diggingInvaders", "Makes invaders dig to your dwarves.",
@ -80,30 +80,30 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out )
*/ */
/*class CompareEdge { /*class CompareEdge {
bool operator()(edge e1, edge e2) { bool operator()(edge e1, edge e2) {
} }
};*/ };*/
class Edge { class Edge {
public: public:
//static map<df::coord, int> pointCost; //static map<df::coord, int> pointCost;
df::coord p1; df::coord p1;
df::coord p2; df::coord p2;
int cost; int cost;
Edge(df::coord p1In, df::coord p2In, int costIn): p1(p1In), p2(p2In), cost(costIn) { Edge(df::coord p1In, df::coord p2In, int costIn): p1(p1In), p2(p2In), cost(costIn) {
} }
/*bool operator<(const Edge e) const { /*bool operator<(const Edge e) const {
int pCost = max(pointCost[p1], pointCost[p2]) + cost; int pCost = max(pointCost[p1], pointCost[p2]) + cost;
int e_pCost = max(pointCost[e.p1], pointCost[e.p2]) + e.cost; int e_pCost = max(pointCost[e.p1], pointCost[e.p2]) + e.cost;
if ( pCost != e_pCost ) if ( pCost != e_pCost )
return pCost < e_pCost; return pCost < e_pCost;
if ( p1 != e.p1 ) if ( p1 != e.p1 )
return p1 < e.p1; return p1 < e.p1;
return p2 < e.p2; return p2 < e.p2;
}*/ }*/
}; };
vector<Edge>* getEdgeSet(color_ostream &out, df::coord point, MapExtras::MapCache& cache, int xMax, int yMax, int zMax); vector<Edge>* getEdgeSet(color_ostream &out, df::coord point, MapExtras::MapCache& cache, int xMax, int yMax, int zMax);
@ -111,26 +111,26 @@ df::coord getRoot(df::coord point, map<df::coord, df::coord>& rootMap);
class PointComp { class PointComp {
public: public:
map<df::coord, int> *pointCost; map<df::coord, int> *pointCost;
PointComp(map<df::coord, int> *p): pointCost(p) { PointComp(map<df::coord, int> *p): pointCost(p) {
} }
int operator()(df::coord p1, df::coord p2) { int operator()(df::coord p1, df::coord p2) {
map<df::coord, int>::iterator i1 = pointCost->find(p1); map<df::coord, int>::iterator i1 = pointCost->find(p1);
map<df::coord, int>::iterator i2 = pointCost->find(p2); map<df::coord, int>::iterator i2 = pointCost->find(p2);
if ( i1 == pointCost->end() && i2 == pointCost->end() ) if ( i1 == pointCost->end() && i2 == pointCost->end() )
return p1 < p2; return p1 < p2;
if ( i1 == pointCost->end() ) if ( i1 == pointCost->end() )
return 1; return 1;
if ( i2 == pointCost->end() ) if ( i2 == pointCost->end() )
return -1; return -1;
int c1 = (*i1).second; int c1 = (*i1).second;
int c2 = (*i2).second; int c2 = (*i2).second;
if ( c1 != c2 ) if ( c1 != c2 )
return c1 < c2; return c1 < c2;
return p1 < p2; return p1 < p2;
} }
}; };
// A command! It sits around and looks pretty. And it's nice and friendly. // A command! It sits around and looks pretty. And it's nice and friendly.
@ -140,353 +140,353 @@ command_result diggingInvadersFunc(color_ostream &out, std::vector <std::string>
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
CoreSuspender suspend; CoreSuspender suspend;
//eventually we're going to want a path from each surviving invader to each dwarf, but for now, let's just do from each dwarf to each dwarf //eventually we're going to want a path from each surviving invader to each dwarf, but for now, let's just do from each dwarf to each dwarf
int32_t race_id = df::global::ui->race_id; int32_t race_id = df::global::ui->race_id;
int32_t civ_id = df::global::ui->civ_id; int32_t civ_id = df::global::ui->civ_id;
uint32_t xMax, yMax, zMax; uint32_t xMax, yMax, zMax;
Maps::getSize(xMax,yMax,zMax); Maps::getSize(xMax,yMax,zMax);
xMax *= 16; xMax *= 16;
yMax *= 16; yMax *= 16;
MapExtras::MapCache cache; MapExtras::MapCache cache;
//TODO: consider whether to pursue hidden dwarf diplomats and merchants //TODO: consider whether to pursue hidden dwarf diplomats and merchants
vector<df::unit*> locals; vector<df::unit*> locals;
vector<df::unit*> invaders; vector<df::unit*> invaders;
map<df::coord, int> dwarfCount; map<df::coord, int> dwarfCount;
//map<df::coord, set<Edge>*> edgeSet; //map<df::coord, set<Edge>*> edgeSet;
map<df::coord, df::coord> rootMap; map<df::coord, df::coord> rootMap;
map<df::coord, df::coord> parentMap; map<df::coord, df::coord> parentMap;
map<df::coord, int> pointCost; map<df::coord, int> pointCost;
PointComp comp(&pointCost); PointComp comp(&pointCost);
set<df::coord, PointComp> fringe(comp); set<df::coord, PointComp> fringe(comp);
for ( size_t a = 0; a < df::global::world->units.all.size(); a++ ) { for ( size_t a = 0; a < df::global::world->units.all.size(); a++ ) {
df::unit* unit = df::global::world->units.all[a]; df::unit* unit = df::global::world->units.all[a];
bool isInvader = false; bool isInvader = false;
if ( df::global::ui->invasions.next_id > 0 && unit->invasion_id+1 == df::global::ui->invasions.next_id ) { if ( df::global::ui->invasions.next_id > 0 && unit->invasion_id+1 == df::global::ui->invasions.next_id ) {
invaders.push_back(unit); invaders.push_back(unit);
//dwarfCount[unit->pos]++; //dwarfCount[unit->pos]++;
isInvader = true; isInvader = true;
} }
if ( (!isInvader && (unit->race != race_id || unit->civ_id != civ_id)) || unit->flags1.bits.dead ) if ( (!isInvader && (unit->race != race_id || unit->civ_id != civ_id)) || unit->flags1.bits.dead )
continue; continue;
if ( !isInvader ) if ( !isInvader )
locals.push_back(unit); locals.push_back(unit);
dwarfCount[unit->pos]++; dwarfCount[unit->pos]++;
//edgeSet[unit->pos] = getEdgeSet(unit->pos, cache, xMax, yMax, zMax); //edgeSet[unit->pos] = getEdgeSet(unit->pos, cache, xMax, yMax, zMax);
rootMap[unit->pos] = unit->pos; rootMap[unit->pos] = unit->pos;
parentMap[unit->pos] = unit->pos; parentMap[unit->pos] = unit->pos;
pointCost[unit->pos] = 0; pointCost[unit->pos] = 0;
fringe.insert(unit->pos); fringe.insert(unit->pos);
} }
//TODO: if only one connectivity group, return //TODO: if only one connectivity group, return
if ( invaders.size() == 0 ) { if ( invaders.size() == 0 ) {
return CR_OK; //no invaders, no problem! return CR_OK; //no invaders, no problem!
} }
set<df::coord> importantPoints; set<df::coord> importantPoints;
int a=0; int a=0;
int dwarvesFound = 1; int dwarvesFound = 1;
while(dwarvesFound < invaders.size()+locals.size() && fringe.size() > 0) { while(dwarvesFound < invaders.size()+locals.size() && fringe.size() > 0) {
df::coord point = *fringe.begin(); df::coord point = *fringe.begin();
//out.print("%d: (%d,%d,%d); dwarvesFound = %d\n", a++, (int)point.x, (int)point.y, (int)point.z, dwarvesFound); //out.print("%d: (%d,%d,%d); dwarvesFound = %d\n", a++, (int)point.x, (int)point.y, (int)point.z, dwarvesFound);
//if ( a > 10000 ) break; //if ( a > 10000 ) break;
fringe.erase(fringe.begin()); fringe.erase(fringe.begin());
//dwarfCount[getRoot(point, rootMap)] += dwarfCount[point]; //dwarfCount[getRoot(point, rootMap)] += dwarfCount[point];
if ( getRoot(point, rootMap) != point && dwarfCount[point] != 0 ) { if ( getRoot(point, rootMap) != point && dwarfCount[point] != 0 ) {
dwarfCount[getRoot(point, rootMap)] += dwarfCount[point]; dwarfCount[getRoot(point, rootMap)] += dwarfCount[point];
} }
int costSoFar = pointCost[point]; int costSoFar = pointCost[point];
vector<Edge>* neighbors = getEdgeSet(out, point, cache, xMax, yMax, zMax); vector<Edge>* neighbors = getEdgeSet(out, point, cache, xMax, yMax, zMax);
for ( size_t a = 0; a < neighbors->size(); a++ ) { for ( size_t a = 0; a < neighbors->size(); a++ ) {
df::coord neighbor = (*neighbors)[a].p2; df::coord neighbor = (*neighbors)[a].p2;
int neighborCost; int neighborCost;
if ( pointCost.find(neighbor) == pointCost.end() ) if ( pointCost.find(neighbor) == pointCost.end() )
neighborCost = -1; neighborCost = -1;
else else
neighborCost = pointCost[neighbor]; neighborCost = pointCost[neighbor];
if ( neighborCost == -1 || neighborCost > costSoFar + (*neighbors)[a].cost ) { if ( neighborCost == -1 || neighborCost > costSoFar + (*neighbors)[a].cost ) {
fringe.erase(neighbor); fringe.erase(neighbor);
pointCost[neighbor] = costSoFar + (*neighbors)[a].cost; pointCost[neighbor] = costSoFar + (*neighbors)[a].cost;
parentMap[neighbor] = point; parentMap[neighbor] = point;
//if ( getRoot(neighbor, rootMap) == neighbor ) //if ( getRoot(neighbor, rootMap) == neighbor )
rootMap[neighbor] = rootMap[point]; rootMap[neighbor] = rootMap[point];
fringe.insert(neighbor); fringe.insert(neighbor);
} }
df::coord pointRoot = getRoot(point, rootMap); df::coord pointRoot = getRoot(point, rootMap);
df::coord neighborRoot = getRoot(neighbor, rootMap); df::coord neighborRoot = getRoot(neighbor, rootMap);
//check for unified sections of the map //check for unified sections of the map
if ( neighborRoot != neighbor && neighborRoot != pointRoot ) { if ( neighborRoot != neighbor && neighborRoot != pointRoot ) {
//dwarvesFound++; //dwarvesFound++;
dwarfCount[pointRoot] += dwarfCount[neighborRoot]; dwarfCount[pointRoot] += dwarfCount[neighborRoot];
dwarfCount[neighborRoot] = 0; dwarfCount[neighborRoot] = 0;
dwarvesFound = max(dwarvesFound, dwarfCount[pointRoot]); dwarvesFound = max(dwarvesFound, dwarfCount[pointRoot]);
rootMap[neighborRoot] = rootMap[pointRoot]; rootMap[neighborRoot] = rootMap[pointRoot];
df::coord temp = point; df::coord temp = point;
while(true) { while(true) {
importantPoints.insert(temp); importantPoints.insert(temp);
if ( parentMap[temp] != temp ) if ( parentMap[temp] != temp )
temp = parentMap[temp]; temp = parentMap[temp];
else break; else break;
} }
temp = neighbor; temp = neighbor;
while(true) { while(true) {
importantPoints.insert(temp); importantPoints.insert(temp);
if ( parentMap[temp] != temp ) if ( parentMap[temp] != temp )
temp = parentMap[temp]; temp = parentMap[temp];
else break; else break;
} }
} }
} }
delete neighbors; delete neighbors;
} }
out.print("dwarves found: %d\n", dwarvesFound); out.print("dwarves found: %d\n", dwarvesFound);
out.print("Important points:\n"); out.print("Important points:\n");
for ( set<df::coord>::iterator i = importantPoints.begin(); i != importantPoints.end(); i++ ) { for ( set<df::coord>::iterator i = importantPoints.begin(); i != importantPoints.end(); i++ ) {
df::coord point = *i; df::coord point = *i;
out.print(" (%d, %d, %d)\n", (int)point.x, (int)point.y, (int)point.z); out.print(" (%d, %d, %d)\n", (int)point.x, (int)point.y, (int)point.z);
} }
//dig out all the important points //dig out all the important points
for ( set<df::coord>::iterator i = importantPoints.begin(); i != importantPoints.end(); i++ ) { for ( set<df::coord>::iterator i = importantPoints.begin(); i != importantPoints.end(); i++ ) {
df::coord point = *i; df::coord point = *i;
//deal with buildings, hatches, and doors //deal with buildings, hatches, and doors
{ {
df::map_block* block = cache.BlockAt(df::coord((point.x)/16, (point.y)/16, point.z))->getRaw(); df::map_block* block = cache.BlockAt(df::coord((point.x)/16, (point.y)/16, point.z))->getRaw();
/*if ( block == NULL ) { /*if ( block == NULL ) {
continue; continue;
}*/ }*/
df::tiletype type = cache.tiletypeAt(point); df::tiletype type = cache.tiletypeAt(point);
df::tiletype_shape shape = tileShape(type); df::tiletype_shape shape = tileShape(type);
df::tiletype_shape_basic basic = ENUM_ATTR(tiletype_shape, basic_shape, shape); df::tiletype_shape_basic basic = ENUM_ATTR(tiletype_shape, basic_shape, shape);
df::tile_building_occ building_occ = block->occupancy[point.x%16][point.y%16].bits.building; df::tile_building_occ building_occ = block->occupancy[point.x%16][point.y%16].bits.building;
int z = point.z; int z = point.z;
if ( basic == df::tiletype_shape_basic::Ramp && building_occ == df::tile_building_occ::None ) { if ( basic == df::tiletype_shape_basic::Ramp && building_occ == df::tile_building_occ::None ) {
df::map_block* block2 = cache.BlockAt(df::coord(point.x/16, point.y/16, point.z+1))->getRaw(); df::map_block* block2 = cache.BlockAt(df::coord(point.x/16, point.y/16, point.z+1))->getRaw();
if ( block2 != NULL ) { if ( block2 != NULL ) {
building_occ = block2->occupancy[point.x%16][point.y%16].bits.building; building_occ = block2->occupancy[point.x%16][point.y%16].bits.building;
z = z+1; z = z+1;
if ( building_occ != df::tile_building_occ::None ) { if ( building_occ != df::tile_building_occ::None ) {
//if it doesn't block pathing, don't destroy it //if it doesn't block pathing, don't destroy it
} }
} }
} }
if ( building_occ != df::tile_building_occ::None ) { if ( building_occ != df::tile_building_occ::None ) {
//find the building there //find the building there
bool foundIt = false; bool foundIt = false;
for( size_t a = 0; a < df::global::world->buildings.all.size(); a++ ) { for( size_t a = 0; a < df::global::world->buildings.all.size(); a++ ) {
df::building* building = df::global::world->buildings.all[a]; df::building* building = df::global::world->buildings.all[a];
if ( z != building->z ) if ( z != building->z )
continue; continue;
if ( building->x1 < point.x || building->x2 > point.x ) if ( building->x1 < point.x || building->x2 > point.x )
continue; continue;
if ( building->y1 < point.y || building->y2 > point.y ) if ( building->y1 < point.y || building->y2 > point.y )
continue; continue;
//found it! //found it!
foundIt = true; foundIt = true;
//destroy it //destroy it
building->deconstructItems(false, false); building->deconstructItems(false, false);
//building->removeUses(false, false); //building->removeUses(false, false);
break; break;
} }
if ( !foundIt ) { if ( !foundIt ) {
out.print("Error: could not find building at (%d,%d,%d).\n", point.x, point.y, point.z); out.print("Error: could not find building at (%d,%d,%d).\n", point.x, point.y, point.z);
} }
} }
} }
df::tiletype type = cache.tiletypeAt(point); df::tiletype type = cache.tiletypeAt(point);
df::tiletype_shape shape = tileShape(type); df::tiletype_shape shape = tileShape(type);
if ( shape == df::tiletype_shape::STAIR_UPDOWN ) if ( shape == df::tiletype_shape::STAIR_UPDOWN )
continue; continue;
df::tiletype_shape_basic basicShape = ENUM_ATTR(tiletype_shape, basic_shape, shape); df::tiletype_shape_basic basicShape = ENUM_ATTR(tiletype_shape, basic_shape, shape);
bool uppyDowny; bool uppyDowny;
{ {
//only needs to change if we need uppy-downiness //only needs to change if we need uppy-downiness
df::coord up = df::coord(point.x, point.y, point.z+1); df::coord up = df::coord(point.x, point.y, point.z+1);
df::coord down = df::coord(point.x, point.y, point.z-1); df::coord down = df::coord(point.x, point.y, point.z-1);
uppyDowny = !(importantPoints.find(up) == importantPoints.end() && importantPoints.find(down) == importantPoints.end()); uppyDowny = !(importantPoints.find(up) == importantPoints.end() && importantPoints.find(down) == importantPoints.end());
} }
if ( (basicShape == df::tiletype_shape_basic::Floor || basicShape == df::tiletype_shape_basic::Ramp) && !uppyDowny ) { if ( (basicShape == df::tiletype_shape_basic::Floor || basicShape == df::tiletype_shape_basic::Ramp) && !uppyDowny ) {
continue; continue;
} }
if ( uppyDowny ) { if ( uppyDowny ) {
cache.setTiletypeAt(point, df::tiletype::StoneStairUD); cache.setTiletypeAt(point, df::tiletype::StoneStairUD);
} else { } else {
cache.setTiletypeAt(point, df::tiletype::StoneFloor1); cache.setTiletypeAt(point, df::tiletype::StoneFloor1);
} }
} }
cache.WriteAll(); cache.WriteAll();
return CR_OK; return CR_OK;
} }
vector<Edge>* getEdgeSet(color_ostream &out, df::coord point, MapExtras::MapCache& cache, int xMax, int yMax, int zMax) { vector<Edge>* getEdgeSet(color_ostream &out, df::coord point, MapExtras::MapCache& cache, int xMax, int yMax, int zMax) {
vector<df::coord> candidates; vector<df::coord> candidates;
for ( int dx = -1; dx <= 1; dx++ ) { for ( int dx = -1; dx <= 1; dx++ ) {
if ( point.x + dx < 0 ) continue; if ( point.x + dx < 0 ) continue;
for ( int dy = -1; dy <= 1; dy++ ) { for ( int dy = -1; dy <= 1; dy++ ) {
if ( point.y + dy < 0 ) continue; if ( point.y + dy < 0 ) continue;
if ( dx == 0 && dy == 0) if ( dx == 0 && dy == 0)
continue; continue;
candidates.push_back(df::coord(point.x+dx,point.y+dy,point.z)); candidates.push_back(df::coord(point.x+dx,point.y+dy,point.z));
} }
} }
for ( int dz = -1; dz <= 1; dz++ ) { for ( int dz = -1; dz <= 1; dz++ ) {
if ( point.z + dz < 0 ) continue; if ( point.z + dz < 0 ) continue;
if ( dz == 0 ) continue; if ( dz == 0 ) continue;
candidates.push_back(df::coord(point.x, point.y, point.z+dz)); candidates.push_back(df::coord(point.x, point.y, point.z+dz));
} }
int connectivityType; int connectivityType;
{ {
df::map_block* block = cache.BlockAt(df::coord(point.x/16, point.y/16, point.z))->getRaw(); df::map_block* block = cache.BlockAt(df::coord(point.x/16, point.y/16, point.z))->getRaw();
if ( block == NULL ) { if ( block == NULL ) {
return new vector<Edge>; return new vector<Edge>;
} }
connectivityType = block->walkable[point.x%16][point.y%16]; connectivityType = block->walkable[point.x%16][point.y%16];
} }
if ( connectivityType == 0 ) if ( connectivityType == 0 )
return new vector<Edge>; return new vector<Edge>;
for ( int dx = -1; dx <= 1; dx++ ) { for ( int dx = -1; dx <= 1; dx++ ) {
if ( point.x + dx < 0 ) if ( point.x + dx < 0 )
continue; continue;
for ( int dy = -1; dy <= 1; dy++ ) { for ( int dy = -1; dy <= 1; dy++ ) {
if ( point.y + dy < 0 ) if ( point.y + dy < 0 )
continue; continue;
for ( int dz = -1; dz <= 1; dz++ ) { for ( int dz = -1; dz <= 1; dz++ ) {
if ( dz == 0 ) continue; if ( dz == 0 ) continue;
if ( point.z + dz < 0 ) if ( point.z + dz < 0 )
continue; continue;
if ( dx == 0 && dy == 0 ) if ( dx == 0 && dy == 0 )
continue; continue;
df::map_block* block = cache.BlockAt(df::coord((point.x+dx)/16, (point.y+dy)/16, point.z+dz))->getRaw(); df::map_block* block = cache.BlockAt(df::coord((point.x+dx)/16, (point.y+dy)/16, point.z+dz))->getRaw();
if ( block == NULL ) { if ( block == NULL ) {
continue; continue;
} }
if ( block->walkable[(point.x+dx)%16][(point.y+dy)%16] != connectivityType ) { if ( block->walkable[(point.x+dx)%16][(point.y+dy)%16] != connectivityType ) {
continue; continue;
} }
candidates.push_back(df::coord(point.x+dx, point.y+dy, point.z+dz)); candidates.push_back(df::coord(point.x+dx, point.y+dy, point.z+dz));
} }
} }
} }
//TODO: ramps, buildings //TODO: ramps, buildings
vector<Edge>* result = new vector<Edge>; vector<Edge>* result = new vector<Edge>;
df::tiletype_shape_basic basePointBasicShape; df::tiletype_shape_basic basePointBasicShape;
bool basePointIsWall; bool basePointIsWall;
{ {
df::tiletype type = cache.tiletypeAt(point); df::tiletype type = cache.tiletypeAt(point);
df::tiletype_shape shape = tileShape(type); df::tiletype_shape shape = tileShape(type);
if ( shape == df::tiletype_shape::EMPTY ) if ( shape == df::tiletype_shape::EMPTY )
return result; return result;
basePointBasicShape = ENUM_ATTR(tiletype_shape, basic_shape, shape); basePointBasicShape = ENUM_ATTR(tiletype_shape, basic_shape, shape);
//TODO: worry about up stairs vs down stairs vs updown stairs //TODO: worry about up stairs vs down stairs vs updown stairs
} }
if ( basePointBasicShape == df::tiletype_shape_basic::Wall && cache.hasConstructionAt(point) ) if ( basePointBasicShape == df::tiletype_shape_basic::Wall && cache.hasConstructionAt(point) )
return result; return result;
/*if ( point.z < zMax-1 ) { /*if ( point.z < zMax-1 ) {
//ramps part 1: going up //ramps part 1: going up
//if I'm a ramp, and there's a wall in some direction, and there's nothing above me, and that tile is open, I can go there. //if I'm a ramp, and there's a wall in some direction, and there's nothing above me, and that tile is open, I can go there.
df::tiletype_shape_basic upBasicShape; df::tiletype_shape_basic upBasicShape;
{ {
df::tiletype type = cache.tiletypeAt(df::coord(point.x, point.y, point.z+1)); df::tiletype type = cache.tiletypeAt(df::coord(point.x, point.y, point.z+1));
df::tiletype_shape shape = tileShape(type); df::tiletype_shape shape = tileShape(type);
upBasicShape = ENUM_ATTR(tiletype_shape, basic_shape, shape); upBasicShape = ENUM_ATTR(tiletype_shape, basic_shape, shape);
} }
if ( upBasicShape == df::tiletype_shape_basic::Ramp ) { if ( upBasicShape == df::tiletype_shape_basic::Ramp ) {
for ( int dx = -1; dx <= 1; dx++ ) { for ( int dx = -1; dx <= 1; dx++ ) {
for ( int dy = -1; dy <= 1; dy++ ) { for ( int dy = -1; dy <= 1; dy++ ) {
if ( dx == 0 && dy == 0 ) if ( dx == 0 && dy == 0 )
continue; continue;
df::tiletype type = cache.tiletypeAt(df::coord(point.x+dx, point.y+dy, point.z+1)); df::tiletype type = cache.tiletypeAt(df::coord(point.x+dx, point.y+dy, point.z+1));
df::tiletype_shape shape = tileShape(type); df::tiletype_shape shape = tileShape(type);
df::tiletype_shape_basic basicShape = ENUM_ATTR(tiletype_shape, basic_shape, shape); df::tiletype_shape_basic basicShape = ENUM_ATTR(tiletype_shape, basic_shape, shape);
if ( basicShape == df::tiletype_shape_basic::Floor || if ( basicShape == df::tiletype_shape_basic::Floor ||
basicShape == df::tiletype_shape_basic::Stair || basicShape == df::tiletype_shape_basic::Stair ||
basicShape == df::tiletype_shape_basic::Ramp ) { basicShape == df::tiletype_shape_basic::Ramp ) {
candidates.push_back(df::coord(point.x+dx, point.y+dy, point.z+1)); candidates.push_back(df::coord(point.x+dx, point.y+dy, point.z+1));
} }
} }
} }
} }
} }
if ( point.z >= 1 ) { if ( point.z >= 1 ) {
//ramps part 2: going down //ramps part 2: going down
}*/ }*/
for ( size_t a = 0; a < candidates.size(); a++ ) { for ( size_t a = 0; a < candidates.size(); a++ ) {
if ( candidates[a].x <= 1 || candidates[a].x >= xMax-1 if ( candidates[a].x <= 1 || candidates[a].x >= xMax-1
|| candidates[a].y <= 1 || candidates[a].y >= yMax-1 || candidates[a].y <= 1 || candidates[a].y >= yMax-1
|| candidates[a].z <= 1 || candidates[a].z >= zMax-1 || candidates[a].z <= 1 || candidates[a].z >= zMax-1
) { ) {
continue; continue;
} }
df::tiletype type = cache.tiletypeAt(candidates[a]); df::tiletype type = cache.tiletypeAt(candidates[a]);
df::tiletype_shape shape = tileShape(type); //what namespace? df::tiletype_shape shape = tileShape(type); //what namespace?
if ( shape == df::tiletype_shape::EMPTY ) if ( shape == df::tiletype_shape::EMPTY )
continue; continue;
df::tiletype_shape_basic basicShape = ENUM_ATTR(tiletype_shape, basic_shape, shape); df::tiletype_shape_basic basicShape = ENUM_ATTR(tiletype_shape, basic_shape, shape);
if ( basicShape == df::tiletype_shape_basic::Wall && cache.hasConstructionAt(candidates[a]) ) { if ( basicShape == df::tiletype_shape_basic::Wall && cache.hasConstructionAt(candidates[a]) ) {
continue; continue;
} }
//if it's a forbidden door, continue //if it's a forbidden door, continue
df::map_block* block = cache.BlockAt(df::coord(candidates[a].x/16, candidates[a].y/16, candidates[a].z))->getRaw(); df::map_block* block = cache.BlockAt(df::coord(candidates[a].x/16, candidates[a].y/16, candidates[a].z))->getRaw();
if ( block == NULL ) { if ( block == NULL ) {
continue; continue;
} else { } else {
df::tile_building_occ building_occ = block->occupancy[candidates[a].x%16][candidates[a].y%16].bits.building; df::tile_building_occ building_occ = block->occupancy[candidates[a].x%16][candidates[a].y%16].bits.building;
if ( building_occ == df::tile_building_occ::Obstacle ) if ( building_occ == df::tile_building_occ::Obstacle )
continue; continue;
if ( building_occ == df::tile_building_occ::Impassable ) if ( building_occ == df::tile_building_occ::Impassable )
continue; continue;
if ( building_occ == df::tile_building_occ::Well ) if ( building_occ == df::tile_building_occ::Well )
continue; continue;
if ( building_occ == df::tile_building_occ::Dynamic ) { if ( building_occ == df::tile_building_occ::Dynamic ) {
//continue; //TODO: check df.map.xml.walkable //continue; //TODO: check df.map.xml.walkable
} }
} }
int cost = 1; int cost = 1;
if ( basePointIsWall || basicShape == df::tiletype_shape_basic::Wall ) { if ( basePointIsWall || basicShape == df::tiletype_shape_basic::Wall ) {
cost += 1000000; //TODO: fancy cost cost += 1000000; //TODO: fancy cost
} }
//if ( candidates[a] < point ) { //if ( candidates[a] < point ) {
// result->push_back(Edge(candidates[a], point, cost)); // result->push_back(Edge(candidates[a], point, cost));
//} else { //} else {
result->push_back(Edge(point, candidates[a], cost)); result->push_back(Edge(point, candidates[a], cost));
//} //}
} }
return result; return result;
} }
df::coord getRoot(df::coord point, map<df::coord, df::coord>& rootMap) { df::coord getRoot(df::coord point, map<df::coord, df::coord>& rootMap) {
map<df::coord, df::coord>::iterator i = rootMap.find(point); map<df::coord, df::coord>::iterator i = rootMap.find(point);
if ( i == rootMap.end() ) { if ( i == rootMap.end() ) {
rootMap[point] = point; rootMap[point] = point;
return point; return point;
} }
df::coord parent = (*i).second; df::coord parent = (*i).second;
if ( parent == point ) if ( parent == point )
return parent; return parent;
df::coord root = getRoot(parent, rootMap); df::coord root = getRoot(parent, rootMap);
rootMap[point] = root; rootMap[point] = root;
return root; return root;
} }