Copy engravings in RFR, and update the art image function.

develop
Japa 2018-02-04 10:12:15 +05:30
parent c8747a772b
commit 38140fb450
5 changed files with 123 additions and 38 deletions

@ -1 +1 @@
Subproject commit b0203a1d982212b1a82ea159d07a2dc6df31c191 Subproject commit 6652fd55e5e489c8a5d12467d1ea85c83192ba17

@ -434,6 +434,7 @@ message BlockList
repeated MapBlock map_blocks = 1; repeated MapBlock map_blocks = 1;
optional int32 map_x = 2; optional int32 map_x = 2;
optional int32 map_y = 3; optional int32 map_y = 3;
repeated Engraving engravings = 4;
} }
message PlantDef message PlantDef
@ -939,3 +940,21 @@ message ArtImage
repeated ArtImageElement elements = 1; repeated ArtImageElement elements = 1;
optional MatPair id = 2; optional MatPair id = 2;
} }
message Engraving
{
optional Coord pos = 1;
optional int32 quality = 2;
optional int32 tile = 3;
optional ArtImage image = 4;
optional bool floor = 5;
optional bool west = 6;
optional bool east = 7;
optional bool north = 8;
optional bool south = 9;
optional bool hidden = 10;
optional bool northwest = 11;
optional bool northeast = 12;
optional bool southwest = 13;
optional bool southeast = 14;
}

