|
|
|
@ -25,11 +25,16 @@ distribution.
|
|
|
|
|
|
|
|
|
|
#include "Internal.h"
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include <cstdlib>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <map>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <unordered_map>
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <map>
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
#include "ColorText.h"
|
|
|
|
|
#include "VersionInfo.h"
|
|
|
|
|
#include "MemAccess.h"
|
|
|
|
|
#include "Types.h"
|
|
|
|
@ -77,6 +82,14 @@ using df::global::building_next_id;
|
|
|
|
|
using df::global::process_jobs;
|
|
|
|
|
using df::building_def;
|
|
|
|
|
|
|
|
|
|
struct CoordHash {
|
|
|
|
|
size_t operator()(const df::coord pos) const {
|
|
|
|
|
return pos.x*65537 + pos.y*17 + pos.z;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static unordered_map<df::coord, int32_t, CoordHash> locationToBuilding;
|
|
|
|
|
|
|
|
|
|
static uint8_t *getExtentTile(df::building_extents &extent, df::coord2d tile)
|
|
|
|
|
{
|
|
|
|
|
if (!extent.extents)
|
|
|
|
@ -222,6 +235,30 @@ df::building *Buildings::findAtTile(df::coord pos)
|
|
|
|
|
if (!occ || !occ->bits.building)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
auto a = locationToBuilding.find(pos);
|
|
|
|
|
if ( a == locationToBuilding.end() ) {
|
|
|
|
|
cerr << __FILE__ << ", " << __LINE__ << ": can't find building at " << pos.x << ", " << pos.y << ", " <<pos.z << "." << endl;
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
int32_t id = (*a).second;
|
|
|
|
|
int32_t index = df::building::binsearch_index(df::global::world->buildings.all, id);
|
|
|
|
|
if ( index == -1 ) {
|
|
|
|
|
cerr << __FILE__ << ", " << __LINE__ << ": can't find building at " << pos.x << ", " << pos.y << ", " <<pos.z << "." << endl;
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
df::building* building = df::global::world->buildings.all[index];
|
|
|
|
|
if (!building->isSettingOccupancy())
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
if (building->room.extents && building->isExtentShaped())
|
|
|
|
|
{
|
|
|
|
|
auto etile = getExtentTile(building->room, pos);
|
|
|
|
|
if (!etile || !*etile)
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
return building;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
auto &vec = df::building::get_vector();
|
|
|
|
|
for (size_t i = 0; i < vec.size(); i++)
|
|
|
|
|
{
|
|
|
|
@ -246,6 +283,7 @@ df::building *Buildings::findAtTile(df::coord pos)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Buildings::findCivzonesAt(std::vector<df::building_civzonest*> *pvec, df::coord pos)
|
|
|
|
@ -1063,3 +1101,45 @@ bool Buildings::deconstruct(df::building *bld)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Buildings::updateBuildings(color_ostream& out, void* ptr) {
|
|
|
|
|
static unordered_map<int32_t, df::coord> corner1;
|
|
|
|
|
static unordered_map<int32_t, df::coord> corner2;
|
|
|
|
|
out.print("Updating buildings, %s %d\n", __FILE__, __LINE__);
|
|
|
|
|
int32_t id = (int32_t)ptr;
|
|
|
|
|
|
|
|
|
|
if ( corner1.find(id) == corner1.end() ) {
|
|
|
|
|
//new building: mark stuff
|
|
|
|
|
int32_t index = df::building::binsearch_index(df::global::world->buildings.all, id);
|
|
|
|
|
if ( index == -1 ) {
|
|
|
|
|
out.print("%s, line %d: Couldn't find new building id=%d.\n", __FILE__, __LINE__, id);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
df::building* building = df::global::world->buildings.all[index];
|
|
|
|
|
df::coord p1(min(building->x1, building->x2), min(building->y1,building->y2), building->z);
|
|
|
|
|
df::coord p2(max(building->x1, building->x2), max(building->y1,building->y2), building->z);
|
|
|
|
|
|
|
|
|
|
corner1[id] = p1;
|
|
|
|
|
corner2[id] = p2;
|
|
|
|
|
|
|
|
|
|
for ( int32_t x = p1.x; x <= p2.x; x++ ) {
|
|
|
|
|
for ( int32_t y = p1.y; y <= p2.y; y++ ) {
|
|
|
|
|
df::coord pt(x,y,building->z);
|
|
|
|
|
locationToBuilding[pt] = id;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
//existing building: destroy it
|
|
|
|
|
df::coord p1 = corner1[id];
|
|
|
|
|
df::coord p2 = corner2[id];
|
|
|
|
|
|
|
|
|
|
for ( int32_t x = p1.x; x <= p2.x; x++ ) {
|
|
|
|
|
for ( int32_t y = p1.y; y <= p2.y; y++ ) {
|
|
|
|
|
df::coord pt(x,y,p1.z);
|
|
|
|
|
locationToBuilding.erase(pt);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
corner1.erase(id);
|
|
|
|
|
corner2.erase(id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|