Move item reader to a separate file.

develop
Japa 2018-01-17 19:10:19 +05:30
parent ea6757377e
commit a63347cf7a
5 changed files with 455 additions and 162 deletions

@ -276,6 +276,7 @@ message Item
optional float velocity_y = 14;
optional float velocity_z = 15;
optional int32 volume = 16;
repeated ItemImprovement improvements = 17;
}
message MapBlock
@ -885,4 +886,29 @@ message ShapeDescriptior
message Language
{
repeated ShapeDescriptior shapes = 1;
}
}
enum ImprovementType
{
ART_IMAGE = 0;
COVERED = 1;
RINGS_HANGING = 2;
BANDS = 3;
SPIKES = 4;
ITEMSPECIFIC = 5;
THREAD = 6;
CLOTH = 7;
SEWN_IMAGE = 8;
PAGES = 9;
ILLUSTRATION = 10;
INSTRUMENT_PIECE = 11;
WRITING = 12;
}
message ItemImprovement
{
optional MatPair mat_type = 1;
optional ImprovementType type = 2;
optional int32 shape = 3;
}

@ -4,11 +4,13 @@ SET(PROJECT_SRCS
remotefortressreader.cpp
adventure_control.cpp
building_reader.cpp
item_reader.cpp
)
# A list of headers
SET(PROJECT_HDRS
adventure_control.h
building_reader.h
item_reader.h
df_version_int.h
)
#proto files to include.