@ -107,20 +107,6 @@ void CopyImage(const df::art_image * image, ArtImage * netImage)
} }
} }
void CopyImage(df::art_image_ref imageRef, ArtImage * netImage)
{
{
for (int i = 0; i < world->art_image_chunks.size(); i++)
{
auto chunk = world->art_image_chunks[i];
if (chunk->id != imageRef.id)
continue;
auto image = chunk->images[imageRef.subid];
CopyImage(image, netImage);
}
}
}
void CopyItem(RemoteFortressReader::Item * NetItem, df::item * DfItem) void CopyItem(RemoteFortressReader::Item * NetItem, df::item * DfItem)
{ {
NetItem->set_id(DfItem->id); NetItem->set_id(DfItem->id);
@ -196,7 +182,27 @@ void CopyItem(RemoteFortressReader::Item * NetItem, df::item * DfItem)
case df::enums::item_type::STATUE: case df::enums::item_type::STATUE:
{ {
VIRTUAL_CAST_VAR(statue, df::item_statuest, DfItem); VIRTUAL_CAST_VAR(statue, df::item_statuest, DfItem);
CopyImage(statue->image, NetItem->mutable_image());
df::art_image_chunk * chunk = NULL;
GET_ART_IMAGE_CHUNK GetArtImageChunk = reinterpret_cast<GET_ART_IMAGE_CHUNK>(Core::getInstance().vinfo->getAddress("rfr_get_art_image"));
if (GetArtImageChunk)
{
chunk = GetArtImageChunk(&(world->art_image_chunks), statue->image.id);
}
else
{
for (int i = 0; i < world->art_image_chunks.size(); i++)
{
if (world->art_image_chunks[i]->id == statue->image.id)
chunk = world->art_image_chunks[i];
}
}
if (chunk)
{
CopyImage(chunk->images[statue->image.subid], NetItem->mutable_image());
}
break; break;
} }
case df::enums::item_type::CORPSE: case df::enums::item_type::CORPSE:

@ -12,7 +12,7 @@ namespace df
struct item; struct item;
struct map_block; struct map_block;
struct art_image; struct art_image;
struct art_image_ref; struct art_image_chunk;
struct world; struct world;
} }
@ -25,11 +25,8 @@ DFHack::command_result GetItemList(DFHack::color_ostream &stream, const DFHack::
void CopyItem(RemoteFortressReader::Item * NetItem, df::item * DfItem); void CopyItem(RemoteFortressReader::Item * NetItem, df::item * DfItem);
void ConvertDFColorDescriptor(int16_t index, RemoteFortressReader::ColorDefinition * out); void ConvertDFColorDescriptor(int16_t index, RemoteFortressReader::ColorDefinition * out);
#if(defined(WIN32) && !defined(_WIN64)) typedef df::art_image_chunk * (*GET_ART_IMAGE_CHUNK)(std::vector<df::art_image_chunk* > *, int);
typedef df::art_image * (__thiscall *GET_IMAGE)(df::world *, df::art_image_ref *, int16_t *);
#else
typedef df::art_image * (*GET_IMAGE)(df::world *, df::art_image_ref *, int16_t *);
#endif
void CopyImage(const df::art_image * image, RemoteFortressReader::ArtImage * netImage);
#endif // !ITEM_READER_H #endif // !ITEM_READER_H

@ -57,6 +57,7 @@
#include "df/descriptor_shape.h" #include "df/descriptor_shape.h"
#include "df/dfhack_material_category.h" #include "df/dfhack_material_category.h"
#include "df/enabler.h" #include "df/enabler.h"
#include "df/engraving.h"
#include "df/graphic.h" #include "df/graphic.h"
#include "df/historical_figure.h" #include "df/historical_figure.h"
@ -182,20 +183,18 @@ const char* growth_locations[] = {
#include "df/art_image.h" #include "df/art_image.h"
#include "df/art_image_chunk.h" #include "df/art_image_chunk.h"
#include "df/art_image_ref.h" #include "df/art_image_ref.h"
command_result generate_image(color_ostream &out, vector <string> & parameters) command_result loadArtImageChunk(color_ostream &out, vector <string> & parameters)
{ {
df::art_image_ref imageRef; if (parameters.size() != 1)
imageRef.civ_id = -1; return CR_WRONG_USAGE;
imageRef.id = -1;
imageRef.site_id = -1;
imageRef.subid = -1;
GET_IMAGE getImage = reinterpret_cast<GET_IMAGE>(Core::getInstance().vinfo->getAddress("rfr_get_art_image"));
if (getImage) GET_ART_IMAGE_CHUNK GetArtImageChunk = reinterpret_cast<GET_ART_IMAGE_CHUNK>(Core::getInstance().vinfo->getAddress("rfr_get_art_image"));
if (GetArtImageChunk)
{ {
int16_t subid = -1; int index = atoi(parameters[0].c_str());
auto image = getImage(world, &imageRef, &subid); auto chunk = GetArtImageChunk(&(world->art_image_chunks), index);
out.print("Id: %d, subid: %d\n", image->id, image->subid); out.print("Loaded chunk id: &d", chunk->id);
} }
return CR_OK; return CR_OK;
} }
@ -271,10 +270,10 @@ DFhackCExport command_result plugin_init(color_ostream &out, std::vector <Plugin
)); ));
commands.push_back(PluginCommand("RemoteFortressReader_version", "List the loaded RemoteFortressReader version", RemoteFortressReader_version, false, "This is used for plugin version checking.")); commands.push_back(PluginCommand("RemoteFortressReader_version", "List the loaded RemoteFortressReader version", RemoteFortressReader_version, false, "This is used for plugin version checking."));
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"generate_image", "load_art_image_chunk",
"make a blank art image using inbuilt DF functions.", "Gets an art image chunk by index, loading from disk if necessary",
generate_image, false, loadArtImageChunk, false,
"used to test the function pointer being correct. If everything works, the subid should increment each time.")); "Usage: load_art_image_chunk N, where N is the id of the chunk to get."));
enableUpdates = true; enableUpdates = true;
return CR_OK; return CR_OK;
} }
@ -799,6 +798,21 @@ bool areItemsChanged(vector<int> * items)
return result; return result;
} }
map<int, int> engravingHashes;
bool isEngravingNew(int index)
{
if (engravingHashes[index])
return false;
engravingHashes[index] = true;
return true;
}
void engravingIsNotNew(int index)
{
engravingHashes[index] = false;
}
static command_result ResetMapHashes(color_ostream &stream, const EmptyMessage *in) static command_result ResetMapHashes(color_ostream &stream, const EmptyMessage *in)
{ {
hashes.clear(); hashes.clear();
@ -806,6 +820,7 @@ static command_result ResetMapHashes(color_ostream &stream, const EmptyMessage *
buildingHashes.clear(); buildingHashes.clear();
spatterHashes.clear(); spatterHashes.clear();
itemHashes.clear(); itemHashes.clear();
engravingHashes.clear();
return CR_OK; return CR_OK;
} }
@ -1485,6 +1500,54 @@ static command_result GetBlockList(color_ostream &stream, const BlockRequest *in
} }
} }
} }
for (int i = 0; i < world->engravings.size(); i++)
{
auto engraving = world->engravings[i];
if (engraving->pos.x < (min_x * 16) || engraving->pos.x >(max_x * 16))
continue;
if (engraving->pos.y < (min_y * 16) || engraving->pos.x >(max_y * 16))
continue;
if (engraving->pos.z < (min_z * 16) || engraving->pos.x >(max_z * 16))
continue;
if (!isEngravingNew(i))
continue;
df::art_image_chunk * chunk = NULL;
GET_ART_IMAGE_CHUNK GetArtImageChunk = reinterpret_cast<GET_ART_IMAGE_CHUNK>(Core::getInstance().vinfo->getAddress("rfr_get_art_image"));
if (GetArtImageChunk)
{
chunk = GetArtImageChunk(&(world->art_image_chunks), engraving->art_id);
}
else
{
for (int i = 0; i < world->art_image_chunks.size(); i++)
{
if (world->art_image_chunks[i]->id == engraving->art_id)
chunk = world->art_image_chunks[i];
}
}
if (!chunk)
{
engravingIsNotNew(i);
continue;
}
auto netEngraving = out->add_engravings();
ConvertDFCoord(engraving->pos, netEngraving->mutable_pos());
netEngraving->set_quality(engraving->quality);
netEngraving->set_tile(engraving->tile);
CopyImage(chunk->images[engraving->art_subid], netEngraving->mutable_image());
netEngraving->set_floor(engraving->flags.bits.floor);
netEngraving->set_west(engraving->flags.bits.west);
netEngraving->set_east(engraving->flags.bits.east);
netEngraving->set_north(engraving->flags.bits.north);
netEngraving->set_south(engraving->flags.bits.south);
netEngraving->set_hidden(engraving->flags.bits.hidden);
netEngraving->set_northwest(engraving->flags.bits.northwest);
netEngraving->set_northeast(engraving->flags.bits.northeast);
netEngraving->set_southwest(engraving->flags.bits.southwest);
netEngraving->set_southeast(engraving->flags.bits.southeast);
}
MC.trash(); MC.trash();
return CR_OK; return CR_OK;
} }