Add buildigs to remotefortressreader.cpp

develop
Japa 2015-09-28 10:06:04 +05:30
parent 051a1f9661
commit 5e43b6b2a6
2 changed files with 176 additions and 3 deletions

@ -109,6 +109,31 @@ message TiletypeList
repeated Tiletype tiletype_list = 1;
}
message BuildingExtents
{
required int32 pos_x = 1;
required int32 pos_y = 2;
required int32 width = 3;
required int32 height = 4;
repeated int32 extents = 5;
}
message BuildingInstance
{
required int32 index = 1;
optional int32 pos_x_min = 2;
optional int32 pos_y_min = 3;
optional int32 pos_z_min = 4;
optional int32 pos_x_max = 5;
optional int32 pos_y_max = 6;
optional int32 pos_z_max = 7;
optional BuildingType building_type = 8;
optional MatPair material = 9;
optional uint32 building_flags = 10;
optional bool is_room = 11;
optional BuildingExtents room = 12;
}
message MapBlock
{
required int32 map_x = 1;
@ -129,6 +154,7 @@ message MapBlock
repeated bool water_stagnant = 16;
repeated bool water_salt = 17;
repeated MatPair construction_items = 18;
repeated BuildingInstance buildings = 19;
}
message MatPair {

@ -31,6 +31,7 @@
#include "df/itemdef.h"
#include "df/building_def_workshopst.h"
#include "df/building_def_furnacest.h"
#include "df/building_wellst.h"
#include "df/descriptor_color.h"
#include "df/descriptor_pattern.h"
@ -98,6 +99,7 @@ static command_result ResetMapHashes(color_ostream &stream, const EmptyMessage *
static command_result GetItemList(color_ostream &stream, const EmptyMessage *in, MaterialList *out);
static command_result GetBuildingDefList(color_ostream &stream, const EmptyMessage *in, BuildingList *out);
static command_result GetWorldMap(color_ostream &stream, const EmptyMessage *in, WorldMap *out);
static command_result GetWorldMapCenter(color_ostream &stream, const EmptyMessage *in, WorldMap *out);
static command_result GetRegionMaps(color_ostream &stream, const EmptyMessage *in, RegionMaps *out);
static command_result GetCreatureRaws(color_ostream &stream, const EmptyMessage *in, CreatureRawList *out);
@ -151,6 +153,7 @@ DFhackCExport RPCService *plugin_rpcconnect(color_ostream &)
svc->addFunction("GetWorldMap", GetWorldMap);
svc->addFunction("GetRegionMaps", GetRegionMaps);
svc->addFunction("GetCreatureRaws", GetCreatureRaws);
svc->addFunction("GetWorldMapCenter", GetWorldMapCenter);
return svc;
}
@ -200,6 +203,49 @@ void ConvertDfColor(int16_t in[3], RemoteFortressReader::ColorDefinition * out)
ConvertDfColor(index, out);
}
void CopyBuilding(int buildingIndex, RemoteFortressReader::BuildingInstance * remote_build)
{
df::building * local_build = df::global::world->buildings.all[buildingIndex];
remote_build->set_index(buildingIndex);
int minZ = local_build->z;
if (local_build->getType() == df::enums::building_type::Well)
{
df::building_wellst * well_building = virtual_cast<df::building_wellst>(local_build);
if (well_building)
minZ = well_building->bucket_z;
}
remote_build->set_pos_x_min(local_build->x1);
remote_build->set_pos_y_min(local_build->y1);
remote_build->set_pos_z_min(minZ);
remote_build->set_pos_x_max(local_build->x2);
remote_build->set_pos_y_max(local_build->y2);
remote_build->set_pos_z_max(local_build->z);
auto buildingType = remote_build->mutable_building_type();
buildingType->set_building_type(local_build->getType());
buildingType->set_building_subtype(local_build->getSubtype());
buildingType->set_building_custom(local_build->getCustomType());
auto material = remote_build->mutable_material();
material->set_mat_type(local_build->mat_type);
material->set_mat_index(local_build->mat_index);
remote_build->set_building_flags(local_build->flags.whole);
remote_build->set_is_room(local_build->is_room);
if (local_build->is_room)
{
auto room = remote_build->mutable_room();
room->set_pos_x(local_build->room.x);
room->set_pos_y(local_build->room.y);
room->set_width(local_build->room.width);
room->set_height(local_build->room.height);
for (int i = 0; i < (local_build->room.width * local_build->room.height); i++)
{
room->add_extents(local_build->room.extents[i]);
}
}
}
RemoteFortressReader::TiletypeMaterial TranslateMaterial(df::tiletype_material material)
{
@ -489,7 +535,7 @@ bool IsTiletypeChanged(DFCoord pos)
map<DFCoord, uint16_t> waterHashes;
//check if the tiletypes have changed
//check if the designations have changed
bool IsDesignationChanged(DFCoord pos)
{
uint16_t hash;
@ -506,10 +552,32 @@ bool IsDesignationChanged(DFCoord pos)
return false;
}
map<DFCoord, uint8_t> buildingHashes;
//check if the designations have changed
bool IsBuildingChanged(DFCoord pos)
{
df::map_block * block = Maps::getBlock(pos);
bool changed = false;
for (int x = 0; x < 16; x++)
for (int y = 0; y < 16; y++)
{
DFCoord localPos = DFCoord(pos.x * 16 + x, pos.y * 16 + y, pos.z);
auto bld = block->occupancy[x][y].bits.building;
if (buildingHashes[pos] != bld)
{
buildingHashes[pos] = bld;
changed = true;
}
}
return changed;
}
static command_result ResetMapHashes(color_ostream &stream, const EmptyMessage *in)
{
hashes.clear();
waterHashes.clear();
buildingHashes.clear();
return CR_OK;
}
@ -746,6 +814,8 @@ void CopyDesignation(df::map_block * DfBlock, RemoteFortressReader::MapBlock * N
NetBlock->set_map_y(DfBlock->map_pos.y);
NetBlock->set_map_z(DfBlock->map_pos.z);
bool hasBuilding = false;
for (int yy = 0; yy < 16; yy++)
for (int xx = 0; xx < 16; xx++)
{
@ -766,6 +836,44 @@ void CopyDesignation(df::map_block * DfBlock, RemoteFortressReader::MapBlock * N
NetBlock->add_water_salt(designation.bits.water_salt);
NetBlock->add_water_stagnant(designation.bits.water_stagnant);
}
if(hasBuilding)
for (int i = 0; i < df::global::world->buildings.all.size(); i++)
{
}
}
void CopyBuildings(df::map_block * DfBlock, RemoteFortressReader::MapBlock * NetBlock, MapExtras::MapCache * MC, DFCoord pos)
{
int minX = DfBlock->map_pos.x;
int minY = DfBlock->map_pos.y;
int Z = DfBlock->map_pos.z;
int maxX = minX + 15;
int maxY = minY + 15;
for (int i = 0; i < df::global::world->buildings.all.size(); i++)
{
df::building * bld = df::global::world->buildings.all[i];
if (bld->x1 > maxX || bld->y1 > maxY || bld->x2 < minX || bld->y2 < minY)
continue;
int z2 = bld->z;
if (bld->getType() == building_type::Well)
{
df::building_wellst * well_building = virtual_cast<df::building_wellst>(bld);
if (well_building)
{
z2 = well_building->bucket_z;
}
}
if (bld->z < Z || z2 > Z)
continue;
auto out_bld = NetBlock->add_buildings();
CopyBuilding(i, out_bld);
}
}
static command_result GetBlockList(color_ostream &stream, const BlockRequest *in, BlockList *out)
@ -816,14 +924,16 @@ static command_result GetBlockList(color_ostream &stream, const BlockRequest *in
for (int yyy = 0; yyy < 16; yyy++)
{
if ((DFHack::tileShapeBasic(DFHack::tileShape(block->tiletype[xxx][yyy])) != df::tiletype_shape_basic::None &&
DFHack::tileShapeBasic(DFHack::tileShape(block->tiletype[xxx][yyy])) != df::tiletype_shape_basic::Open) ||
block->designation[xxx][yyy].bits.flow_size > 0)
DFHack::tileShapeBasic(DFHack::tileShape(block->tiletype[xxx][yyy])) != df::tiletype_shape_basic::Open)
|| block->designation[xxx][yyy].bits.flow_size > 0
|| block->occupancy[xxx][yyy].bits.building > 0)
nonAir++;
}
if (nonAir > 0)
{
bool tileChanged = IsTiletypeChanged(pos);
bool desChanged = IsDesignationChanged(pos);
//bool bldChanged = IsBuildingChanged(pos);
RemoteFortressReader::MapBlock *net_block;
if (tileChanged || desChanged)
net_block = out->add_map_blocks();
@ -834,6 +944,10 @@ static command_result GetBlockList(color_ostream &stream, const BlockRequest *in
}
if (desChanged)
CopyDesignation(block, net_block, &MC, pos);
if (tileChanged)
{
CopyBuildings(block, net_block, &MC, pos);
}
}
}
}
@ -1223,6 +1337,39 @@ static command_result GetBuildingDefList(color_ostream &stream, const EmptyMessa
return CR_OK;
}
static command_result GetWorldMapCenter(color_ostream &stream, const EmptyMessage *in, WorldMap *out)
{
if (!df::global::world->world_data)
{
out->set_world_width(0);
out->set_world_height(0);
return CR_FAILURE;
}
df::world_data * data = df::global::world->world_data;
int width = data->world_width;
int height = data->world_height;
out->set_world_width(width);
out->set_world_height(height);
int32_t pos_x = 0, pos_y = 0, pos_z = 0;
if (Maps::IsValid())
Maps::getPosition(pos_x, pos_y, pos_z);
else
for (int i = 0; i < df::global::world->armies.all.size(); i++)
{
df::army * thisArmy = df::global::world->armies.all[i];
if (thisArmy->flags.is_set(df::enums::army_flags::player))
{
pos_x = (thisArmy->pos.x / 3) - 1;
pos_y = (thisArmy->pos.y / 3) - 1;
pos_z = thisArmy->pos.z;
}
}
out->set_center_x(pos_x);
out->set_center_y(pos_y);
out->set_center_z(pos_z);
return CR_OK;
}
static command_result GetWorldMap(color_ostream &stream, const EmptyMessage *in, WorldMap *out)
{
if (!df::global::world->world_data)