Merge branch 'export-plugin' of https://github.com/espenhw/dfhack

develop
Petr Mrázek 2012-02-05 20:05:19 +01:00
commit 7d8a176e59
5 changed files with 284 additions and 0 deletions

@ -74,6 +74,8 @@ DFHACK_PLUGIN(fixveins fixveins.cpp)
DFHACK_PLUGIN(fixpositions fixpositions.cpp)
#DFHACK_PLUGIN(versionosd versionosd.cpp)
add_subdirectory(export)
# this is the skeleton plugin. If you want to make your own, make a copy and then change it
OPTION(BUILD_SKELETON "Build the skeleton plugin." OFF)
if(BUILD_SKELETON)

@ -0,0 +1,31 @@
PROJECT (export)
# A list of source files
SET(PROJECT_SRCS
export.cpp
)
# A list of headers
SET(PROJECT_HDRS
export.h
)
SET_SOURCE_FILES_PROPERTIES( ${PROJECT_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE)
# mash them together (headers are marked as headers and nothing will try to compile them)
LIST(APPEND PROJECT_SRCS ${PROJECT_HDRS})
#linux
IF(UNIX)
add_definitions(-DLINUX_BUILD)
SET(PROJECT_LIBS
# add any extra linux libs here
${PROJECT_LIBS}
)
# windows
ELSE(UNIX)
SET(PROJECT_LIBS
# add any extra linux libs here
${PROJECT_LIBS}
$(NOINHERIT)
)
ENDIF(UNIX)
# this makes sure all the stuff is put in proper places and linked to dfhack
DFHACK_PLUGIN(export ${PROJECT_SRCS} LINK_LIBRARIES ${PROJECT_LIBS})

@ -0,0 +1,183 @@
// some headers required for a plugin. Nothing special, just the basics.
#include <vector>
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
#define DFHACK_WANT_MISCUTILS
#include <Core.h>
#include <VersionInfo.h>
#include <Console.h>
#include <Export.h>
#include <PluginManager.h>
#include <modules/Units.h>
#include <modules/Translation.h>
#include <df/ui.h>
#include <df/world.h>
#include <df/unit.h>
#include <df/unit_soul.h>
using namespace DFHack;
using namespace DFHack::Simple;
using namespace DFHack::Simple;
using df::global::ui;
using df::global::world;
// our own, empty header.
#include "export.h"
// Here go all the command declarations...
// mostly to allow having the mandatory stuff on top of the file and commands on the bottom
DFhackCExport command_result export_dwarves (Core * c, std::vector <std::string> & parameters);
// A plugins must be able to return its name. This must correspond to the filename - export.plug.so or export.plug.dll
DFhackCExport const char * plugin_name ( void )
{
return "export";
}
// Mandatory init function. If you have some global state, create it here.
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands)
{
// Fill the command list with your commands.
commands.clear();
commands.push_back(PluginCommand("export",
"Export dwarves to RuneSmith-compatible XML.",
export_dwarves /*,
true or false - true means that the command can't be used from non-interactive user interface'*/));
return CR_OK;
}
// This is called right before the plugin library is removed from memory.
DFhackCExport command_result plugin_shutdown ( Core * c )
{
return CR_OK;
}
static char* physicals[] = {
"Strength",
"Agility",
"Toughness",
"Endurance",
"Recuperation",
"DiseaseResistance",
};
static char* mentals[] = {
"Willpower",
"Memory",
"Focus",
"Intuition",
"Patience",
"Empathy",
"SocialAwareness",
"Creatvity", //Speeling deliberate
"Musicality",
"AnalyticalAbility",
"LinguisticAbility",
"SpatialSense",
"KinaestheticSense",
};
static void element(const char* name, const char* content, ostream& out, const char* extra_indent="") {
out << extra_indent << " <" << name << ">" << content << "</" << name << ">" << endl;
}
static void element(const char* name, const uint32_t content, ostream& out, const char* extra_indent="") {
out << extra_indent << " <" << name << ">" << content << "</" << name << ">" << endl;
}
static void printAttributes(Core* c, df::unit* cre, ostream& out) {
out << " <Attributes>" << endl;
for (int i = 0; i < NUM_CREATURE_PHYSICAL_ATTRIBUTES; i++) {
element(physicals[i], cre->body.physical_attrs[i].unk1, out, " ");
}
df::unit_soul * s = cre->status.current_soul;
if (s) {
for (int i = 0; i < NUM_CREATURE_MENTAL_ATTRIBUTES; i++) {
element(mentals[i], s->mental_attrs[i].unk1, out, " ");
}
}
out << " </Attributes>" << endl;
}
static void printTraits(Core* c, df::unit* cre, ostream& out) {
out << " <Traits>" << endl;
df::unit_soul * s = cre->status.current_soul;
if (s) {
for (int i = 0; i < NUM_CREATURE_TRAITS; i++) {
out << " <Trait name='" << c->vinfo->getTraitName(i) <<
"' value='" << s->traits[i] << "'>";
string trait = c->vinfo->getTrait(i, s->traits[i]);
if (!trait.empty()) {
out << trait.c_str();
}
out << "</Trait>" << endl;
}
}
out << " </Traits>" << endl;
}
// GDC needs:
// Name
// Nickname
// Sex
// Attributes
// Traits
static void export_dwarf(Core* c, df::unit* cre, ostream& out) {
string info = cre->name.first_name;
info += " ";
info += Translation::TranslateName(&cre->name, false);
info[0] = toupper(info[0]);
c->con.print("Exporting %s\n", info.c_str());
out << " <Creature>" << endl;
element("Name", info.c_str(), out);
element("Nickname", cre->name.nickname.c_str(), out);
element("Sex", cre->sex == 0 ? "Female" : "Male", out);
printAttributes(c, cre, out);
printTraits(c, cre, out);
out << " </Creature>" << endl;
}
DFhackCExport command_result export_dwarves (Core * c, std::vector <std::string> & parameters)
{
string filename;
if (parameters.size() == 1) {
filename = parameters[0];
} else {
c->con.print("export <filename>\n");
return CR_OK;
}
ofstream outf(filename);
if (!outf) {
c->con.printerr("Failed to open file %s\n", filename.c_str());
return CR_FAILURE;
}
c->Suspend();
uint32_t race = ui->race_id;
uint32_t civ = ui->civ_id;
outf << "<?xml version='1.0' encoding='ibm850'?>" << endl << "<Creatures>" << endl;
for (int i = 0; i < world->units.all.size(); ++i)
{
df::unit* cre = world->units.all[i];
if (cre->race == race && cre->civ_id == civ) {
export_dwarf(c, cre, outf);
}
}
outf << "</Creatures>" << endl;
c->Resume();
return CR_OK;
}

