Merge remote-tracking branches 'warmist/fixpositions', 'warmist/gm_editor_changes', 'rubybrowncoat/feature/fix-multiquality-gui-create-item' and 'AtomicChicken/item-trigger-fix' into develop
						commit
						d93cbd709e
					
				| @ -1,244 +0,0 @@ | ||||
| // 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; | ||||
| 
 | ||||
| DFHACK_PLUGIN("fixpositions"); | ||||
| REQUIRE_GLOBAL(world); | ||||
| 
 | ||||
| command_result df_fixdiplomats (color_ostream &out, vector<string> ¶meters) | ||||
| { | ||||
|     if (!parameters.empty()) | ||||
|         return CR_WRONG_USAGE; | ||||
| 
 | ||||
|     CoreSuspender suspend; | ||||
| 
 | ||||
|     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.own.size(); j++) | ||||
|         { | ||||
|             pos = ent->positions.own[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.own.push_back(pos); | ||||
| 
 | ||||
|                 pos->code = "DIPLOMAT"; | ||||
|                 pos->id = ent->positions.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::unk_12); | ||||
|                 pos->flags.set(entity_position_flags::unk_1a); | ||||
|                 pos->flags.set(entity_position_flags::unk_1b); | ||||
|                 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->positions.assignments.size(); j++) | ||||
|         { | ||||
|             if (ent->positions.assignments[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->positions.assignments.push_back(asn); | ||||
| 
 | ||||
|             asn->id = ent->positions.next_assignment_id++; | ||||
|             asn->position_id = pos->id; | ||||
|             asn->flags.extend(0x1F); // make room for 32 flags
 | ||||
|             asn->flags.set(0);  // and set the first one
 | ||||
|         } | ||||
|         if (update || assign) | ||||
|             fixed++; | ||||
|     } | ||||
|     out.print("Fixed %d of %d civilizations to enable tree cap diplomacy.\n", fixed, checked); | ||||
|     return CR_OK; | ||||
| } | ||||
| 
 | ||||
| command_result df_fixmerchants (color_ostream &out, vector<string> ¶meters) | ||||
| { | ||||
|     if (!parameters.empty()) | ||||
|         return CR_WRONG_USAGE; | ||||
| 
 | ||||
|     CoreSuspender suspend; | ||||
| 
 | ||||
|     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.own.size(); j++) | ||||
|         { | ||||
|             pos = ent->positions.own[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.own.push_back(pos); | ||||
| 
 | ||||
|                 pos->code = "GUILD_REPRESENTATIVE"; | ||||
|                 pos->id = ent->positions.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::unk_12); | ||||
|                 pos->flags.set(entity_position_flags::unk_1a); | ||||
|                 pos->flags.set(entity_position_flags::unk_1b); | ||||
|                 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->positions.assignments.size(); j++) | ||||
|         { | ||||
|             if (ent->positions.assignments[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->positions.assignments.push_back(asn); | ||||
| 
 | ||||
|             asn->id = ent->positions.next_assignment_id++; | ||||
|             asn->position_id = pos->id; | ||||
|             asn->flags.extend(0x1F); // make room for 32 flags
 | ||||
|             asn->flags.set(0);  // and set the first one
 | ||||
|         } | ||||
|         if (update || assign) | ||||
|             fixed++; | ||||
|     } | ||||
|     out.print("Fixed %d of %d civilizations to enable merchant nobility.\n", fixed, checked); | ||||
|     return CR_OK; | ||||
| } | ||||
| 
 | ||||
| DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands) | ||||
| { | ||||
|     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 ( color_ostream &out ) | ||||
| { | ||||
|     return CR_OK; | ||||
| } | ||||
| @ -0,0 +1,106 @@ | ||||
| -- Add Elven diplomats to negotiate tree caps | ||||
| --[[=begin | ||||
| 
 | ||||
| fix/diplomats | ||||
| ============= | ||||
| Adds a Diplomat position to all Elven civilizations, allowing them to negotiate | ||||
| tree cutting quotas - and you to violate them and start wars. | ||||
| This was vanilla behaviour until ``0.31.12``, in which the "bug" was "fixed". | ||||
| 
 | ||||
| =end]] | ||||
| 
 | ||||
| 
 | ||||
| function update_pos(ent) | ||||
|     local pos = df.entity_position:new() | ||||
|     ent.positions.own:insert('#', pos) | ||||
| 
 | ||||
|     pos.code = "DIPLOMAT" | ||||
|     pos.id = ent.positions.next_position_id + 1 | ||||
|     ent.positions.next_position_id = ent.positions.next_position_id + 1 | ||||
|      | ||||
|     pos.flags.DO_NOT_CULL = true | ||||
|     pos.flags.MENIAL_WORK_EXEMPTION = true | ||||
|     pos.flags.SLEEP_PRETENSION = true | ||||
|     pos.flags.PUNISHMENT_EXEMPTION = true | ||||
|     pos.flags.ACCOUNT_EXEMPT = true | ||||
|     pos.flags.DUTY_BOUND = true | ||||
|     pos.flags.COLOR = true | ||||
|     pos.flags.HAS_RESPONSIBILITIES = true | ||||
|     pos.flags.IS_DIPLOMAT = true | ||||
|     pos.flags.IS_LEADER = true | ||||
|     -- not sure what these flags do, but the game sets them for a valid diplomat | ||||
|     pos.flags.unk_12 = true | ||||
|     pos.flags.unk_1a = true | ||||
|     pos.flags.unk_1b = true | ||||
|     pos.name[0] = "Diplomat" | ||||
|     pos.name[1] = "Diplomats" | ||||
|     pos.precedence = 70 | ||||
|     pos.color[0] = 7 | ||||
|     pos.color[1] = 0 | ||||
|     pos.color[2] = 1 | ||||
| 
 | ||||
|     return pos | ||||
| end | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| local checked = 0 | ||||
| local fixed = 0 | ||||
| 
 | ||||
| for _,ent in pairs(df.global.world.entities.all) do | ||||
|     if ent.type == df.historical_entity_type.Civilization and ent.entity_raw.flags.TREE_CAP_DIPLOMACY then | ||||
|         checked = checked + 1 | ||||
| 
 | ||||
|         update = true | ||||
|         local found_position | ||||
|         -- see if we need to add a new position or modify an existing one | ||||
|         for _,pos in pairs(ent.positions.own) do | ||||
|             if  pos.responsibilities.MAKE_INTRODUCTIONS and | ||||
|                 pos.responsibilities.MAKE_PEACE_AGREEMENTS and | ||||
|                 pos.responsibilities.MAKE_TOPIC_AGREEMENTS then | ||||
|                     -- a diplomat position exists with the proper responsibilities - skip to the end | ||||
|                     update = false | ||||
|                     found_position=pos | ||||
|                     break | ||||
|             end | ||||
|             -- Diplomat position already exists, but has the wrong options - modify it instead of creating a new one | ||||
|             if pos.code == "DIPLOMAT" then | ||||
|                 found_position=pos | ||||
|                 break | ||||
|             end | ||||
|         end | ||||
|         if update then | ||||
|             -- either there's no diplomat, or there is one and it's got the wrong responsibilities | ||||
|             if not found_position then | ||||
|                 found_position = add_guild_rep( ent ) | ||||
|             end | ||||
|             -- assign responsibilities | ||||
|             found_position.responsibilities.MAKE_INTRODUCTIONS = true | ||||
|             found_position.responsibilities.MAKE_PEACE_AGREEMENTS = true | ||||
|             found_position.responsibilities.MAKE_TOPIC_AGREEMENTS = true | ||||
|         end | ||||
|         -- make sure the diplomat position, whether we created it or not, is set up for proper assignment | ||||
|         local assign = true | ||||
|         for _,p in pairs(ent.positions.assignments) do | ||||
|             if p.position_id == found_position.id then -- it is - nothing more to do here | ||||
|                 assign = false | ||||
|                 break | ||||
|             end | ||||
|         end | ||||
|         if assign then -- it isn't - set it up | ||||
|             local asn = df.entity_position_assignment:new() | ||||
|             ent.positions.assignments:insert('#', asn); | ||||
| 
 | ||||
|             asn.id = ent.positions.next_assignment_id | ||||
|             ent.positions.next_assignment_id = asn.id + 1 | ||||
|             asn.position_id = found_position.id | ||||
|             asn.flags:resize(math.max(32, #asn.flags)) -- make room for 32 flags | ||||
|             asn.flags[0] = true  -- and set the first one | ||||
|         end | ||||
|         if update or assign then | ||||
|             fixed = fixed + 1 | ||||
|         end | ||||
|     end | ||||
| end | ||||
| 
 | ||||
| print("Enabled tree cap diplomacy for "..fixed.." of "..checked.." civilizations.") | ||||
| @ -0,0 +1,104 @@ | ||||
| -- Allow humans to make trade agreements | ||||
| --[[=begin | ||||
| 
 | ||||
| fix/merchants | ||||
| ============= | ||||
| Adds the Guild Representative position to all Human civilizations, | ||||
| allowing them to make trade agreements.  This was the default behaviour in | ||||
| ``0.28.181.40d`` and earlier. | ||||
| 
 | ||||
| =end]] | ||||
| 
 | ||||
| 
 | ||||
| function add_guild_rep(ent) | ||||
|     -- there was no guild rep - create it | ||||
|     local pos = df.entity_position:new() | ||||
|     ent.positions.own:insert('#', pos) | ||||
| 
 | ||||
|     pos.code = "GUILD_REPRESENTATIVE" | ||||
|     pos.id = ent.positions.next_position_id + 1 | ||||
|     ent.positions.next_position_id = ent.positions.next_position_id + 1 | ||||
| 
 | ||||
|     pos.flags.DO_NOT_CULL = true | ||||
|     pos.flags.MENIAL_WORK_EXEMPTION = true | ||||
|     pos.flags.SLEEP_PRETENSION = true | ||||
|     pos.flags.PUNISHMENT_EXEMPTION = true | ||||
|     pos.flags.ACCOUNT_EXEMPT = true | ||||
|     pos.flags.DUTY_BOUND = true | ||||
|     pos.flags.COLOR = true | ||||
|     pos.flags.HAS_RESPONSIBILITIES = true | ||||
|     pos.flags.IS_DIPLOMAT = true | ||||
|     pos.flags.IS_LEADER = true | ||||
|     -- not sure what these flags do, but the game sets them for a valid guild rep | ||||
|     pos.flags.unk_12 = true | ||||
|     pos.flags.unk_1a = true | ||||
|     pos.flags.unk_1b = true | ||||
|     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 | ||||
|      | ||||
|     return pos | ||||
| end | ||||
| 
 | ||||
| local checked = 0 | ||||
| local fixed = 0 | ||||
| 
 | ||||
| for _,ent in pairs(df.global.world.entities.all) do | ||||
|     if ent.type == df.historical_entity_type.Civilization and ent.entity_raw.flags.MERCHANT_NOBILITY then | ||||
|         checked = checked + 1 | ||||
| 
 | ||||
|         update = true | ||||
|         -- see if we need to add a new position or modify an existing one | ||||
|         local found_position | ||||
|         for _,pos in pairs(ent.positions.own) do | ||||
|             if pos.responsibilities.TRADE and pos.responsibilities.ESTABLISH_COLONY_TRADE_AGREEMENTS then | ||||
|                 -- a guild rep exists with the proper responsibilities - skip to the end | ||||
|                 update = false | ||||
|                 found_position=pos | ||||
|                 break | ||||
|             end | ||||
|             -- Guild Representative position already exists, but has the wrong options - modify it instead of creating a new one | ||||
|             if pos.code == "GUILD_REPRESENTATIVE" then | ||||
|                 found_position=pos | ||||
|                 break | ||||
|             end | ||||
|         end | ||||
|         if update then | ||||
|             -- either there's no guild rep, or there is one and it's got the wrong responsibilities | ||||
|             if not found_position then | ||||
|                 found_position = add_guild_rep(ent) | ||||
|             end | ||||
|             -- assign responsibilities | ||||
|             found_position.responsibilities.ESTABLISH_COLONY_TRADE_AGREEMENTS = true | ||||
|             found_position.responsibilities.TRADE=true | ||||
|         end | ||||
| 
 | ||||
|         -- make sure the guild rep position, whether we created it or not, is set up for proper assignment | ||||
|         local assign = true | ||||
|         for _,p in pairs(ent.positions.assignments) do | ||||
|             if p.position_id == found_position.id then -- it is - nothing more to do here | ||||
|                 assign = false | ||||
|                 break | ||||
|             end | ||||
|         end | ||||
|         if assign then | ||||
|             -- it isn't - set it up | ||||
|             local asn = df.entity_position_assignment:new() | ||||
|             ent.positions.assignments:insert('#', asn) | ||||
| 
 | ||||
|             asn.id = ent.positions.next_assignment_id | ||||
|             ent.positions.next_assignment_id = asn.id + 1 | ||||
|             asn.position_id = found_position.id | ||||
|             asn.flags:resize(math.max(32, #asn.flags)) -- make room for 32 flags | ||||
|             asn.flags[0] = true  -- and set the first one | ||||
|         end | ||||
|         if update or assign then | ||||
|             fixed = fixed + 1 | ||||
|         end | ||||
|     end | ||||
| end | ||||
| 
 | ||||
| print("Added merchant nobility for "..fixed.." of "..checked.." civilizations.") | ||||
		Loading…
	
		Reference in New Issue