From 565f937246caa87aa281d4c1c714af9de6ef7969 Mon Sep 17 00:00:00 2001 From: Espen Wiborg Date: Wed, 28 Dec 2011 20:54:36 +0100 Subject: [PATCH 01/12] Traits are active if MORE than 10 away from 50 --- library/VersionInfo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/VersionInfo.cpp b/library/VersionInfo.cpp index e0da4ca96..c7a4c6893 100644 --- a/library/VersionInfo.cpp +++ b/library/VersionInfo.cpp @@ -1164,7 +1164,7 @@ string VersionInfo::getTrait (const uint32_t traitIdx, const uint32_t traitValue if(d->traits.size() > traitIdx) { int diff = absolute(traitValue-50); - if(diff < 10) + if(diff <= 10) { return string(""); } @@ -1253,4 +1253,4 @@ std::string VersionInfo::PrintOffsets() ss << i << "" << endl; ss << endl; return ss.str(); -} \ No newline at end of file +} From 89e3361140bc19c585dab857faa1e038cb272545 Mon Sep 17 00:00:00 2001 From: Espen Wiborg Date: Fri, 23 Dec 2011 10:58:45 +0100 Subject: [PATCH 02/12] Plugin to export for dfcareers --- plugins/export/CMakeLists.txt | 31 ++++++ plugins/export/export.cpp | 178 ++++++++++++++++++++++++++++++++++ plugins/export/export.h | 1 + 3 files changed, 210 insertions(+) create mode 100644 plugins/export/CMakeLists.txt create mode 100644 plugins/export/export.cpp create mode 100644 plugins/export/export.h diff --git a/plugins/export/CMakeLists.txt b/plugins/export/CMakeLists.txt new file mode 100644 index 000000000..1ff69fb27 --- /dev/null +++ b/plugins/export/CMakeLists.txt @@ -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}) diff --git a/plugins/export/export.cpp b/plugins/export/export.cpp new file mode 100644 index 000000000..3331948f8 --- /dev/null +++ b/plugins/export/export.cpp @@ -0,0 +1,178 @@ +// some headers required for a plugin. Nothing special, just the basics. +#include +#include +#include +#include +using namespace std; + +#define DFHACK_WANT_MISCUTILS +#include +#include +#include +#include +#include +#include +#include +using namespace DFHack; + +// 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 & 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 &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 << "" << endl; +} + +static void element(const char* name, const uint32_t content, ostream& out, const char* extra_indent="") { + out << extra_indent << " <" << name << ">" << content << "" << endl; +} + +static void printAttributes(Core* c, Translation* t, t_unit* cre, ostream& out) { + out << " " << endl; + for (int i = 0; i < NUM_CREATURE_PHYSICAL_ATTRIBUTES; i++) { + element(physicals[i], cre->origin->physical[i].unk_0, out, " "); + } + + df_soul * s = cre->origin->current_soul; + if (s) { + for (int i = 0; i < NUM_CREATURE_MENTAL_ATTRIBUTES; i++) { + element(mentals[i], s->mental[i].unk_0, out, " "); + } + } + out << " " << endl; +} + +static void printTraits(Core* c, Translation* t, t_unit* cre, ostream& out) { + out << " " << endl; + df_soul * s = cre->origin->current_soul; + if (s) { + for (int i = 0; i < NUM_CREATURE_TRAITS; i++) { + string trait = c->vinfo->getTrait(i, s->traits[i]); + if (!trait.empty()) { + element("Trait", trait.c_str(), out, " "); + } + } + } + out << " " << endl; +} + +// GDC needs: +// Name +// Nickname +// Sex +// Attributes +// Traits +static void export_dwarf(Core* c, Translation* t, t_unit* cre, ostream& out) { + string info = cre->name.first_name; + info += " "; + info += t->TranslateName(&cre->origin->name, false); + info[0] = toupper(info[0]); + c->con.print("Exporting %s\n", info.c_str()); + + out << " " << endl; + element("Name", info.c_str(), out); + element("Nickname", cre->name.nickname, out); + element("Sex", cre->sex == 0 ? "Female" : "Male", out); + printAttributes(c, t, cre, out); + printTraits(c, t, cre, out); + + out << " " << endl; +} + +DFhackCExport command_result export_dwarves (Core * c, std::vector & parameters) +{ + string filename; + if (parameters.size() == 1) { + filename = parameters[0]; + } else { + c->con.print("export \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(); + + Translation* t = c->getTranslation(); + t->Start(); + + DFHack::Units* cr = c->getUnits(); + uint32_t race = cr->GetDwarfRaceIndex(); + uint32_t civ = cr->GetDwarfCivId(); + + uint32_t num_creatures; + cr->Start(num_creatures); + + outf << "" << endl; + + for (unsigned i = 0; i < num_creatures; ++i) + { + df_unit* cre = cr->GetCreature(i); + if (cre->race == race && cre->civ == civ) { + t_unit t_cre; + cr->CopyCreature(cre, t_cre); + export_dwarf(c, t, &t_cre, outf); + } + } + outf << "" << endl; + + c->Resume(); + return CR_OK; +} diff --git a/plugins/export/export.h b/plugins/export/export.h new file mode 100644 index 000000000..7b9637ef9 --- /dev/null +++ b/plugins/export/export.h @@ -0,0 +1 @@ +#pragma once \ No newline at end of file From 12446a62e20936ad321669437e743098b5dad06c Mon Sep 17 00:00:00 2001 From: Espen Wiborg Date: Wed, 28 Dec 2011 20:59:10 +0100 Subject: [PATCH 03/12] Export exact trait value --- plugins/export/export.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/export/export.cpp b/plugins/export/export.cpp index 3331948f8..0020aaf45 100644 --- a/plugins/export/export.cpp +++ b/plugins/export/export.cpp @@ -100,10 +100,13 @@ static void printTraits(Core* c, Translation* t, t_unit* cre, ostream& out) { df_soul * s = cre->origin->current_soul; if (s) { for (int i = 0; i < NUM_CREATURE_TRAITS; i++) { + out << " "; string trait = c->vinfo->getTrait(i, s->traits[i]); if (!trait.empty()) { - element("Trait", trait.c_str(), out, " "); + out << trait.c_str(); } + out << "" << endl; } } out << " " << endl; From 6c0d5d3cd211ef4601d805f743904455e387a5e0 Mon Sep 17 00:00:00 2001 From: Espen Wiborg Date: Wed, 28 Dec 2011 20:59:49 +0100 Subject: [PATCH 04/12] Make sure the export plugin is built --- plugins/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index ab7e039a4..22b6987c0 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -61,6 +61,8 @@ DFHACK_PLUGIN(initflags initflags.cpp) DFHACK_PLUGIN(stockpiles stockpiles.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) From 21d81c8804013c835d71bfc388def3e91a201e2e Mon Sep 17 00:00:00 2001 From: Espen Wiborg Date: Wed, 28 Dec 2011 21:22:39 +0100 Subject: [PATCH 05/12] Make sure the encoding is right --- plugins/export/export.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/export/export.cpp b/plugins/export/export.cpp index 0020aaf45..e64355485 100644 --- a/plugins/export/export.cpp +++ b/plugins/export/export.cpp @@ -163,7 +163,7 @@ DFhackCExport command_result export_dwarves (Core * c, std::vector uint32_t num_creatures; cr->Start(num_creatures); - outf << "" << endl; + outf << "" << endl << "" << endl; for (unsigned i = 0; i < num_creatures; ++i) { From e9c4d12d2ae8c7bc4a9deac1e5e2797bcbb3e755 Mon Sep 17 00:00:00 2001 From: Espen Wiborg Date: Mon, 2 Jan 2012 12:52:09 +0100 Subject: [PATCH 06/12] Track upstream changes --- plugins/export/export.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/export/export.cpp b/plugins/export/export.cpp index e64355485..be38606ea 100644 --- a/plugins/export/export.cpp +++ b/plugins/export/export.cpp @@ -6,13 +6,13 @@ using namespace std; #define DFHACK_WANT_MISCUTILS -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include using namespace DFHack; // our own, empty header. From 06f1cffcbf658c47438b08816ba7a79240554927 Mon Sep 17 00:00:00 2001 From: Espen Wiborg Date: Fri, 6 Jan 2012 00:35:05 +0100 Subject: [PATCH 07/12] Add flood-fill brush to liquids (for wclean) --- plugins/liquids.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/plugins/liquids.cpp b/plugins/liquids.cpp index 17f4e6309..1ac7c7592 100644 --- a/plugins/liquids.cpp +++ b/plugins/liquids.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -141,6 +142,63 @@ 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 to_flood; + to_flood.push(start); + + std::set seen; + + while (!to_flood.empty()) { + DFCoord xy = to_flood.top(); + to_flood.pop(); + + t_designation des = mc.designationAt(xy); + + if (seen.find(xy) == seen.end() + && des.bits.flow_size && des.bits.liquid_type != liquid_magma) { + 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 &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 & parameters); @@ -224,6 +282,8 @@ DFhackCExport command_result df_liquids (Core * c, vector & 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 @@ -312,6 +372,12 @@ DFhackCExport command_result df_liquids (Core * c, vector & parameters) brushname = "column"; brush = new ColumnBrush(); } + else if(command == "flood") + { + delete brush; + brushname = "flood"; + brush = new FloodBrush(c); + } else if(command == "q") { end = true; From 8b7da08638975d3a758d0b3322dfceb531cd93aa Mon Sep 17 00:00:00 2001 From: Espen Wiborg Date: Fri, 6 Jan 2012 00:35:05 +0100 Subject: [PATCH 08/12] Add flood-fill brush to liquids (for wclean) --- plugins/liquids.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/plugins/liquids.cpp b/plugins/liquids.cpp index 17f4e6309..1ac7c7592 100644 --- a/plugins/liquids.cpp +++ b/plugins/liquids.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -141,6 +142,63 @@ 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 to_flood; + to_flood.push(start); + + std::set seen; + + while (!to_flood.empty()) { + DFCoord xy = to_flood.top(); + to_flood.pop(); + + t_designation des = mc.designationAt(xy); + + if (seen.find(xy) == seen.end() + && des.bits.flow_size && des.bits.liquid_type != liquid_magma) { + 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 &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 & parameters); @@ -224,6 +282,8 @@ DFhackCExport command_result df_liquids (Core * c, vector & 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 @@ -312,6 +372,12 @@ DFhackCExport command_result df_liquids (Core * c, vector & parameters) brushname = "column"; brush = new ColumnBrush(); } + else if(command == "flood") + { + delete brush; + brushname = "flood"; + brush = new FloodBrush(c); + } else if(command == "q") { end = true; From e068552c04600921162e376c6375f2816e066ff5 Mon Sep 17 00:00:00 2001 From: Espen Wiborg Date: Fri, 6 Jan 2012 12:10:11 +0100 Subject: [PATCH 09/12] Make gcc happy, too --- plugins/liquids.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/liquids.cpp b/plugins/liquids.cpp index 1ac7c7592..7da017938 100644 --- a/plugins/liquids.cpp +++ b/plugins/liquids.cpp @@ -191,7 +191,7 @@ public: return v; } private: - void maybeFlood(DFCoord &c, std::stack &to_flood, MapCache &mc) { + void maybeFlood(DFCoord c, std::stack &to_flood, MapCache &mc) { if (mc.testCoord(c)) { to_flood.push(c); } From 6d79255131b4f6edfe1cfcaf6e5eed20ec2cc0ca Mon Sep 17 00:00:00 2001 From: Espen Wiborg Date: Fri, 6 Jan 2012 12:10:11 +0100 Subject: [PATCH 10/12] Make gcc happy, too --- plugins/liquids.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/liquids.cpp b/plugins/liquids.cpp index 1ac7c7592..7da017938 100644 --- a/plugins/liquids.cpp +++ b/plugins/liquids.cpp @@ -191,7 +191,7 @@ public: return v; } private: - void maybeFlood(DFCoord &c, std::stack &to_flood, MapCache &mc) { + void maybeFlood(DFCoord c, std::stack &to_flood, MapCache &mc) { if (mc.testCoord(c)) { to_flood.push(c); } From cfb975a522488e099c244335ee20dee9d1065ec4 Mon Sep 17 00:00:00 2001 From: Espen Wiborg Date: Fri, 27 Jan 2012 12:06:57 +0100 Subject: [PATCH 11/12] Track upstream changes --- plugins/liquids.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/liquids.cpp b/plugins/liquids.cpp index 3f6d330fa..a2e06eccf 100644 --- a/plugins/liquids.cpp +++ b/plugins/liquids.cpp @@ -164,10 +164,11 @@ public: DFCoord xy = to_flood.top(); to_flood.pop(); - t_designation des = mc.designationAt(xy); + df::tile_designation des = mc.designationAt(xy); if (seen.find(xy) == seen.end() - && des.bits.flow_size && des.bits.liquid_type != liquid_magma) { + && des.bits.flow_size + && des.bits.liquid_type == tile_liquid::Water) { v.push_back(xy); seen.insert(xy); From 5072c6e1f4c43774d347e57fef16be0c2642a2e0 Mon Sep 17 00:00:00 2001 From: Espen Wiborg Date: Fri, 27 Jan 2012 14:46:42 +0100 Subject: [PATCH 12/12] Update the export plugin for new API --- plugins/export/export.cpp | 54 ++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/plugins/export/export.cpp b/plugins/export/export.cpp index be38606ea..4915e34c8 100644 --- a/plugins/export/export.cpp +++ b/plugins/export/export.cpp @@ -13,7 +13,18 @@ using namespace std; #include #include #include + +#include +#include +#include +#include + 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" @@ -80,24 +91,24 @@ static void element(const char* name, const uint32_t content, ostream& out, cons out << extra_indent << " <" << name << ">" << content << "" << endl; } -static void printAttributes(Core* c, Translation* t, t_unit* cre, ostream& out) { +static void printAttributes(Core* c, df::unit* cre, ostream& out) { out << " " << endl; for (int i = 0; i < NUM_CREATURE_PHYSICAL_ATTRIBUTES; i++) { - element(physicals[i], cre->origin->physical[i].unk_0, out, " "); + element(physicals[i], cre->body.physical_attrs[i].unk1, out, " "); } - df_soul * s = cre->origin->current_soul; + 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[i].unk_0, out, " "); + element(mentals[i], s->mental_attrs[i].unk1, out, " "); } } out << " " << endl; } -static void printTraits(Core* c, Translation* t, t_unit* cre, ostream& out) { +static void printTraits(Core* c, df::unit* cre, ostream& out) { out << " " << endl; - df_soul * s = cre->origin->current_soul; + df::unit_soul * s = cre->status.current_soul; if (s) { for (int i = 0; i < NUM_CREATURE_TRAITS; i++) { out << " " << endl << "" << endl; - for (unsigned i = 0; i < num_creatures; ++i) + for (int i = 0; i < world->units.all.size(); ++i) { - df_unit* cre = cr->GetCreature(i); - if (cre->race == race && cre->civ == civ) { - t_unit t_cre; - cr->CopyCreature(cre, t_cre); - export_dwarf(c, t, &t_cre, outf); + df::unit* cre = world->units.all[i]; + if (cre->race == race && cre->civ_id == civ) { + export_dwarf(c, cre, outf); } } outf << "" << endl;