@ -0,0 +1 @@
#pragma once

@ -1,5 +1,6 @@
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cstdlib>
@ -141,6 +142,64 @@ public:
};
};
/**
* Flood-fill water tiles from cursor (for wclean)
* example: remove salt flag from a river
*/
class FloodBrush : public Brush
{
public:
FloodBrush(Core *c){c_ = c;};
~FloodBrush(){};
coord_vec points(MapCache & mc, DFHack::DFCoord start)
{
coord_vec v;
std::stack<DFCoord> to_flood;
to_flood.push(start);
std::set<DFCoord> seen;
while (!to_flood.empty()) {
DFCoord xy = to_flood.top();
to_flood.pop();
df::tile_designation des = mc.designationAt(xy);
if (seen.find(xy) == seen.end()
&& des.bits.flow_size
&& des.bits.liquid_type == tile_liquid::Water) {
v.push_back(xy);
seen.insert(xy);
maybeFlood(DFCoord(xy.x - 1, xy.y, xy.z), to_flood, mc);
maybeFlood(DFCoord(xy.x + 1, xy.y, xy.z), to_flood, mc);
maybeFlood(DFCoord(xy.x, xy.y - 1, xy.z), to_flood, mc);
maybeFlood(DFCoord(xy.x, xy.y + 1, xy.z), to_flood, mc);
uint16_t tt = mc.tiletypeAt(xy);
if (LowPassable(tt))
{
maybeFlood(DFCoord(xy.x, xy.y, xy.z - 1), to_flood, mc);
}
if (HighPassable(tt))
{
maybeFlood(DFCoord(xy.x, xy.y, xy.z + 1), to_flood, mc);
}
}
}
return v;
}
private:
void maybeFlood(DFCoord c, std::stack<DFCoord> &to_flood, MapCache &mc) {
if (mc.testCoord(c)) {
to_flood.push(c);
}
}
Core *c_;
};
CommandHistory liquids_hist;
DFhackCExport command_result df_liquids (Core * c, vector <string> & parameters);
@ -229,6 +288,8 @@ DFhackCExport command_result df_liquids (Core * c, vector <string> & parameters)
<< "block - DF map block with cursor in it" << endl
<< " (regular spaced 16x16x1 blocks)" << endl
<< "column - Column from cursor, up through free space" << endl
<< "flood - Flood-fill water tiles from cursor" << endl
<< " (only makes sense with wclean)" << endl
<< "Other:" << endl
<< "q - quit" << endl
<< "help or ? - print this list of commands" << endl
@ -317,6 +378,12 @@ DFhackCExport command_result df_liquids (Core * c, vector <string> & parameters)
brushname = "column";
brush = new ColumnBrush();
}
else if(command == "flood")
{
delete brush;
brushname = "flood";
brush = new FloodBrush(c);
}
else if(command == "q")
{
end = true;