diff options
| author | Alexander Gavrilov | 2012-01-04 19:39:38 +0400 |
|---|---|---|
| committer | Alexander Gavrilov | 2012-01-04 19:39:38 +0400 |
| commit | 284009e873b95eed32fae62703ab3bc59e8e905b (patch) | |
| tree | 717be1878c3e3bd6374a1dcabccb9c31759eb418 /plugins/jobutils.cpp | |
| parent | 99dda069de241920b19ad99ba8dbc88f166f1d91 (diff) | |
| download | dfhack-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.cpp | 100 |
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); |
