summaryrefslogtreecommitdiff
path: root/plugins/jobutils.cpp
diff options
context:
space:
mode:
authorAlexander Gavrilov2012-01-04 19:39:38 +0400
committerAlexander Gavrilov2012-01-04 19:39:38 +0400
commit284009e873b95eed32fae62703ab3bc59e8e905b (patch)
tree717be1878c3e3bd6374a1dcabccb9c31759eb418 /plugins/jobutils.cpp
parent99dda069de241920b19ad99ba8dbc88f166f1d91 (diff)
downloaddfhack-284009e873b95eed32fae62703ab3bc59e8e905b.tar.gz
dfhack-284009e873b95eed32fae62703ab3bc59e8e905b.tar.bz2
dfhack-284009e873b95eed32fae62703ab3bc59e8e905b.tar.xz
Add a hotkey command to duplicate jobs in workshops.
Diffstat (limited to 'plugins/jobutils.cpp')
-rw-r--r--plugins/jobutils.cpp100
1 files changed, 97 insertions, 3 deletions
diff --git a/plugins/jobutils.cpp b/plugins/jobutils.cpp
index 71ecc2b2..bca8696f 100644
--- a/plugins/jobutils.cpp
+++ b/plugins/jobutils.cpp
@@ -17,8 +17,11 @@
#include <df/building_furnacest.h>
#include <df/job.h>
#include <df/job_item.h>
+#include <df/job_list_link.h>
#include <df/item.h>
#include <df/tool_uses.h>
+#include <df/general_ref.h>
+#include <df/general_ref_unit_workerst.h>
using std::vector;
using std::string;
@@ -30,13 +33,16 @@ using df::global::world;
using df::global::ui;
using df::global::ui_build_selector;
using df::global::ui_workshop_job_cursor;
+using df::global::job_next_id;
-static bool wokshop_job_hotkey(Core *c, df::viewscreen *top);
-static bool build_selector_hotkey(Core *c, df::viewscreen *top);
+/* Plugin registration */
+static bool workshop_job_hotkey(Core *c, df::viewscreen *top);
+static bool build_selector_hotkey(Core *c, df::viewscreen *top);
static bool job_material_hotkey(Core *c, df::viewscreen *top);
-static command_result job_material(Core *c, vector <string> & parameters);
+static command_result job_material(Core *c, vector <string> & parameters);
+static command_result job_duplicate(Core *c, vector <string> & parameters);
static command_result job_cmd(Core *c, vector <string> & parameters);
DFhackCExport const char * plugin_name ( void )
@@ -75,6 +81,17 @@ DFhackCExport command_result plugin_init (Core *c, std::vector <PluginCommand> &
);
}
+ if (ui_workshop_job_cursor && job_next_id) {
+ commands.push_back(
+ PluginCommand(
+ "job-duplicate", "Duplicate the selected job in a workshop.",
+ job_duplicate, workshop_job_hotkey,
+ " - In 'q' mode, when a job is highlighted within a workshop\n"
+ " or furnace building, instantly duplicates the job.\n"
+ )
+ );
+ }
+
return CR_OK;
}
@@ -83,6 +100,8 @@ DFhackCExport command_result plugin_shutdown ( Core * c )
return CR_OK;
}
+/* UI state guards */
+
static bool workshop_job_hotkey(Core *c, df::viewscreen *top)
{
using namespace ui_sidebar_mode;
@@ -150,6 +169,8 @@ static bool job_material_hotkey(Core *c, df::viewscreen *top)
build_selector_hotkey(c, top);
}
+/* job-material implementation */
+
static df::job *getWorkshopJob(Core *c)
{
df::building *selected = world->selected_building;
@@ -288,6 +309,79 @@ static command_result job_material(Core * c, vector <string> & parameters)
return CR_WRONG_USAGE;
}
+/* job-duplicate implementation */
+
+static df::job *clone_job(df::job *job)
+{
+ df::job *pnew = new df::job(*job);
+
+ pnew->id = (*job_next_id)++;
+
+ // Clean out transient fields
+ pnew->flags.whole = 0;
+ pnew->flags.bits.repeat = job->flags.bits.repeat;
+
+ pnew->completion_timer = -1;
+ pnew->items.clear();
+ pnew->misc_links.clear();
+
+ // Link the job into the global list
+ pnew->list_link = new df::job_list_link();
+ pnew->list_link->item = pnew;
+
+ linked_list_append(&world->job_list, pnew->list_link);
+
+ // Clone refs
+ for (int i = pnew->references.size()-1; i >= 0; i--)
+ {
+ df::general_ref *ref = pnew->references[i];
+
+ if (virtual_cast<df::general_ref_unit_workerst>(ref))
+ pnew->references.erase(pnew->references.begin()+i);
+ else
+ pnew->references[i] = ref->clone();
+ }
+
+ // Clone items
+ for (int i = pnew->job_items.size()-1; i >= 0; i--)
+ pnew->job_items[i] = new df::job_item(*pnew->job_items[i]);
+
+ return pnew;
+}
+
+static command_result job_duplicate(Core * c, vector <string> & parameters)
+{
+ if (!parameters.empty())
+ return CR_WRONG_USAGE;
+
+ df::job *job = getWorkshopJob(c);
+ if (!job)
+ return CR_FAILURE;
+
+ if (!job->misc_links.empty() || job->job_items.empty())
+ {
+ c->con.printerr("Cannot duplicate job %s\n", ENUM_KEY_STR(job_type,job->job_type));
+ return CR_FAILURE;
+ }
+
+ df::building *building = world->selected_building;
+ if (building->jobs.size() >= 10)
+ {
+ c->con.printerr("Job list is already full.\n");
+ return CR_FAILURE;
+ }
+
+ // Actually clone
+ df::job *pnew = clone_job(job);
+
+ int pos = ++*ui_workshop_job_cursor;
+ building->jobs.insert(building->jobs.begin()+pos, pnew);
+
+ return CR_OK;
+}
+
+/* Main job command implementation */
+
static void print_job_item_details(Core *c, df::job *job, df::job_item *item)
{
c->con << " Input Item: " << ENUM_KEY_STR(item_type,item->item_type);