Add confirmations for hauling route/stop deletion and depot removal

develop
lethosor 2015-06-06 10:31:12 -04:00
parent 175edf501a
commit 35f229c578
1 changed files with 79 additions and 24 deletions

@ -7,18 +7,26 @@
#include "PluginManager.h" #include "PluginManager.h"
#include "VTableInterpose.h" #include "VTableInterpose.h"
#include "uicommon.h" #include "uicommon.h"
#include "modules/Gui.h"
#include "df/building_tradedepotst.h"
#include "df/viewscreen_dwarfmodest.h"
#include "df/viewscreen_tradegoodsst.h" #include "df/viewscreen_tradegoodsst.h"
using namespace DFHack; using namespace DFHack;
using namespace df::enums;
using std::string;
using std::vector;
DFHACK_PLUGIN("confirm"); DFHACK_PLUGIN("confirm");
DFHACK_PLUGIN_IS_ENABLED(is_enabled); DFHACK_PLUGIN_IS_ENABLED(is_enabled);
REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(gps);
REQUIRE_GLOBAL(ui);
typedef std::set<df::interface_key> ikey_set; typedef std::set<df::interface_key> ikey_set;
command_result df_confirm (color_ostream &out, std::vector <std::string> & parameters); command_result df_confirm (color_ostream &out, vector <string> & parameters);
static std::multimap<std::string, VMethodInterposeLinkBase> hooks; static std::multimap<string, VMethodInterposeLinkBase> hooks;
#define IMPLEMENT_CONFIRMATION_HOOKS(cls) \ #define IMPLEMENT_CONFIRMATION_HOOKS(cls) \
static cls cls##_instance; \ static cls cls##_instance; \
@ -82,7 +90,7 @@ public:
return state == ACTIVE; return state == ACTIVE;
} }
void render() { void render() {
static std::vector<std::string> lines; static vector<string> lines;
Screen::Pen corner_ul = Screen::Pen((char)201, COLOR_GREY, COLOR_BLACK); Screen::Pen corner_ul = Screen::Pen((char)201, COLOR_GREY, COLOR_BLACK);
Screen::Pen corner_ur = Screen::Pen((char)187, COLOR_GREY, COLOR_BLACK); Screen::Pen corner_ur = Screen::Pen((char)187, COLOR_GREY, COLOR_BLACK);
Screen::Pen corner_dl = Screen::Pen((char)200, COLOR_GREY, COLOR_BLACK); Screen::Pen corner_dl = Screen::Pen((char)200, COLOR_GREY, COLOR_BLACK);
@ -115,7 +123,9 @@ public:
Screen::paintTile(corner_ur, x2, y1); Screen::paintTile(corner_ur, x2, y1);
Screen::paintTile(corner_dl, x1, y2); Screen::paintTile(corner_dl, x1, y2);
Screen::paintTile(corner_dr, x2, y2); Screen::paintTile(corner_dr, x2, y2);
std::string title = " " + get_title() + " "; string title = " " + get_title() + " ";
Screen::paintString(Screen::Pen(' ', COLOR_DARKGREY, COLOR_BLACK),
x2 - 6, y1, "DFHack");
Screen::paintString(Screen::Pen(' ', COLOR_BLACK, COLOR_GREY), Screen::paintString(Screen::Pen(' ', COLOR_BLACK, COLOR_GREY),
(gps->dimx / 2) - (title.size() / 2), y1, title); (gps->dimx / 2) - (title.size() / 2), y1, title);
int x = x1 + 2; int x = x1 + 2;
@ -139,8 +149,8 @@ public:
} }
} }
virtual bool intercept_key (df::interface_key key) = 0; virtual bool intercept_key (df::interface_key key) = 0;
virtual std::string get_title() { return "Confirm"; } virtual string get_title() { return "Confirm"; }
virtual std::string get_message() = 0; virtual string get_message() = 0;
virtual UIColor get_color() { return COLOR_YELLOW; } virtual UIColor get_color() { return COLOR_YELLOW; }
protected: protected:
cstate state; cstate state;
@ -150,38 +160,83 @@ protected:
class trade_seize_confirmation : public confirmation<df::viewscreen_tradegoodsst> { class trade_seize_confirmation : public confirmation<df::viewscreen_tradegoodsst> {
public: public:
virtual bool intercept_key (df::interface_key key) { return key == df::interface_key::TRADE_SEIZE; } virtual bool intercept_key (df::interface_key key) { return key == df::interface_key::TRADE_SEIZE; }
virtual std::string get_id() { return "trade-seize"; } virtual string get_id() { return "trade-seize"; }
virtual std::string get_title() { return "Confirm seize"; } virtual string get_title() { return "Confirm seize"; }
virtual std::string get_message() { return "Are you sure you want to sieze these goods?"; } virtual string get_message() { return "Are you sure you want to sieze these goods?"; }
}; };
IMPLEMENT_CONFIRMATION_HOOKS(trade_seize_confirmation); IMPLEMENT_CONFIRMATION_HOOKS(trade_seize_confirmation);
class trade_offer_confirmation : public confirmation<df::viewscreen_tradegoodsst> { class trade_offer_confirmation : public confirmation<df::viewscreen_tradegoodsst> {
public: public:
virtual bool intercept_key (df::interface_key key) { return key == df::interface_key::TRADE_OFFER; } virtual bool intercept_key (df::interface_key key) { return key == df::interface_key::TRADE_OFFER; }
virtual std::string get_id() { return "trade-offer"; } virtual string get_id() { return "trade-offer"; }
virtual std::string get_title() { return "Confirm offer"; } virtual string get_title() { return "Confirm offer"; }
virtual std::string get_message() { return "Are you sure you want to offer these goods?\nYou will receive no payment."; } virtual string get_message() { return "Are you sure you want to offer these goods?\nYou will receive no payment."; }
}; };
IMPLEMENT_CONFIRMATION_HOOKS(trade_offer_confirmation); IMPLEMENT_CONFIRMATION_HOOKS(trade_offer_confirmation);
class hauling_route_delete_confirmation : public confirmation<df::viewscreen_dwarfmodest> {
public:
virtual bool intercept_key (df::interface_key key)
{
if (ui->main.mode == ui_sidebar_mode::Hauling && ui->hauling.view_routes.size())
return key == df::interface_key::D_HAULING_REMOVE;
return false;
}
virtual string get_id() { return "haul-delete"; }
virtual string get_title() { return "Confirm deletion"; }
virtual string get_message()
{
std::string type = (ui->hauling.view_stops[ui->hauling.cursor_top]) ? "stop" : "route";
return std::string("Are you sure you want to delete this ") + type + "?";
}
};
IMPLEMENT_CONFIRMATION_HOOKS(hauling_route_delete_confirmation);
class depot_remove_confirmation : public confirmation<df::viewscreen_dwarfmodest> {
public:
virtual bool intercept_key (df::interface_key key)
{
df::building_tradedepotst *depot = virtual_cast<df::building_tradedepotst>(Gui::getAnyBuilding(screen));
if (depot && key == df::interface_key::DESTROYBUILDING)
{
for (auto it = ui->caravans.begin(); it != ui->caravans.end(); ++it)
{
if ((**it).time_remaining)
return true;
}
}
return false;
}
virtual string get_id() { return "depot-remove"; }
virtual string get_title() { return "Confirm depot removal"; }
virtual string get_message()
{
return "Are you sure you want to remove this depot?\n"
"Merchants are present and will lose profits.";
}
};
IMPLEMENT_CONFIRMATION_HOOKS(depot_remove_confirmation);
#define CHOOK(cls) \ #define CHOOK(cls) \
HOOK_ACTION(cls, render) \ HOOK_ACTION(cls, cls##_hooks, render) \
HOOK_ACTION(cls, feed) \ HOOK_ACTION(cls, cls##_hooks, feed) \
HOOK_ACTION(cls, key_conflict) HOOK_ACTION(cls, cls##_hooks, key_conflict)
#define CHOOKS \ #define CHOOKS \
CHOOK(trade_seize_confirmation) \ CHOOK(trade_seize_confirmation) \
CHOOK(trade_offer_confirmation) CHOOK(trade_offer_confirmation) \
CHOOK(hauling_route_delete_confirmation) \
CHOOK(depot_remove_confirmation)
DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init (color_ostream &out, vector <PluginCommand> &commands)
{ {
std::vector<std::string> hook_names; vector<string> hook_names;
#define HOOK_ACTION(cls, method) hooks.insert(std::pair<std::string, VMethodInterposeLinkBase>(cls##_instance.get_id(), INTERPOSE_HOOK(cls##_hooks, method))); \ #define HOOK_ACTION(cls, hookcls, method) hooks.insert(std::pair<string, VMethodInterposeLinkBase>(cls##_instance.get_id(), INTERPOSE_HOOK(hookcls, method))); \
if (std::find(hook_names.begin(), hook_names.end(), cls##_instance.get_id()) == hook_names.end()) hook_names.push_back(cls##_instance.get_id()); if (std::find(hook_names.begin(), hook_names.end(), cls##_instance.get_id()) == hook_names.end()) hook_names.push_back(cls##_instance.get_id());
CHOOKS CHOOKS
#undef HOOK_ACTION #undef HOOK_ACTION
std::string help = string help =
" confirmation enable|disable option|all ...\n" " confirmation enable|disable option|all ...\n"
"Available options:\n " + join_strings(", ", hook_names); "Available options:\n " + join_strings(", ", hook_names);
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
@ -198,7 +253,7 @@ DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable)
{ {
if (is_enabled != enable) if (is_enabled != enable)
{ {
#define HOOK_ACTION(cls, method) !INTERPOSE_HOOK(cls##_hooks, method).apply(enable) || #define HOOK_ACTION(cls, hookcls, method) !INTERPOSE_HOOK(hookcls, method).apply(enable) ||
if (CHOOKS 0) if (CHOOKS 0)
return CR_FAILURE; return CR_FAILURE;
#undef HOOK_ACTION #undef HOOK_ACTION
@ -210,13 +265,13 @@ DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable)
DFhackCExport command_result plugin_shutdown (color_ostream &out) DFhackCExport command_result plugin_shutdown (color_ostream &out)
{ {
#define HOOK_ACTION(cls, method) INTERPOSE_HOOK(cls##_hooks, method).remove(); #define HOOK_ACTION(cls, hookcls, method) INTERPOSE_HOOK(hookcls, method).remove();
CHOOKS; CHOOKS;
#undef HOOK_ACTION #undef HOOK_ACTION
return CR_OK; return CR_OK;
} }
void enable_conf (color_ostream &out, std::string name, bool state) void enable_conf (color_ostream &out, string name, bool state)
{ {
bool found = false; bool found = false;
for (auto it = hooks.begin(); it != hooks.end(); ++it) for (auto it = hooks.begin(); it != hooks.end(); ++it)
@ -231,7 +286,7 @@ void enable_conf (color_ostream &out, std::string name, bool state)
out.printerr("Unrecognized option: %s\n", name.c_str()); out.printerr("Unrecognized option: %s\n", name.c_str());
} }
command_result df_confirm (color_ostream &out, std::vector <std::string> & parameters) command_result df_confirm (color_ostream &out, vector <string> & parameters)
{ {
CoreSuspender suspend; CoreSuspender suspend;
bool state = true; bool state = true;