@ -0,0 +1,395 @@
#include "item_reader.h"
#include "df/descriptor_shape.h"
#include "df/item_type.h"
#include "df/item_constructed.h"
#include "df/item_gemst.h"
#include "df/item_threadst.h"
#include "df/item_toolst.h"
#include "df/item_smallgemst.h"
#include "df/itemimprovement.h"
#include "df/itemimprovement_threadst.h"
#include "df/itemdef.h"
#include "df/map_block.h"
#include "df/vehicle.h"
#include "df/world.h"
#include "modules/Items.h"
#include "modules/MapCache.h"
#include "modules/Materials.h"
#include "MiscUtils.h"
using namespace DFHack;
using namespace df::enums;
using namespace RemoteFortressReader;
using namespace std;
using namespace df::global;
void CopyItem(RemoteFortressReader::Item * NetItem, df::item * DfItem)
{
NetItem->set_id(DfItem->id);
NetItem->set_flags1(DfItem->flags.whole);
NetItem->set_flags2(DfItem->flags2.whole);
auto pos = NetItem->mutable_pos();
pos->set_x(DfItem->pos.x);
pos->set_y(DfItem->pos.y);
pos->set_z(DfItem->pos.z);
auto mat = NetItem->mutable_material();
mat->set_mat_index(DfItem->getMaterialIndex());
mat->set_mat_type(DfItem->getMaterial());
auto type = NetItem->mutable_type();
type->set_mat_type(DfItem->getType());
type->set_mat_index(DfItem->getSubtype());
bool isProjectile = false;
item_type::item_type itemType = DfItem->getType();
switch (itemType)
{
case df::enums::item_type::NONE:
break;
case df::enums::item_type::BAR:
break;
case df::enums::item_type::SMALLGEM:
{
VIRTUAL_CAST_VAR(smallgem_item, df::item_smallgemst, DfItem);
type->set_mat_index(smallgem_item->shape);
break;
}
case df::enums::item_type::BLOCKS:
break;
case df::enums::item_type::ROUGH:
break;
case df::enums::item_type::BOULDER:
break;
case df::enums::item_type::WOOD:
break;
case df::enums::item_type::DOOR:
break;
case df::enums::item_type::FLOODGATE:
break;
case df::enums::item_type::BED:
break;
case df::enums::item_type::CHAIR:
break;
case df::enums::item_type::CHAIN:
break;
case df::enums::item_type::FLASK:
break;
case df::enums::item_type::GOBLET:
break;
case df::enums::item_type::INSTRUMENT:
break;
case df::enums::item_type::TOY:
break;
case df::enums::item_type::WINDOW:
break;
case df::enums::item_type::CAGE:
break;
case df::enums::item_type::BARREL:
break;
case df::enums::item_type::BUCKET:
break;
case df::enums::item_type::ANIMALTRAP:
break;
case df::enums::item_type::TABLE:
break;
case df::enums::item_type::COFFIN:
break;
case df::enums::item_type::STATUE:
break;
case df::enums::item_type::CORPSE:
break;
case df::enums::item_type::WEAPON:
break;
case df::enums::item_type::ARMOR:
break;
case df::enums::item_type::SHOES:
break;
case df::enums::item_type::SHIELD:
break;
case df::enums::item_type::HELM:
break;
case df::enums::item_type::GLOVES:
break;
case df::enums::item_type::BOX:
type->set_mat_index(DfItem->isBag());
break;
case df::enums::item_type::BIN:
break;
case df::enums::item_type::ARMORSTAND:
break;
case df::enums::item_type::WEAPONRACK:
break;
case df::enums::item_type::CABINET:
break;
case df::enums::item_type::FIGURINE:
break;
case df::enums::item_type::AMULET:
break;
case df::enums::item_type::SCEPTER:
break;
case df::enums::item_type::AMMO:
break;
case df::enums::item_type::CROWN:
break;
case df::enums::item_type::RING:
break;
case df::enums::item_type::EARRING:
break;
case df::enums::item_type::BRACELET:
break;
case df::enums::item_type::GEM:
{
VIRTUAL_CAST_VAR(gem_item, df::item_gemst, DfItem);
type->set_mat_index(gem_item->shape);
break;
}
case df::enums::item_type::ANVIL:
break;
case df::enums::item_type::CORPSEPIECE:
break;
case df::enums::item_type::REMAINS:
break;
case df::enums::item_type::MEAT:
break;
case df::enums::item_type::FISH:
break;
case df::enums::item_type::FISH_RAW:
break;
case df::enums::item_type::VERMIN:
break;
case df::enums::item_type::PET:
break;
case df::enums::item_type::SEEDS:
break;
case df::enums::item_type::PLANT:
break;
case df::enums::item_type::SKIN_TANNED:
break;
case df::enums::item_type::PLANT_GROWTH:
break;
case df::enums::item_type::THREAD:
{
VIRTUAL_CAST_VAR(thread, df::item_threadst, DfItem);
if (thread && thread->dye_mat_type >= 0)
{
DFHack::MaterialInfo info;
if (info.decode(thread->dye_mat_type, thread->dye_mat_index))
ConvertDFColorDescriptor(info.material->powder_dye, NetItem->mutable_dye());
}
break;
}
case df::enums::item_type::CLOTH:
break;
case df::enums::item_type::TOTEM:
break;
case df::enums::item_type::PANTS:
break;
case df::enums::item_type::BACKPACK:
break;
case df::enums::item_type::QUIVER:
break;
case df::enums::item_type::CATAPULTPARTS:
break;
case df::enums::item_type::BALLISTAPARTS:
break;
case df::enums::item_type::SIEGEAMMO:
break;
case df::enums::item_type::BALLISTAARROWHEAD:
break;
case df::enums::item_type::TRAPPARTS:
break;
case df::enums::item_type::TRAPCOMP:
break;
case df::enums::item_type::DRINK:
break;
case df::enums::item_type::POWDER_MISC:
break;
case df::enums::item_type::CHEESE:
break;
case df::enums::item_type::FOOD:
break;
case df::enums::item_type::LIQUID_MISC:
break;
case df::enums::item_type::COIN:
break;
case df::enums::item_type::GLOB:
break;
case df::enums::item_type::ROCK:
break;
case df::enums::item_type::PIPE_SECTION:
break;
case df::enums::item_type::HATCH_COVER:
break;
case df::enums::item_type::GRATE:
break;
case df::enums::item_type::QUERN:
break;
case df::enums::item_type::MILLSTONE:
break;
case df::enums::item_type::SPLINT:
break;
case df::enums::item_type::CRUTCH:
break;
case df::enums::item_type::TRACTION_BENCH:
break;
case df::enums::item_type::ORTHOPEDIC_CAST:
break;
case df::enums::item_type::TOOL:
if (!isProjectile)
{
VIRTUAL_CAST_VAR(tool, df::item_toolst, DfItem);
if (tool)
{
auto vehicle = binsearch_in_vector(world->vehicles.active, tool->vehicle_id);
if (vehicle)
{
NetItem->set_subpos_x(vehicle->offset_x / 100000.0);
NetItem->set_subpos_y(vehicle->offset_y / 100000.0);
NetItem->set_subpos_z(vehicle->offset_z / 140000.0);
}
}
}
break;
case df::enums::item_type::SLAB:
break;
case df::enums::item_type::EGG:
break;
case df::enums::item_type::BOOK:
break;
case df::enums::item_type::SHEET:
break;
case df::enums::item_type::BRANCH:
break;
default:
break;
}
VIRTUAL_CAST_VAR(actual_item, df::item_actual, DfItem);
if (actual_item)
{
NetItem->set_stack_size(actual_item->stack_size);
}
VIRTUAL_CAST_VAR(constructed_item, df::item_constructed, DfItem);
if (constructed_item)
{
for (int i = 0; i < constructed_item->improvements.size(); i++)
{
auto improvement = constructed_item->improvements[i];
if (!improvement)
continue;
improvement_type::improvement_type impType = improvement->getType();
switch (impType)
{
case df::enums::improvement_type::ART_IMAGE:
break;
case df::enums::improvement_type::COVERED:
{
break;
}
case df::enums::improvement_type::RINGS_HANGING:
break;
case df::enums::improvement_type::BANDS:
break;
case df::enums::improvement_type::SPIKES:
break;
case df::enums::improvement_type::ITEMSPECIFIC:
break;
case df::enums::improvement_type::THREAD:
{
VIRTUAL_CAST_VAR(improvement_thread, df::itemimprovement_threadst, improvement);
if (improvement_thread->dye.mat_type >= 0)
{
DFHack::MaterialInfo info;
if (!info.decode(improvement_thread->dye.mat_type, improvement_thread->dye.mat_index))
continue;
ConvertDFColorDescriptor(info.material->powder_dye, NetItem->mutable_dye());
}
break;
}
case df::enums::improvement_type::CLOTH:
break;
case df::enums::improvement_type::SEWN_IMAGE:
break;
case df::enums::improvement_type::PAGES:
break;
case df::enums::improvement_type::ILLUSTRATION:
break;
case df::enums::improvement_type::INSTRUMENT_PIECE:
break;
case df::enums::improvement_type::WRITING:
break;
default:
break;
}
}
}
NetItem->set_volume(DfItem->getVolume());
}
DFHack::command_result GetItemList(DFHack::color_ostream &stream, const DFHack::EmptyMessage *in, RemoteFortressReader::MaterialList *out)
{
if (!Core::getInstance().isWorldLoaded()) {
//out->set_available(false);
return CR_OK;
}
FOR_ENUM_ITEMS(item_type, it)
{
MaterialDefinition *mat_def = out->add_material_list();
mat_def->mutable_mat_pair()->set_mat_type((int)it);
mat_def->mutable_mat_pair()->set_mat_index(-1);
mat_def->set_id(ENUM_KEY_STR(item_type, it));
switch (it)
{
case df::enums::item_type::GEM:
case df::enums::item_type::SMALLGEM:
{
for (int i = 0; i < world->raws.language.shapes.size(); i++)
{
auto shape = world->raws.language.shapes[i];
if (shape->gems_use.whole == 0)
continue;
mat_def = out->add_material_list();
mat_def->mutable_mat_pair()->set_mat_type((int)it);
mat_def->mutable_mat_pair()->set_mat_index(i);
mat_def->set_id(ENUM_KEY_STR(item_type, it) + "/" + shape->id);
}
break;
}
case df::enums::item_type::BOX:
{
mat_def = out->add_material_list();
mat_def->mutable_mat_pair()->set_mat_type((int)it);
mat_def->mutable_mat_pair()->set_mat_index(0);
mat_def->set_id("BOX_CHEST");
mat_def = out->add_material_list();
mat_def->mutable_mat_pair()->set_mat_type((int)it);
mat_def->mutable_mat_pair()->set_mat_index(1);
mat_def->set_id("BOX_BAG");
break;
}
}
int subtypes = Items::getSubtypeCount(it);
if (subtypes >= 0)
{
for (int i = 0; i < subtypes; i++)
{
mat_def = out->add_material_list();
mat_def->mutable_mat_pair()->set_mat_type((int)it);
mat_def->mutable_mat_pair()->set_mat_index(i);
df::itemdef * item = Items::getSubtypeDef(it, i);
mat_def->set_id(ENUM_KEY_STR(item_type, it) + "/" + item->id);
}
}
}
return CR_OK;
}

