summaryrefslogtreecommitdiff
path: root/plugins/fixpositions.cpp
diff options
context:
space:
mode:
authorQuietust2012-02-04 20:45:45 -0600
committerQuietust2012-02-04 20:45:45 -0600
commite9118dceebc18259ab74bd25a71eb3557157df7c (patch)
tree3a5cb3961c0073074eeedd65e9991401a93e8abe /plugins/fixpositions.cpp
parent4c8717477cc2b9a63ff880e15dd4e6053693a221 (diff)
downloaddfhack-e9118dceebc18259ab74bd25a71eb3557157df7c.tar.gz
dfhack-e9118dceebc18259ab74bd25a71eb3557157df7c.tar.bz2
dfhack-e9118dceebc18259ab74bd25a71eb3557157df7c.tar.xz
Add fixpositions plugin - adds Elven Diplomats and Human Merchant Nobles to existing worlds
Diffstat (limited to 'plugins/fixpositions.cpp')
-rw-r--r--plugins/fixpositions.cpp255
1 files changed, 255 insertions, 0 deletions
diff --git a/plugins/fixpositions.cpp b/plugins/fixpositions.cpp
new file mode 100644
index 00000000..d15cf3e8
--- /dev/null
+++ b/plugins/fixpositions.cpp
@@ -0,0 +1,255 @@
+// Fix Entity Positions - make sure Elves have diplomats and Humans have guild representatives
+
+#include "Core.h"
+#include <Console.h>
+#include <Export.h>
+#include <PluginManager.h>
+
+#include <DataDefs.h>
+#include "df/world.h"
+#include "df/historical_entity.h"
+#include "df/entity_raw.h"
+#include "df/entity_position.h"
+#include "df/entity_position_responsibility.h"
+#include "df/entity_position_assignment.h"
+
+using std::string;
+using std::vector;
+using namespace DFHack;
+using namespace df::enums;
+
+using df::global::world;
+
+command_result df_fixdiplomats (Core *c, vector<string> &parameters)
+{
+ if (!parameters.empty())
+ return CR_WRONG_USAGE;
+
+ CoreSuspender suspend(c);
+ int checked = 0, fixed = 0;
+ for (int i = 0; i < world->entities.all.size(); i++)
+ {
+ df::historical_entity *ent = world->entities.all[i];
+ // only work with civilizations - ignore groups and religions
+ if (ent->type != 0)
+ continue;
+ // only add diplomats for tree cap diplomacy
+ if (!ent->entity_raw->flags.is_set(entity_raw_flags::TREE_CAP_DIPLOMACY))
+ continue;
+ checked++;
+
+ bool update = true;
+ df::entity_position *pos = NULL;
+ // see if we need to add a new position or modify an existing one
+ for (int j = 0; j < ent->positions.size(); j++)
+ {
+ pos = ent->positions[j];
+ if (pos->responsibilities[entity_position_responsibility::MAKE_INTRODUCTIONS] &&
+ pos->responsibilities[entity_position_responsibility::MAKE_PEACE_AGREEMENTS] &&
+ pos->responsibilities[entity_position_responsibility::MAKE_TOPIC_AGREEMENTS])
+ {
+ // a diplomat position exists with the proper responsibilities - skip to the end
+ update = false;
+ break;
+ }
+ // Diplomat position already exists, but has the wrong options - modify it instead of creating a new one
+ if (pos->code == "DIPLOMAT")
+ break;
+ pos = NULL;
+ }
+ if (update)
+ {
+ // either there's no diplomat, or there is one and it's got the wrong responsibilities
+ if (!pos)
+ {
+ // there was no diplomat - create it
+ pos = new df::entity_position;
+ ent->positions.push_back(pos);
+
+ pos->code = "DIPLOMAT";
+ pos->id = ent->next_position_id++;
+ pos->flags.set(entity_position_flags::DO_NOT_CULL);
+ pos->flags.set(entity_position_flags::MENIAL_WORK_EXEMPTION);
+ pos->flags.set(entity_position_flags::SLEEP_PRETENSION);
+ pos->flags.set(entity_position_flags::PUNISHMENT_EXEMPTION);
+ pos->flags.set(entity_position_flags::ACCOUNT_EXEMPT);
+ pos->flags.set(entity_position_flags::DUTY_BOUND);
+ pos->flags.set(entity_position_flags::COLOR);
+ pos->flags.set(entity_position_flags::HAS_RESPONSIBILITIES);
+ pos->flags.set(entity_position_flags::IS_DIPLOMAT);
+ pos->flags.set(entity_position_flags::IS_LEADER);
+ // not sure what these flags do, but the game sets them for a valid diplomat
+ pos->flags.set(entity_position_flags::anon_1);
+ pos->flags.set(entity_position_flags::anon_3);
+ pos->flags.set(entity_position_flags::anon_4);
+ pos->name[0] = "Diplomat";
+ pos->name[1] = "Diplomats";
+ pos->precedence = 70;
+ pos->color[0] = 7;
+ pos->color[1] = 0;
+ pos->color[2] = 1;
+ }
+ // assign responsibilities
+ pos->responsibilities[entity_position_responsibility::MAKE_INTRODUCTIONS] = true;
+ pos->responsibilities[entity_position_responsibility::MAKE_PEACE_AGREEMENTS] = true;
+ pos->responsibilities[entity_position_responsibility::MAKE_TOPIC_AGREEMENTS] = true;
+ }
+
+ // make sure the diplomat position, whether we created it or not, is set up for proper assignment
+ bool assign = true;
+ for (int j = 0; j < ent->position_assignment.size(); j++)
+ {
+ if (ent->position_assignment[j]->position_id == pos->id)
+ {
+ // it is - nothing more to do here
+ assign = false;
+ break;
+ }
+ }
+ if (assign)
+ {
+ // it isn't - set it up
+ df::entity_position_assignment *asn = new df::entity_position_assignment;
+ ent->position_assignment.push_back(asn);
+
+ asn->id = ent->next_position_assignment_id++;
+ asn->histfig = -1;
+ asn->position_id = pos->id;
+ asn->flags.extend(0x1F); // make room for 32 flags
+ asn->flags.set(0); // and set the first one
+ asn->anon_1 = -1;
+ asn->anon_2 = -1;
+ asn->anon_3 = -1;
+ }
+ if (update || assign)
+ fixed++;
+ }
+ c->con.print("Fixed %d of %d civilizations to enable tree cap diplomacy.\n", fixed, checked);
+ return CR_OK;
+}
+
+command_result df_fixmerchants (Core *c, vector<string> &parameters)
+{
+ if (!parameters.empty())
+ return CR_WRONG_USAGE;
+
+ CoreSuspender suspend(c);
+ int checked = 0, fixed = 0;
+ for (int i = 0; i < world->entities.all.size(); i++)
+ {
+ df::historical_entity *ent = world->entities.all[i];
+ // only work with civilizations - ignore groups and religions
+ if (ent->type != 0)
+ continue;
+ // only add guild reps for merchant nobility
+ if (!ent->entity_raw->flags.is_set(entity_raw_flags::MERCHANT_NOBILITY))
+ continue;
+ checked++;
+
+ bool update = true;
+ df::entity_position *pos = NULL;
+ // see if we need to add a new position or modify an existing one
+ for (int j = 0; j < ent->positions.size(); j++)
+ {
+ pos = ent->positions[j];
+ if (pos->responsibilities[entity_position_responsibility::TRADE])
+ {
+ // a guild rep exists with the proper responsibilities - skip to the end
+ update = false;
+ break;
+ }
+ // Guild Representative position already exists, but has the wrong options - modify it instead of creating a new one
+ if (pos->code == "GUILD_REPRESENTATIVE")
+ break;
+ pos = NULL;
+ }
+ if (update)
+ {
+ // either there's no guild rep, or there is one and it's got the wrong responsibilities
+ if (!pos)
+ {
+ // there was no guild rep - create it
+ pos = new df::entity_position;
+ ent->positions.push_back(pos);
+
+ pos->code = "GUILD_REPRESENTATIVE";
+ pos->id = ent->next_position_id++;
+ pos->flags.set(entity_position_flags::DO_NOT_CULL);
+ pos->flags.set(entity_position_flags::MENIAL_WORK_EXEMPTION);
+ pos->flags.set(entity_position_flags::SLEEP_PRETENSION);
+ pos->flags.set(entity_position_flags::PUNISHMENT_EXEMPTION);
+ pos->flags.set(entity_position_flags::ACCOUNT_EXEMPT);
+ pos->flags.set(entity_position_flags::DUTY_BOUND);
+ pos->flags.set(entity_position_flags::COLOR);
+ pos->flags.set(entity_position_flags::HAS_RESPONSIBILITIES);
+ pos->flags.set(entity_position_flags::IS_DIPLOMAT);
+ pos->flags.set(entity_position_flags::IS_LEADER);
+ // not sure what these flags do, but the game sets them for a valid guild rep
+ pos->flags.set(entity_position_flags::anon_1);
+ pos->flags.set(entity_position_flags::anon_3);
+ pos->flags.set(entity_position_flags::anon_4);
+ pos->name[0] = "Guild Representative";
+ pos->name[1] = "Guild Representatives";
+ pos->precedence = 40;
+ pos->color[0] = 7;
+ pos->color[1] = 0;
+ pos->color[2] = 1;
+ }
+ // assign responsibilities
+ pos->responsibilities[entity_position_responsibility::TRADE] = true;
+ }
+
+ // make sure the guild rep position, whether we created it or not, is set up for proper assignment
+ bool assign = true;
+ for (int j = 0; j < ent->position_assignment.size(); j++)
+ {
+ if (ent->position_assignment[j]->position_id == pos->id)
+ {
+ // it is - nothing more to do here
+ assign = false;
+ break;
+ }
+ }
+ if (assign)
+ {
+ // it isn't - set it up
+ df::entity_position_assignment *asn = new df::entity_position_assignment;
+ ent->position_assignment.push_back(asn);
+
+ asn->id = ent->next_position_assignment_id++;
+ asn->histfig = -1;
+ asn->position_id = pos->id;
+ asn->flags.extend(0x1F); // make room for 32 flags
+ asn->flags.set(0); // and set the first one
+ asn->anon_1 = -1;
+ asn->anon_2 = -1;
+ asn->anon_3 = -1;
+ }
+ if (update || assign)
+ fixed++;
+ }
+ c->con.print("Fixed %d of %d civilizations to enable merchant nobility.\n", fixed, checked);
+ return CR_OK;
+}
+
+DFhackCExport const char * plugin_name ( void )
+{
+ return "fixpositions";
+}
+
+DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands)
+{
+ commands.clear();
+ commands.push_back(PluginCommand(
+ "fixdiplomats", "Add Diplomat position to Elven civilizations for tree cap diplomacy.",
+ df_fixdiplomats, false));
+ commands.push_back(PluginCommand(
+ "fixmerchants", "Add Guild Representative position to Human civilizations for merchant nobility.",
+ df_fixmerchants, false));
+ return CR_OK;
+}
+
+DFhackCExport command_result plugin_shutdown ( Core * c )
+{
+ return CR_OK;
+}