@ -0,0 +1,25 @@
#ifndef ITEM_READER_H
#define ITEM_READER_H
#include <stdint.h>
#include "RemoteClient.h"
#include "RemoteFortressReader.pb.h"
#include "DataDefs.h"
namespace df
{
struct item;
struct map_block;
}
namespace MapExtras
{
struct MapCache;
}
DFHack::command_result GetItemList(DFHack::color_ostream &stream, const DFHack::EmptyMessage *in, RemoteFortressReader::MaterialList *out);
void CopyItem(RemoteFortressReader::Item * NetItem, df::item * DfItem);
void ConvertDFColorDescriptor(int16_t index, RemoteFortressReader::ColorDefinition * out);
#endif // !ITEM_READER_H

@ -60,15 +60,7 @@
#include "df/enabler.h"
#include "df/graphic.h"
#include "df/historical_figure.h"
#include "df/item.h"
#include "df/item_constructed.h"
#include "df/item_gemst.h"
#include "df/item_threadst.h"
#include "df/item_toolst.h"
#include "df/item_smallgemst.h"
#include "df/itemimprovement.h"
#include "df/itemimprovement_threadst.h"
#include "df/itemdef.h"
#include "df/job.h"
#include "df/job_type.h"
#include "df/job_item.h"
@ -96,8 +88,8 @@
#include "df/ui.h"
#include "df/unit.h"
#include "df/unit_inventory_item.h"
#include "df/vehicle.h"
#include "df/viewscreen_choose_start_sitest.h"
#include "df/vehicle.h"
#include "df/world.h"
#include "df/world_data.h"
#include "df/world_geo_biome.h"
@ -121,6 +113,7 @@
#include "adventure_control.h"
#include "building_reader.h"
#include "item_reader.h"
using namespace DFHack;
using namespace df::enums;
@ -153,7 +146,6 @@ static command_result GetUnitListInside(color_ostream &stream, const BlockReques
static command_result GetViewInfo(color_ostream &stream, const EmptyMessage *in, ViewInfo *out);
static command_result GetMapInfo(color_ostream &stream, const EmptyMessage *in, MapInfo *out);
static command_result ResetMapHashes(color_ostream &stream, const EmptyMessage *in);
static command_result GetItemList(color_ostream &stream, const EmptyMessage *in, MaterialList *out);
static command_result GetWorldMap(color_ostream &stream, const EmptyMessage *in, WorldMap *out);
static command_result GetWorldMapNew(color_ostream &stream, const EmptyMessage *in, WorldMap *out);
static command_result GetWorldMapCenter(color_ostream &stream, const EmptyMessage *in, WorldMap *out);
@ -169,7 +161,6 @@ static command_result SendDigCommand(color_ostream &stream, const DigCommand *in
static command_result SetPauseState(color_ostream & stream, const SingleBool * in);
static command_result GetPauseState(color_ostream & stream, const EmptyMessage * in, SingleBool * out);
static command_result GetVersionInfo(color_ostream & stream, const EmptyMessage * in, RemoteFortressReader::VersionInfo * out);
void CopyItem(RemoteFortressReader::Item * NetItem, df::item * DfItem);
static command_result GetReports(color_ostream & stream, const EmptyMessage * in, RemoteFortressReader::Status * out);
static command_result GetLanguage(color_ostream & stream, const EmptyMessage * in, RemoteFortressReader::Language * out);
@ -908,66 +899,6 @@ static command_result GetMaterialList(color_ostream &stream, const EmptyMessage
return CR_OK;
}
static command_result GetItemList(color_ostream &stream, const EmptyMessage *in, MaterialList *out)
{
if (!Core::getInstance().isWorldLoaded()) {
//out->set_available(false);
return CR_OK;
}
FOR_ENUM_ITEMS(item_type, it)
{
MaterialDefinition *mat_def = out->add_material_list();
mat_def->mutable_mat_pair()->set_mat_type((int)it);
mat_def->mutable_mat_pair()->set_mat_index(-1);
mat_def->set_id(ENUM_KEY_STR(item_type, it));
switch (it)
{
case df::enums::item_type::GEM:
case df::enums::item_type::SMALLGEM:
{
for (int i = 0; i < world->raws.language.shapes.size(); i++)
{
auto shape = world->raws.language.shapes[i];
if (shape->gems_use.whole == 0)
continue;
mat_def = out->add_material_list();
mat_def->mutable_mat_pair()->set_mat_type((int)it);
mat_def->mutable_mat_pair()->set_mat_index(i);
mat_def->set_id(ENUM_KEY_STR(item_type, it) + "/" + shape->id);
}
break;
}
case df::enums::item_type::BOX:
{
mat_def = out->add_material_list();
mat_def->mutable_mat_pair()->set_mat_type((int)it);
mat_def->mutable_mat_pair()->set_mat_index(0);
mat_def->set_id("BOX_CHEST");
mat_def = out->add_material_list();
mat_def->mutable_mat_pair()->set_mat_type((int)it);
mat_def->mutable_mat_pair()->set_mat_index(1);
mat_def->set_id("BOX_BAG");
break;
}
}
int subtypes = Items::getSubtypeCount(it);
if (subtypes >= 0)
{
for (int i = 0; i < subtypes; i++)
{
mat_def = out->add_material_list();
mat_def->mutable_mat_pair()->set_mat_type((int)it);
mat_def->mutable_mat_pair()->set_mat_index(i);
df::itemdef * item = Items::getSubtypeDef(it, i);
mat_def->set_id(ENUM_KEY_STR(item_type, it) + "/" + item->id);
}
}
}
return CR_OK;
}
static command_result GetGrowthList(color_ostream &stream, const EmptyMessage *in, MaterialList *out)
{
if (!Core::getInstance().isWorldLoaded()) {
@ -1403,92 +1334,6 @@ void Copyspatters(df::map_block * DfBlock, RemoteFortressReader::MapBlock * NetB
}
}
void CopyItem(RemoteFortressReader::Item * NetItem, df::item * DfItem)
{
NetItem->set_id(DfItem->id);
NetItem->set_flags1(DfItem->flags.whole);
NetItem->set_flags2(DfItem->flags2.whole);
auto pos = NetItem->mutable_pos();
pos->set_x(DfItem->pos.x);
pos->set_y(DfItem->pos.y);
pos->set_z(DfItem->pos.z);
auto mat = NetItem->mutable_material();
mat->set_mat_index(DfItem->getMaterialIndex());
mat->set_mat_type(DfItem->getMaterial());
auto type = NetItem->mutable_type();
type->set_mat_type(DfItem->getType());
type->set_mat_index(DfItem->getSubtype());
bool isProjectile = false;
if (!isProjectile && DfItem->getType() == item_type::TOOL)
{
VIRTUAL_CAST_VAR(tool, df::item_toolst, DfItem);
if (tool)
{
auto vehicle = binsearch_in_vector(world->vehicles.active, tool->vehicle_id);
if (vehicle)
{
NetItem->set_subpos_x(vehicle->offset_x / 100000.0);
NetItem->set_subpos_y(vehicle->offset_y / 100000.0);
NetItem->set_subpos_z(vehicle->offset_z / 140000.0);
}
}
}
if (DfItem->getType() == item_type::BOX)
{
type->set_mat_index(DfItem->isBag());
}
VIRTUAL_CAST_VAR(actual_item, df::item_actual, DfItem);
if (actual_item)
{
NetItem->set_stack_size(actual_item->stack_size);
}
VIRTUAL_CAST_VAR(gem_item, df::item_gemst, DfItem);
if (gem_item)
{
type->set_mat_index(gem_item->shape);
}
VIRTUAL_CAST_VAR(smallgem_item, df::item_smallgemst, DfItem);
if (smallgem_item)
{
type->set_mat_index(smallgem_item->shape);
}
VIRTUAL_CAST_VAR(constructed_item, df::item_constructed, DfItem);
if (constructed_item)
{
for (int i = 0; i < constructed_item->improvements.size(); i++)
{
auto improvement = constructed_item->improvements[i];
if (!improvement || improvement->getType() != improvement_type::THREAD)
continue;
auto improvement_thread = virtual_cast<df::itemimprovement_threadst>(improvement);
if (!improvement_thread || improvement_thread->dye.mat_type < 0)
continue;
DFHack::MaterialInfo info;
if (!info.decode(improvement_thread->dye.mat_type, improvement_thread->dye.mat_index))
continue;
ConvertDFColorDescriptor(info.material->powder_dye, NetItem->mutable_dye());
}
}
else if (DfItem->getType() == item_type::THREAD)
{
auto thread = virtual_cast<df::item_threadst>(DfItem);
if (thread && thread->dye_mat_type >= 0)
{
DFHack::MaterialInfo info;
if (info.decode(thread->dye_mat_type, thread->dye_mat_index))
ConvertDFColorDescriptor(info.material->powder_dye, NetItem->mutable_dye());
}
}
NetItem->set_volume(DfItem->getVolume());
}
void CopyItems(df::map_block * DfBlock, RemoteFortressReader::MapBlock * NetBlock, MapExtras::MapCache * MC, DFCoord pos)
{
NetBlock->set_map_x(DfBlock->map_pos.x);
@ -1498,13 +1343,13 @@ void CopyItems(df::map_block * DfBlock, RemoteFortressReader::MapBlock * NetBloc
{
int id = DfBlock->items[i];
auto item = df::item::find(id);
if (item)
CopyItem(NetBlock->add_items(), item);
}
}
static command_result GetBlockList(color_ostream &stream, const BlockRequest *in, BlockList *out)
{
int x, y, z;
@ -1684,7 +1529,7 @@ static command_result GetPlantList(color_ostream &stream, const BlockRequest *in
out_plant->set_pos_y(plant->pos.y);
out_plant->set_pos_z(plant->pos.z);
}
}
}
#endif
return CR_OK;
}
@ -2017,7 +1862,7 @@ static command_result GetWorldMap(color_ostream &stream, const EmptyMessage *in,
}
else
out->add_water_elevation(99);
}
}
DFCoord pos = GetMapCenter();
out->set_center_x(pos.x);
out->set_center_y(pos.y);