Add built-in enable and disable commands.

develop
Alexander Gavrilov 2013-09-30 13:19:51 +04:00
parent a487ede2b9
commit d7e35c2d23
37 changed files with 607 additions and 114 deletions

@ -209,6 +209,25 @@ or is a prefix ending at a '/' boundary would be considered for execution, i.e.
for context ``foo/bar/baz``, possible matches are any of ``@foo/bar/baz``, ``@foo/bar``, for context ``foo/bar/baz``, possible matches are any of ``@foo/bar/baz``, ``@foo/bar``,
``@foo`` or none. ``@foo`` or none.
Enabling plugins
================
Many plugins can be in a distinct enabled or disabled state. Some of
them activate and deactivate automatically depending on the contents
of the world raws. Others store their state in world data. However a
number of them have to be enabled globally, and the init file is the
right place to do it.
Most of such plugins support the built-in ``enable`` and ``disable``
commands. Calling them at any time without arguments prints a list
of enabled and disabled plugins, and shows whether that can be changed
through the same commands.
To enable or disable plugins that support this, use their names as
arguments for the command::
enable manipulator search
======== ========
Commands Commands

@ -150,8 +150,24 @@ tweak military-training
# prevent crash if bees die in a hive with ungathered products by insta-gathering them # prevent crash if bees die in a hive with ungathered products by insta-gathering them
tweak hive-crash tweak hive-crash
# enable autoSyndrome ###########################
autoSyndrome enable # Globally acting plugins #
###########################
# Dwarf Manipulator (simple in-game Dwarf Therapist replacement)
enable manipulator
# Search tool in various screens (by falconne)
enable search
# Improved build material selection interface (by falconne)
enable automaterial
# Other interface improvement tools
#enable dwarfmonitor mousequery autotrade buildingplan resume zone
# Auto Syndrome
#autoSyndrome enable
########### ###########
# Scripts # # Scripts #

@ -544,6 +544,56 @@ command_result Core::runCommand(color_ostream &con, const std::string &first, ve
} }
} }
} }
else if( first == "enable" || first == "disable" )
{
CoreSuspender suspend;
bool enable = (first == "enable");
if(parts.size())
{
command_result res = CR_OK;
for (size_t i = 0; i < parts.size(); i++)
{
Plugin * plug = plug_mgr->getPluginByName(parts[i]);
if(!plug)
{
res = CR_NOT_FOUND;
con.printerr("No such plugin: %s\n", parts[i].c_str());
}
else if (!plug->can_set_enabled())
{
res = CR_NOT_IMPLEMENTED;
con.printerr("Cannot %s plugin: %s\n", first.c_str(), parts[i].c_str());
}
else
{
res = plug->set_enabled(con, enable);
if (res != CR_OK || plug->is_enabled() != enable)
con.printerr("Could not %s plugin: %s\n", first.c_str(), parts[i].c_str());
}
}
return res;
}
else
{
for(size_t i = 0; i < plug_mgr->size();i++)
{
Plugin * plug = (plug_mgr->operator[](i));
if (!plug->can_be_enabled()) continue;
con.print(
"%20s\t%-3s%s\n",
(plug->getName()+":").c_str(),
plug->is_enabled() ? "on" : "off",
plug->can_set_enabled() ? "" : " (controlled elsewhere)"
);
}
}
}
else if(first == "ls" || first == "dir") else if(first == "ls" || first == "dir")
{ {
bool all = false; bool all = false;
@ -584,6 +634,7 @@ command_result Core::runCommand(color_ostream &con, const std::string &first, ve
" load PLUGIN|all - Load a plugin by name or load all possible plugins.\n" " load PLUGIN|all - Load a plugin by name or load all possible plugins.\n"
" unload PLUGIN|all - Unload a plugin or all loaded plugins.\n" " unload PLUGIN|all - Unload a plugin or all loaded plugins.\n"
" reload PLUGIN|all - Reload a plugin or all loaded plugins.\n" " reload PLUGIN|all - Reload a plugin or all loaded plugins.\n"
" enable/disable PLUGIN - Enable or disable a plugin if supported.\n"
"\n" "\n"
"plugins:\n" "plugins:\n"
); );

@ -172,6 +172,8 @@ Plugin::Plugin(Core * core, const std::string & filepath, const std::string & _f
plugin_onupdate = 0; plugin_onupdate = 0;
plugin_onstatechange = 0; plugin_onstatechange = 0;
plugin_rpcconnect = 0; plugin_rpcconnect = 0;
plugin_enable = 0;
plugin_is_enabled = 0;
state = PS_UNLOADED; state = PS_UNLOADED;
access = new RefLock(); access = new RefLock();
} }
@ -245,6 +247,8 @@ bool Plugin::load(color_ostream &con)
plugin_shutdown = (command_result (*)(color_ostream &)) LookupPlugin(plug, "plugin_shutdown"); plugin_shutdown = (command_result (*)(color_ostream &)) LookupPlugin(plug, "plugin_shutdown");
plugin_onstatechange = (command_result (*)(color_ostream &, state_change_event)) LookupPlugin(plug, "plugin_onstatechange"); plugin_onstatechange = (command_result (*)(color_ostream &, state_change_event)) LookupPlugin(plug, "plugin_onstatechange");
plugin_rpcconnect = (RPCService* (*)(color_ostream &)) LookupPlugin(plug, "plugin_rpcconnect"); plugin_rpcconnect = (RPCService* (*)(color_ostream &)) LookupPlugin(plug, "plugin_rpcconnect");
plugin_enable = (command_result (*)(color_ostream &,bool)) LookupPlugin(plug, "plugin_enable");
plugin_is_enabled = (bool*) LookupPlugin(plug, "plugin_is_enabled");
plugin_eval_ruby = (command_result (*)(color_ostream &, const char*)) LookupPlugin(plug, "plugin_eval_ruby"); plugin_eval_ruby = (command_result (*)(color_ostream &, const char*)) LookupPlugin(plug, "plugin_eval_ruby");
index_lua(plug); index_lua(plug);
this->name = *plug_name; this->name = *plug_name;
@ -254,11 +258,15 @@ bool Plugin::load(color_ostream &con)
{ {
state = PS_LOADED; state = PS_LOADED;
parent->registerCommands(this); parent->registerCommands(this);
if ((plugin_onupdate || plugin_enable) && !plugin_is_enabled)
con.printerr("Plugin %s has no enabled var!\n", name.c_str());
return true; return true;
} }
else else
{ {
con.printerr("Plugin %s has failed to initialize properly.\n", filename.c_str()); con.printerr("Plugin %s has failed to initialize properly.\n", filename.c_str());
plugin_is_enabled = 0;
plugin_onupdate = 0;
reset_lua(); reset_lua();
ClosePlugin(plugin_lib); ClosePlugin(plugin_lib);
state = PS_BROKEN; state = PS_BROKEN;
@ -294,6 +302,8 @@ bool Plugin::unload(color_ostream &con)
if(plugin_shutdown) if(plugin_shutdown)
cr = plugin_shutdown(con); cr = plugin_shutdown(con);
// cleanup... // cleanup...
plugin_is_enabled = 0;
plugin_onupdate = 0;
reset_lua(); reset_lua();
parent->unregisterCommands(this); parent->unregisterCommands(this);
commands.clear(); commands.clear();
@ -408,6 +418,12 @@ bool Plugin::can_invoke_hotkey(const std::string & command, df::viewscreen *top
command_result Plugin::on_update(color_ostream &out) command_result Plugin::on_update(color_ostream &out)
{ {
// Check things that are implicitly protected by the suspend lock
if (!plugin_onupdate)
return CR_NOT_IMPLEMENTED;
if (plugin_is_enabled && !*plugin_is_enabled)
return CR_OK;
// Grab mutex and call the thing
command_result cr = CR_NOT_IMPLEMENTED; command_result cr = CR_NOT_IMPLEMENTED;
access->lock_add(); access->lock_add();
if(state == PS_LOADED && plugin_onupdate) if(state == PS_LOADED && plugin_onupdate)
@ -419,6 +435,21 @@ command_result Plugin::on_update(color_ostream &out)
return cr; return cr;
} }
command_result Plugin::set_enabled(color_ostream &out, bool enable)
{
command_result cr = CR_NOT_IMPLEMENTED;
access->lock_add();
if(state == PS_LOADED && plugin_is_enabled && plugin_enable)
{
cr = plugin_enable(out, enable);
if (cr == CR_OK && enable != is_enabled())
cr = CR_FAILURE;
}
access->lock_sub();
return cr;
}
command_result Plugin::on_state_change(color_ostream &out, state_change_event event) command_result Plugin::on_state_change(color_ostream &out, state_change_event event)
{ {
command_result cr = CR_NOT_IMPLEMENTED; command_result cr = CR_NOT_IMPLEMENTED;
@ -524,6 +555,37 @@ void Plugin::reset_lua()
} }
} }
int Plugin::lua_is_enabled(lua_State *state)
{
auto obj = (Plugin*)lua_touserdata(state, lua_upvalueindex(1));
RefAutoinc lock(obj->access);
if (obj->state == PS_LOADED && obj->plugin_is_enabled)
lua_pushboolean(state, obj->is_enabled());
else
lua_pushnil(state);
return 1;
}
int Plugin::lua_set_enabled(lua_State *state)
{
lua_settop(state, 1);
bool val = lua_toboolean(state, 1);
auto obj = (Plugin*)lua_touserdata(state, lua_upvalueindex(1));
RefAutoinc lock(obj->access);
color_ostream *out = Lua::GetOutput(state);
if (obj->state == PS_LOADED && obj->plugin_enable)
lua_pushboolean(state, obj->set_enabled(*out, val) == CR_OK);
else
luaL_error(state, "plugin %s unloaded, cannot enable or disable", obj->name.c_str());
return 1;
}
int Plugin::lua_cmd_wrapper(lua_State *state) int Plugin::lua_cmd_wrapper(lua_State *state)
{ {
auto cmd = (LuaCommand*)lua_touserdata(state, lua_upvalueindex(1)); auto cmd = (LuaCommand*)lua_touserdata(state, lua_upvalueindex(1));
@ -561,6 +623,19 @@ void Plugin::open_lua(lua_State *state, int table)
RefAutolock lock(access); RefAutolock lock(access);
if (plugin_is_enabled)
{
lua_pushlightuserdata(state, this);
lua_pushcclosure(state, lua_is_enabled, 1);
lua_setfield(state, table, "isEnabled");
}
if (plugin_enable)
{
lua_pushlightuserdata(state, this);
lua_pushcclosure(state, lua_set_enabled, 1);
lua_setfield(state, table, "setEnabled");
}
for (auto it = lua_commands.begin(); it != lua_commands.end(); ++it) for (auto it = lua_commands.begin(); it != lua_commands.end(); ++it)
{ {
lua_pushlightuserdata(state, it->second); lua_pushlightuserdata(state, it->second);

@ -144,6 +144,11 @@ namespace DFHack
bool unload(color_ostream &out); bool unload(color_ostream &out);
bool reload(color_ostream &out); bool reload(color_ostream &out);
bool can_be_enabled() { return plugin_is_enabled != 0; }
bool is_enabled() { return plugin_is_enabled && *plugin_is_enabled; }
bool can_set_enabled() { return plugin_is_enabled != 0 && plugin_enable; }
command_result set_enabled(color_ostream &out, bool enable);
command_result invoke(color_ostream &out, const std::string & command, std::vector <std::string> & parameters); command_result invoke(color_ostream &out, const std::string & command, std::vector <std::string> & parameters);
bool can_invoke_hotkey(const std::string & command, df::viewscreen *top ); bool can_invoke_hotkey(const std::string & command, df::viewscreen *top );
plugin_state getState () const; plugin_state getState () const;
@ -184,17 +189,22 @@ namespace DFHack
static int lua_fun_wrapper(lua_State *state); static int lua_fun_wrapper(lua_State *state);
void push_function(lua_State *state, LuaFunction *fn); void push_function(lua_State *state, LuaFunction *fn);
static int lua_is_enabled(lua_State *state);
static int lua_set_enabled(lua_State *state);
struct LuaEvent; struct LuaEvent;
std::map<std::string, LuaEvent*> lua_events; std::map<std::string, LuaEvent*> lua_events;
void index_lua(DFLibrary *lib); void index_lua(DFLibrary *lib);
void reset_lua(); void reset_lua();
bool *plugin_is_enabled;
command_result (*plugin_init)(color_ostream &, std::vector <PluginCommand> &); command_result (*plugin_init)(color_ostream &, std::vector <PluginCommand> &);
command_result (*plugin_status)(color_ostream &, std::string &); command_result (*plugin_status)(color_ostream &, std::string &);
command_result (*plugin_shutdown)(color_ostream &); command_result (*plugin_shutdown)(color_ostream &);
command_result (*plugin_onupdate)(color_ostream &); command_result (*plugin_onupdate)(color_ostream &);
command_result (*plugin_onstatechange)(color_ostream &, state_change_event); command_result (*plugin_onstatechange)(color_ostream &, state_change_event);
command_result (*plugin_enable)(color_ostream &, bool);
RPCService* (*plugin_rpcconnect)(color_ostream &); RPCService* (*plugin_rpcconnect)(color_ostream &);
command_result (*plugin_eval_ruby)(color_ostream &, const char*); command_result (*plugin_eval_ruby)(color_ostream &, const char*);
}; };
@ -250,6 +260,10 @@ namespace DFHack
DFhackDataExport const char * name = plugin_name;\ DFhackDataExport const char * name = plugin_name;\
DFhackDataExport Plugin *plugin_self = NULL; DFhackDataExport Plugin *plugin_self = NULL;
#define DFHACK_PLUGIN_IS_ENABLED(varname) \
DFhackDataExport bool plugin_is_enabled = false; \
bool &varname = plugin_is_enabled;
#define DFHACK_PLUGIN_LUA_COMMANDS \ #define DFHACK_PLUGIN_LUA_COMMANDS \
DFhackCExport const DFHack::CommandReg plugin_lua_commands[] = DFhackCExport const DFHack::CommandReg plugin_lua_commands[] =
#define DFHACK_PLUGIN_LUA_FUNCTIONS \ #define DFHACK_PLUGIN_LUA_FUNCTIONS \

@ -48,6 +48,7 @@ using df::global::ui;
typedef df::reaction_product_item_improvementst improvement_product; typedef df::reaction_product_item_improvementst improvement_product;
DFHACK_PLUGIN("add-spatter"); DFHACK_PLUGIN("add-spatter");
DFHACK_PLUGIN_IS_ENABLED(is_enabled);
struct ReagentSource { struct ReagentSource {
int idx; int idx;
@ -390,6 +391,7 @@ static bool find_reactions(color_ostream &out)
static void enable_hooks(bool enable) static void enable_hooks(bool enable)
{ {
is_enabled = enable;
INTERPOSE_HOOK(item_hook, isImprovable).apply(enable); INTERPOSE_HOOK(item_hook, isImprovable).apply(enable);
INTERPOSE_HOOK(product_hook, produce).apply(enable); INTERPOSE_HOOK(product_hook, produce).apply(enable);
} }

@ -99,7 +99,7 @@ DFhackCExport command_result plugin_shutdown ( color_ostream &out )
df::nemesis_record *getPlayerNemesis(color_ostream &out, bool restore_swap); df::nemesis_record *getPlayerNemesis(color_ostream &out, bool restore_swap);
static bool in_transient_swap = false; DFHACK_PLUGIN_IS_ENABLED(in_transient_swap);
DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event) DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event)
{ {

@ -98,7 +98,7 @@ reaction_duck
Next, start a new fort in a new world, build a duck workshop, then have someone become a duck. Next, start a new fort in a new world, build a duck workshop, then have someone become a duck.
*/ */
bool enabled = false; DFHACK_PLUGIN_IS_ENABLED(enabled);
DFHACK_PLUGIN("autoSyndrome"); DFHACK_PLUGIN("autoSyndrome");
@ -139,37 +139,45 @@ DFhackCExport command_result plugin_shutdown(color_ostream& out) {
return CR_OK; return CR_OK;
}*/ }*/
DFhackCExport command_result plugin_enable(color_ostream &out, bool enable)
{
if (enabled == enable)
return CR_OK;
enabled = enable;
Plugin* me = Core::getInstance().getPluginManager()->getPluginByName("autoSyndrome");
if ( enabled ) {
EventManager::EventHandler handle(processJob, 5);
EventManager::registerListener(EventManager::EventType::JOB_COMPLETED, handle, me);
} else {
EventManager::unregisterAll(me);
}
return CR_OK;
}
command_result autoSyndrome(color_ostream& out, vector<string>& parameters) { command_result autoSyndrome(color_ostream& out, vector<string>& parameters) {
if ( parameters.size() > 1 ) if ( parameters.size() > 1 )
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
bool wasEnabled = enabled; bool enable = false;
if ( parameters.size() == 1 ) { if ( parameters.size() == 1 ) {
if ( parameters[0] == "enable" ) { if ( parameters[0] == "enable" ) {
enabled = true; enable = true;
} else if ( parameters[0] == "disable" ) { } else if ( parameters[0] == "disable" ) {
enabled = false; enable = false;
} else { } else {
int32_t a = atoi(parameters[0].c_str()); int32_t a = atoi(parameters[0].c_str());
if ( a < 0 || a > 1 ) if ( a < 0 || a > 1 )
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
enabled = (bool)a; enable = (bool)a;
} }
} }
out.print("autoSyndrome is %s\n", enabled ? "enabled" : "disabled"); out.print("autoSyndrome is %s\n", enable ? "enabled" : "disabled");
if ( enabled == wasEnabled ) return plugin_enable(out, enable);
return CR_OK;
Plugin* me = Core::getInstance().getPluginManager()->getPluginByName("autoSyndrome");
if ( enabled ) {
EventManager::EventHandler handle(processJob, 5);
EventManager::registerListener(EventManager::EventType::JOB_COMPLETED, handle, me);
} else {
EventManager::unregisterAll(me);
}
return CR_OK;
} }
bool maybeApply(color_ostream& out, df::syndrome* syndrome, int32_t workerId, df::unit* unit) { bool maybeApply(color_ostream& out, df::syndrome* syndrome, int32_t workerId, df::unit* unit) {

@ -76,7 +76,7 @@ using df::global::world;
* (mining, hunting, and woodcutting) need to be handled carefully to minimize churn. * (mining, hunting, and woodcutting) need to be handled carefully to minimize churn.
*/ */
static int enable_autolabor = 0; DFHACK_PLUGIN_IS_ENABLED(enable_autolabor);
static bool print_debug = 0; static bool print_debug = 0;
@ -535,6 +535,7 @@ static void setOptionEnabled(ConfigFlags flag, bool on)
static void cleanup_state() static void cleanup_state()
{ {
enable_autolabor = false;
labor_infos.clear(); labor_infos.clear();
} }
@ -1297,6 +1298,27 @@ void print_labor (df::unit_labor labor, color_ostream &out)
} }
} }
DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable )
{
if (!Core::getInstance().isWorldLoaded()) {
out.printerr("World is not loaded: please load a game first.\n");
return CR_FAILURE;
}
if (enable && !enable_autolabor)
{
enable_plugin(out);
}
else if(!enable && enable_autolabor)
{
enable_autolabor = false;
setOptionEnabled(CF_ENABLED, false);
out << "Autolabor is disabled." << endl;
}
return CR_OK;
}
command_result autolabor (color_ostream &out, std::vector <std::string> & parameters) command_result autolabor (color_ostream &out, std::vector <std::string> & parameters)
{ {
@ -1312,19 +1334,8 @@ command_result autolabor (color_ostream &out, std::vector <std::string> & parame
parameters[0] == "1" || parameters[0] == "disable")) parameters[0] == "1" || parameters[0] == "disable"))
{ {
bool enable = (parameters[0] == "1" || parameters[0] == "enable"); bool enable = (parameters[0] == "1" || parameters[0] == "enable");
if (enable && !enable_autolabor)
{
enable_plugin(out);
}
else if(!enable && enable_autolabor)
{
enable_autolabor = false;
setOptionEnabled(CF_ENABLED, false);
out << "The plugin is disabled." << endl; return plugin_enable(out, enable);
}
return CR_OK;
} }
else if (parameters.size() == 2 && parameters[0] == "haulpct") else if (parameters.size() == 2 && parameters[0] == "haulpct")
{ {

@ -1179,11 +1179,27 @@ color_ostream_proxy console_out(Core::getInstance().getConsole());
IMPLEMENT_VMETHOD_INTERPOSE(jobutils_hook, feed); IMPLEMENT_VMETHOD_INTERPOSE(jobutils_hook, feed);
IMPLEMENT_VMETHOD_INTERPOSE(jobutils_hook, render); IMPLEMENT_VMETHOD_INTERPOSE(jobutils_hook, render);
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands) DFHACK_PLUGIN_IS_ENABLED(is_enabled);
DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable)
{ {
if (!gps || !INTERPOSE_HOOK(jobutils_hook, feed).apply() || !INTERPOSE_HOOK(jobutils_hook, render).apply()) if (!gps)
out.printerr("Could not insert jobutils hooks!\n"); return CR_FAILURE;
if (enable != is_enabled)
{
if (!INTERPOSE_HOOK(jobutils_hook, feed).apply(enable) ||
!INTERPOSE_HOOK(jobutils_hook, render).apply(enable))
return CR_FAILURE;
is_enabled = enable;
}
return CR_OK;
}
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{
hotkeys[construction_type::Wall] = df::interface_key::HOTKEY_BUILDING_CONSTRUCTION_WALL; hotkeys[construction_type::Wall] = df::interface_key::HOTKEY_BUILDING_CONSTRUCTION_WALL;
hotkeys[construction_type::Floor] = df::interface_key::HOTKEY_BUILDING_CONSTRUCTION_FLOOR; hotkeys[construction_type::Floor] = df::interface_key::HOTKEY_BUILDING_CONSTRUCTION_FLOOR;
hotkeys[construction_type::Ramp] = df::interface_key::HOTKEY_BUILDING_CONSTRUCTION_RAMP; hotkeys[construction_type::Ramp] = df::interface_key::HOTKEY_BUILDING_CONSTRUCTION_RAMP;

@ -583,7 +583,6 @@ static command_result autotrade_cmd(color_ostream &out, vector <string> & parame
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event) DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event)
{ {
switch (event) switch (event)
@ -600,11 +599,30 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands) DFHACK_PLUGIN_IS_ENABLED(is_enabled);
DFhackCExport command_result plugin_enable(color_ostream &out, bool enable)
{ {
if (!gps || !INTERPOSE_HOOK(trade_hook, feed).apply() || !INTERPOSE_HOOK(trade_hook, render).apply()) if (!gps)
out.printerr("Could not insert autotrade hooks!\n"); return CR_FAILURE;
if (enable != is_enabled)
{
depot_info.reset();
monitor.reset();
if (!INTERPOSE_HOOK(trade_hook, feed).apply(enable) ||
!INTERPOSE_HOOK(trade_hook, render).apply(enable))
return CR_FAILURE;
is_enabled = enable;
}
return CR_OK;
}
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{
commands.push_back( commands.push_back(
PluginCommand( PluginCommand(
"autotrade", "Automatically send items in marked stockpiles to trade depot, when trading is possible.", "autotrade", "Automatically send items in marked stockpiles to trade depot, when trading is possible.",

@ -1153,12 +1153,29 @@ static command_result buildingplan_cmd(color_ostream &out, vector <string> & par
return CR_OK; return CR_OK;
} }
DFHACK_PLUGIN_IS_ENABLED(is_enabled);
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_enable(color_ostream &out, bool enable)
{ {
if (!gps || !INTERPOSE_HOOK(buildingplan_hook, feed).apply() || !INTERPOSE_HOOK(buildingplan_hook, render).apply()) if (!gps)
out.printerr("Could not insert buildingplan hooks!\n"); return CR_FAILURE;
if (enable != is_enabled)
{
planner.reset(out);
if (!INTERPOSE_HOOK(buildingplan_hook, feed).apply(enable) ||
!INTERPOSE_HOOK(buildingplan_hook, render).apply(enable))
return CR_FAILURE;
is_enabled = enable;
}
return CR_OK;
}
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{
commands.push_back( commands.push_back(
PluginCommand( PluginCommand(
"buildingplan", "Place furniture before it's built", "buildingplan", "Place furniture before it's built",

@ -221,7 +221,8 @@ static void detect_digging(color_ostream &out)
} }
} }
static bool active = false; DFHACK_PLUGIN_IS_ENABLED(active);
static bool auto_grow = false; static bool auto_grow = false;
static std::vector<int> grow_burrows; static std::vector<int> grow_burrows;

@ -76,7 +76,7 @@ using df::global::world;
#define ARRAY_COUNT(array) (sizeof(array)/sizeof((array)[0])) #define ARRAY_COUNT(array) (sizeof(array)/sizeof((array)[0]))
static int enable_autolabor = 0; DFHACK_PLUGIN_IS_ENABLED(enable_autolabor);
static bool print_debug = 0; static bool print_debug = 0;
@ -1375,6 +1375,7 @@ static void setOptionEnabled(ConfigFlags flag, bool on)
static void cleanup_state() static void cleanup_state()
{ {
enable_autolabor = false;
labor_infos.clear(); labor_infos.clear();
} }
@ -2384,6 +2385,27 @@ df::unit_labor lookup_labor_by_name (std::string& name)
return labor; return labor;
} }
DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable )
{
if (!Core::getInstance().isWorldLoaded()) {
out.printerr("World is not loaded: please load a game first.\n");
return CR_FAILURE;
}
if (enable && !enable_autolabor)
{
enable_plugin(out);
}
else if(!enable && enable_autolabor)
{
enable_autolabor = false;
setOptionEnabled(CF_ENABLED, false);
out << "Autolabor is disabled." << endl;
}
return CR_OK;
}
command_result autolabor (color_ostream &out, std::vector <std::string> & parameters) command_result autolabor (color_ostream &out, std::vector <std::string> & parameters)
{ {
@ -2398,19 +2420,7 @@ command_result autolabor (color_ostream &out, std::vector <std::string> & parame
(parameters[0] == "enable" || parameters[0] == "disable")) (parameters[0] == "enable" || parameters[0] == "disable"))
{ {
bool enable = (parameters[0] == "enable"); bool enable = (parameters[0] == "enable");
if (enable && !enable_autolabor) return plugin_enable(out, enable);
{
enable_plugin(out);
}
else if(!enable && enable_autolabor)
{
enable_autolabor = false;
setOptionEnabled(CF_ENABLED, false);
out << "The plugin is disabled." << endl;
}
return CR_OK;
} }
else if (parameters.size() == 3 && else if (parameters.size() == 3 &&
(parameters[0] == "max" || parameters[0] == "priority")) (parameters[0] == "max" || parameters[0] == "priority"))

@ -16,6 +16,8 @@ using std::vector;
using std::string; using std::string;
using namespace DFHack; using namespace DFHack;
DFHACK_PLUGIN_IS_ENABLED(is_enabled);
//FIXME: possible race conditions with calling kittens from the IO thread and shutdown from Core. //FIXME: possible race conditions with calling kittens from the IO thread and shutdown from Core.
bool shutdown_flag = false; bool shutdown_flag = false;
bool final_flag = true; bool final_flag = true;
@ -141,6 +143,7 @@ command_result trackmenu (color_ostream &out, vector <string> & parameters)
if(df::global::ui) if(df::global::ui)
{ {
trackmenu_flg = true; trackmenu_flg = true;
is_enabled = true;
last_menu = df::global::ui->main.mode; last_menu = df::global::ui->main.mode;
out.print("Menu: %d\n",last_menu); out.print("Menu: %d\n",last_menu);
return CR_OK; return CR_OK;
@ -155,6 +158,7 @@ command_result trackmenu (color_ostream &out, vector <string> & parameters)
command_result trackpos (color_ostream &out, vector <string> & parameters) command_result trackpos (color_ostream &out, vector <string> & parameters)
{ {
trackpos_flg = !trackpos_flg; trackpos_flg = !trackpos_flg;
is_enabled = true;
return CR_OK; return CR_OK;
} }
@ -214,6 +218,7 @@ command_result ktimer (color_ostream &out, vector <string> & parameters)
// harmless potential data race here... // harmless potential data race here...
timeLast = timeend; timeLast = timeend;
timering = true; timering = true;
is_enabled = true;
return CR_OK; return CR_OK;
} }

@ -15,6 +15,8 @@ using namespace DFHack;
uint64_t timeLast=0; uint64_t timeLast=0;
static tthread::mutex* mymutex=0; static tthread::mutex* mymutex=0;
DFHACK_PLUGIN_IS_ENABLED(is_enabled);
struct memory_data struct memory_data
{ {
void * addr; void * addr;
@ -96,6 +98,7 @@ void Deinit()
{ {
if(memdata.state==STATE_ON) if(memdata.state==STATE_ON)
{ {
is_enabled = false;
memdata.state=STATE_OFF; memdata.state=STATE_OFF;
delete [] memdata.buf; delete [] memdata.buf;
delete [] memdata.lbuf; delete [] memdata.lbuf;
@ -140,6 +143,7 @@ command_result memview (color_ostream &out, vector <string> & parameters)
{ {
Deinit(); Deinit();
memdata.state=STATE_OFF; memdata.state=STATE_OFF;
is_enabled = false;
mymutex->unlock(); mymutex->unlock();
return CR_OK; return CR_OK;
} }
@ -156,6 +160,7 @@ command_result memview (color_ostream &out, vector <string> & parameters)
mymutex->unlock(); mymutex->unlock();
return CR_OK; return CR_OK;
} }
is_enabled = true;
memdata.state=STATE_ON; memdata.state=STATE_ON;
} }
if(parameters.size()>1) if(parameters.size()>1)

@ -31,7 +31,7 @@ static command_result nestboxes(color_ostream &out, vector <string> & parameters
DFHACK_PLUGIN("nestboxes"); DFHACK_PLUGIN("nestboxes");
static bool enabled = false; DFHACK_PLUGIN_IS_ENABLED(enabled);
static void eggscan(color_ostream &out) static void eggscan(color_ostream &out)
{ {
@ -97,6 +97,12 @@ DFhackCExport command_result plugin_onupdate(color_ostream &out)
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_enable(color_ostream &out, bool enable)
{
enabled = enable;
return CR_OK;
}
static command_result nestboxes(color_ostream &out, vector <string> & parameters) static command_result nestboxes(color_ostream &out, vector <string> & parameters)
{ {
CoreSuspender suspend; CoreSuspender suspend;

@ -23,6 +23,8 @@ using df::global::gps;
DFHACK_PLUGIN("vshook"); DFHACK_PLUGIN("vshook");
DFHACK_PLUGIN_IS_ENABLED(is_enabled);
struct title_hook : df::viewscreen_titlest { struct title_hook : df::viewscreen_titlest {
typedef df::viewscreen_titlest interpose_base; typedef df::viewscreen_titlest interpose_base;
@ -37,17 +39,30 @@ struct title_hook : df::viewscreen_titlest {
IMPLEMENT_VMETHOD_INTERPOSE(title_hook, render); IMPLEMENT_VMETHOD_INTERPOSE(title_hook, render);
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable)
{ {
if (gps) if (!gps)
return CR_FAILURE;
if (enable != is_enabled)
{ {
if (!INTERPOSE_HOOK(title_hook, render).apply()) if (!INTERPOSE_HOOK(title_hook, render).apply(enable))
out.printerr("Could not interpose viewscreen_titlest::render\n"); return CR_FAILURE;
is_enabled = enable;
} }
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{
// DON'T DO THIS IN NON-EXAMPLE PLUGINS
plugin_enable(out, true);
return CR_OK;
}
DFhackCExport command_result plugin_shutdown ( color_ostream &out ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
INTERPOSE_HOOK(title_hook, render).remove(); INTERPOSE_HOOK(title_hook, render).remove();

@ -1179,11 +1179,15 @@ IMPLEMENT_VMETHOD_INTERPOSE(dwarf_monitor_hook, feed);
IMPLEMENT_VMETHOD_INTERPOSE(dwarf_monitor_hook, render); IMPLEMENT_VMETHOD_INTERPOSE(dwarf_monitor_hook, render);
DFHACK_PLUGIN("dwarfmonitor"); DFHACK_PLUGIN("dwarfmonitor");
DFHACK_PLUGIN_IS_ENABLED(is_enabled);
static bool set_monitoring_mode(const string &mode, const bool &state) static bool set_monitoring_mode(const string &mode, const bool &state)
{ {
bool mode_recognized = false; bool mode_recognized = false;
if (!is_enabled)
return false;
if (mode == "work" || mode == "all") if (mode == "work" || mode == "all")
{ {
mode_recognized = true; mode_recognized = true;
@ -1201,6 +1205,24 @@ static bool set_monitoring_mode(const string &mode, const bool &state)
return mode_recognized; return mode_recognized;
} }
DFhackCExport command_result plugin_enable(color_ostream &out, bool enable)
{
if (!gps)
return CR_FAILURE;
if (is_enabled != enable)
{
if (!INTERPOSE_HOOK(dwarf_monitor_hook, feed).apply(enable) ||
!INTERPOSE_HOOK(dwarf_monitor_hook, render).apply(enable))
return CR_FAILURE;
reset();
is_enabled = enable;
}
return CR_OK;
}
static command_result dwarfmonitor_cmd(color_ostream &out, vector <string> & parameters) static command_result dwarfmonitor_cmd(color_ostream &out, vector <string> & parameters)
{ {
bool show_help = false; bool show_help = false;
@ -1222,6 +1244,9 @@ static command_result dwarfmonitor_cmd(color_ostream &out, vector <string> & par
} }
else if ((cmd == 'e' || cmd == 'E') && !mode.empty()) else if ((cmd == 'e' || cmd == 'E') && !mode.empty())
{ {
if (!is_enabled)
plugin_enable(out, true);
if (set_monitoring_mode(mode, true)) if (set_monitoring_mode(mode, true))
{ {
out << "Monitoring enabled: " << mode << endl; out << "Monitoring enabled: " << mode << endl;
@ -1257,9 +1282,6 @@ static command_result dwarfmonitor_cmd(color_ostream &out, vector <string> & par
DFhackCExport command_result plugin_init(color_ostream &out, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init(color_ostream &out, std::vector <PluginCommand> &commands)
{ {
if (!gps || !INTERPOSE_HOOK(dwarf_monitor_hook, feed).apply() || !INTERPOSE_HOOK(dwarf_monitor_hook, render).apply())
out.printerr("Could not insert dwarfmonitor hooks!\n");
activity_labels[JOB_IDLE] = "Idle"; activity_labels[JOB_IDLE] = "Idle";
activity_labels[JOB_MILITARY] = "Military Duty"; activity_labels[JOB_MILITARY] = "Military Duty";
activity_labels[JOB_LEISURE] = "Leisure"; activity_labels[JOB_LEISURE] = "Leisure";

@ -19,6 +19,8 @@ using df::global::world;
// dfhack interface // dfhack interface
DFHACK_PLUGIN("fastdwarf"); DFHACK_PLUGIN("fastdwarf");
DFHACK_PLUGIN_IS_ENABLED(active);
static bool enable_fastdwarf = false; static bool enable_fastdwarf = false;
static bool enable_teledwarf = false; static bool enable_teledwarf = false;
@ -152,6 +154,8 @@ static command_result fastdwarf (color_ostream &out, vector <string> & parameter
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
active = enable_fastdwarf || enable_teledwarf;
out.print("Current state: fast = %d, teleport = %d.\n", out.print("Current state: fast = %d, teleport = %d.\n",
(df::global::debug_turbospeed && *df::global::debug_turbospeed) ? 2 : (enable_fastdwarf ? 1 : 0), (df::global::debug_turbospeed && *df::global::debug_turbospeed) ? 2 : (enable_fastdwarf ? 1 : 0),
enable_teledwarf ? 1 : 0); enable_teledwarf ? 1 : 0);
@ -159,6 +163,17 @@ static command_result fastdwarf (color_ostream &out, vector <string> & parameter
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable )
{
if (active != enable)
{
active = enable_fastdwarf = enable;
enable_teledwarf = false;
}
return CR_OK;
}
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand("fastdwarf", commands.push_back(PluginCommand("fastdwarf",

@ -698,7 +698,7 @@ static void try_store_ammo(df::squad *squad)
} }
} }
static bool is_enabled = false; DFHACK_PLUGIN_IS_ENABLED(is_enabled);
DFhackCExport command_result plugin_onupdate(color_ostream &out, state_change_event event) DFhackCExport command_result plugin_onupdate(color_ostream &out, state_change_event event)
{ {
@ -810,6 +810,21 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_enable(color_ostream &out, bool enable)
{
if (!Core::getInstance().isWorldLoaded()) {
out.printerr("World is not loaded: please load a game first.\n");
return CR_FAILURE;
}
if (enable)
enable_plugin(out);
else
disable_plugin(out);
return CR_OK;
}
static command_result fix_armory(color_ostream &out, vector <string> &parameters) static command_result fix_armory(color_ostream &out, vector <string> &parameters)
{ {
CoreSuspender suspend; CoreSuspender suspend;
@ -820,13 +835,9 @@ static command_result fix_armory(color_ostream &out, vector <string> &parameters
string cmd = parameters[0]; string cmd = parameters[0];
if (cmd == "enable") if (cmd == "enable")
{ return plugin_enable(out, true);
enable_plugin(out);
}
else if (cmd == "disable") else if (cmd == "disable")
{ return plugin_enable(out, false);
disable_plugin(out);
}
else else
return CR_WRONG_USAGE; return CR_WRONG_USAGE;

@ -24,6 +24,7 @@ int32_t prevX, prevY, prevZ;
uint8_t prevMenuWidth; uint8_t prevMenuWidth;
DFHACK_PLUGIN("follow"); DFHACK_PLUGIN("follow");
DFHACK_PLUGIN_IS_ENABLED(is_enabled);
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
@ -53,6 +54,7 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan
followedUnit = 0; followedUnit = 0;
prevX=prevY=prevZ = -1; prevX=prevY=prevZ = -1;
prevMenuWidth = 0; prevMenuWidth = 0;
is_enabled = false;
break; break;
default: default:
break; break;
@ -97,6 +99,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out )
} }
else if((prevX != x || prevY != y || prevZ != z) && prevMenuWidth == menu_width) //User has manually moved the window, stop following the unit else if((prevX != x || prevY != y || prevZ != z) && prevMenuWidth == menu_width) //User has manually moved the window, stop following the unit
{ {
is_enabled = false;
followedUnit = 0; followedUnit = 0;
prevX=prevY=prevZ = -1; prevX=prevY=prevZ = -1;
prevMenuWidth = 0; prevMenuWidth = 0;
@ -146,6 +149,7 @@ command_result follow (color_ostream &out, std::vector <std::string> & parameter
followedUnit = Gui::getSelectedUnit(out); followedUnit = Gui::getSelectedUnit(out);
if (followedUnit) if (followedUnit)
{ {
is_enabled = true;
std::ostringstream ss; std::ostringstream ss;
ss << "Unpause to begin following " << df::global::world->raws.creatures.all[followedUnit->race]->name[0]; ss << "Unpause to begin following " << df::global::world->raws.creatures.all[followedUnit->race]->name[0];
if (followedUnit->name.has_name) ss << " " << followedUnit->name.first_name; if (followedUnit->name.has_name) ss << " " << followedUnit->name.first_name;
@ -153,5 +157,6 @@ command_result follow (color_ostream &out, std::vector <std::string> & parameter
out.print(ss.str().c_str()); out.print(ss.str().c_str());
} }
else followedUnit = 0; else followedUnit = 0;
is_enabled = (followedUnit != NULL);
return CR_OK; return CR_OK;
} }

@ -71,7 +71,7 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan
*/ */
static size_t constructionSize = 0; static size_t constructionSize = 0;
static bool enabled = false; DFHACK_PLUGIN_IS_ENABLED(enabled);
void doInfiniteSky(color_ostream& out, int32_t howMany); void doInfiniteSky(color_ostream& out, int32_t howMany);
DFhackCExport command_result plugin_onupdate ( color_ostream &out ) DFhackCExport command_result plugin_onupdate ( color_ostream &out )
@ -155,6 +155,12 @@ void doInfiniteSky(color_ostream& out, int32_t howMany) {
} }
DFhackCExport command_result plugin_enable(color_ostream &out, bool enable)
{
enabled = enable;
return CR_OK;
}
command_result infiniteSky (color_ostream &out, std::vector <std::string> & parameters) command_result infiniteSky (color_ostream &out, std::vector <std::string> & parameters)
{ {
if ( parameters.size() > 1 ) if ( parameters.size() > 1 )

@ -1209,10 +1209,27 @@ IMPLEMENT_VMETHOD_INTERPOSE(unitlist_hook, render);
DFHACK_PLUGIN("manipulator"); DFHACK_PLUGIN("manipulator");
DFHACK_PLUGIN_IS_ENABLED(is_enabled);
DFhackCExport command_result plugin_enable(color_ostream &out, bool enable)
{
if (!gps)
return CR_FAILURE;
if (enable != is_enabled)
{
if (!INTERPOSE_HOOK(unitlist_hook, feed).apply(enable) ||
!INTERPOSE_HOOK(unitlist_hook, render).apply(enable))
return CR_FAILURE;
is_enabled = enable;
}
return CR_OK;
}
DFhackCExport command_result plugin_init ( color_ostream &out, vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, vector <PluginCommand> &commands)
{ {
if (!gps || !INTERPOSE_HOOK(unitlist_hook, feed).apply() || !INTERPOSE_HOOK(unitlist_hook, render).apply())
out.printerr("Could not insert Dwarf Manipulator hooks!\n");
return CR_OK; return CR_OK;
} }

@ -15,6 +15,8 @@ using namespace std;
using namespace DFHack; using namespace DFHack;
DFHACK_PLUGIN_IS_ENABLED(is_enabled);
static int factor = 1; static int factor = 1;
static map<int, int> processedThoughtCountTable; static map<int, int> processedThoughtCountTable;
@ -38,6 +40,7 @@ DFhackCExport command_result plugin_onupdate(color_ostream& out) {
if ( wasLoaded ) { if ( wasLoaded ) {
//we just unloaded the game: clear all data //we just unloaded the game: clear all data
factor = 1; factor = 1;
is_enabled = false;
processedThoughtCountTable.clear(); processedThoughtCountTable.clear();
fakeThoughts.clear(); fakeThoughts.clear();
wasLoaded = false; wasLoaded = false;
@ -138,6 +141,17 @@ DFhackCExport command_result plugin_init(color_ostream& out, vector<PluginComman
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_enable(color_ostream &out, bool enable)
{
if (enable != is_enabled)
{
is_enabled = enable;
factor = enable ? 2 : 1;
}
return CR_OK;
}
command_result misery(color_ostream &out, vector<string>& parameters) { command_result misery(color_ostream &out, vector<string>& parameters) {
if ( !df::global::world || !df::global::world->map.block_index ) { if ( !df::global::world || !df::global::world->map.block_index ) {
out.printerr("misery can only be enabled in fortress mode with a fully-loaded game.\n"); out.printerr("misery can only be enabled in fortress mode with a fully-loaded game.\n");
@ -153,15 +167,18 @@ command_result misery(color_ostream &out, vector<string>& parameters) {
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
factor = 1; factor = 1;
is_enabled = false;
return CR_OK; return CR_OK;
} else if ( parameters[0] == "enable" ) { } else if ( parameters[0] == "enable" ) {
is_enabled = true;
factor = 2; factor = 2;
if ( parameters.size() == 2 ) { if ( parameters.size() == 2 ) {
factor = atoi(parameters[1].c_str()); int a = atoi(parameters[1].c_str());
if ( factor < 1 ) { if ( a <= 1 ) {
out.printerr("Second argument must be a positive integer.\n"); out.printerr("Second argument must be a positive integer.\n");
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
factor = a;
} }
} else if ( parameters[0] == "clear" ) { } else if ( parameters[0] == "clear" ) {
for ( size_t a = 0; a < fakeThoughts.size(); a++ ) { for ( size_t a = 0; a < fakeThoughts.size(); a++ ) {
@ -176,6 +193,7 @@ command_result misery(color_ostream &out, vector<string>& parameters) {
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
factor = a; factor = a;
is_enabled = factor > 1;
} }
return CR_OK; return CR_OK;

@ -33,12 +33,6 @@ DFhackCExport command_result plugin_shutdown ( color_ostream &out )
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_onupdate ( color_ostream &out )
{
// add tracking here
return CR_OK;
}
void printCurrentModes(t_gamemodes gm, Console & con) void printCurrentModes(t_gamemodes gm, Console & con)
{ {
con << "Current game type:\t" << gm.g_type << " ("; con << "Current game type:\t" << gm.g_type << " (";

@ -239,12 +239,28 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest
IMPLEMENT_VMETHOD_INTERPOSE(mousequery_hook, feed); IMPLEMENT_VMETHOD_INTERPOSE(mousequery_hook, feed);
DFHACK_PLUGIN("mousequery"); DFHACK_PLUGIN("mousequery");
DFHACK_PLUGIN_IS_ENABLED(is_enabled);
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable)
{ {
if (!gps || !INTERPOSE_HOOK(mousequery_hook, feed).apply()) if (!gps)
out.printerr("Could not insert mousequery hooks!\n"); return CR_FAILURE;
if (is_enabled != enable)
{
last_x = last_y = last_z = -1;
if (!INTERPOSE_HOOK(mousequery_hook, feed).apply(enable))
return CR_FAILURE;
is_enabled = enable;
}
return CR_OK;
}
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{
last_x = last_y = last_z = -1; last_x = last_y = last_z = -1;
return CR_OK; return CR_OK;

@ -160,7 +160,7 @@ IMPLEMENT_VMETHOD_INTERPOSE(trap_hook, getName);
IMPLEMENT_VMETHOD_INTERPOSE(trap_hook, updateAction); IMPLEMENT_VMETHOD_INTERPOSE(trap_hook, updateAction);
IMPLEMENT_VMETHOD_INTERPOSE(trap_hook, drawBuilding); IMPLEMENT_VMETHOD_INTERPOSE(trap_hook, drawBuilding);
static bool enabled = false; DFHACK_PLUGIN_IS_ENABLED(enabled);
static void enable_hooks(bool enable) static void enable_hooks(bool enable)
{ {

@ -55,6 +55,7 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan
static command_result rename(color_ostream &out, vector <string> & parameters); static command_result rename(color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("rename"); DFHACK_PLUGIN("rename");
DFHACK_PLUGIN_IS_ENABLED(is_enabled);
DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands)
{ {
@ -174,6 +175,9 @@ KNOWN_BUILDINGS
static bool enable_building_rename(char code, bool enable) static bool enable_building_rename(char code, bool enable)
{ {
if (enable)
is_enabled = true;
if (code == 'Z') if (code == 'Z')
INTERPOSE_HOOK(dwarf_render_zone_hook, render).apply(enable); INTERPOSE_HOOK(dwarf_render_zone_hook, render).apply(enable);
@ -189,6 +193,7 @@ KNOWN_BUILDINGS
static void disable_building_rename() static void disable_building_rename()
{ {
is_enabled = false;
INTERPOSE_HOOK(dwarf_render_zone_hook, render).remove(); INTERPOSE_HOOK(dwarf_render_zone_hook, render).remove();
#define BUILDING(code, cname, tag) \ #define BUILDING(code, cname, tag) \

@ -107,7 +107,7 @@ struct SuspendedBuilding
} }
}; };
static bool enabled = false; DFHACK_PLUGIN_IS_ENABLED(enabled);
static bool buildings_scanned = false; static bool buildings_scanned = false;
static vector<SuspendedBuilding> suspended_buildings, resumed_buildings; static vector<SuspendedBuilding> suspended_buildings, resumed_buildings;
@ -234,6 +234,23 @@ struct resume_hook : public df::viewscreen_dwarfmodest
IMPLEMENT_VMETHOD_INTERPOSE(resume_hook, render); IMPLEMENT_VMETHOD_INTERPOSE(resume_hook, render);
DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable)
{
if (!gps)
return CR_FAILURE;
if (enabled != enable)
{
clear_scanned();
if (!INTERPOSE_HOOK(resume_hook, render).apply(enable))
return CR_FAILURE;
enabled = enable;
}
return CR_OK;
}
static command_result resume_cmd(color_ostream &out, vector <string> & parameters) static command_result resume_cmd(color_ostream &out, vector <string> & parameters)
{ {
@ -251,12 +268,12 @@ static command_result resume_cmd(color_ostream &out, vector <string> & parameter
} }
else if (cmd == 's') else if (cmd == 's')
{ {
enabled = true; plugin_enable(out, true);
out << "Overlay enabled" << endl; out << "Overlay enabled" << endl;
} }
else if (cmd == 'h') else if (cmd == 'h')
{ {
enabled = false; plugin_enable(out, false);
out << "Overlay disabled" << endl; out << "Overlay disabled" << endl;
} }
else if (cmd == 'a') else if (cmd == 'a')
@ -275,12 +292,8 @@ static command_result resume_cmd(color_ostream &out, vector <string> & parameter
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
if (!gps || !INTERPOSE_HOOK(resume_hook, render).apply())
out.printerr("Could not insert resume hooks!\n");
commands.push_back( commands.push_back(
PluginCommand( PluginCommand(
"resume", "A plugin to help display and resume suspended constructions conveniently", "resume", "A plugin to help display and resume suspended constructions conveniently",

@ -85,6 +85,8 @@ DFhackCExport command_result plugin_init ( color_ostream &out, vector <PluginCom
return CR_OK; return CR_OK;
} }
DFHACK_PLUGIN_IS_ENABLED(is_active);
DFhackCExport command_result plugin_onupdate ( color_ostream &out ) DFhackCExport command_result plugin_onupdate ( color_ostream &out )
{ {
t_gamemodes gm; t_gamemodes gm;
@ -117,6 +119,7 @@ command_result nopause (color_ostream &out, vector <string> & parameters)
nopause_state = 0; nopause_state = 0;
else else
nopause_state = 1; nopause_state = 1;
is_active = nopause_state || (revealed == REVEALED);
out.print("nopause %sactivated.\n", (nopause_state ? "" : "de")); out.print("nopause %sactivated.\n", (nopause_state ? "" : "de"));
} }
else else
@ -237,6 +240,7 @@ command_result reveal(color_ostream &out, vector<string> & params)
else else
revealed = DEMON_REVEALED; revealed = DEMON_REVEALED;
} }
is_active = nopause_state || (revealed == REVEALED);
con.print("Map revealed.\n"); con.print("Map revealed.\n");
if(!no_hell) if(!no_hell)
con.print("Unpausing can unleash the forces of hell, so it has been temporarily disabled.\n"); con.print("Unpausing can unleash the forces of hell, so it has been temporarily disabled.\n");
@ -296,6 +300,7 @@ command_result unreveal(color_ostream &out, vector<string> & params)
// give back memory. // give back memory.
hidesaved.clear(); hidesaved.clear();
revealed = NOT_REVEALED; revealed = NOT_REVEALED;
is_active = nopause_state || (revealed == REVEALED);
con.print("Map hidden!\n"); con.print("Map hidden!\n");
return CR_OK; return CR_OK;
} }
@ -490,6 +495,7 @@ command_result revforget(color_ostream &out, vector<string> & params)
// give back memory. // give back memory.
hidesaved.clear(); hidesaved.clear();
revealed = NOT_REVEALED; revealed = NOT_REVEALED;
is_active = nopause_state || (revealed == REVEALED);
con.print("Reveal data forgotten!\n"); con.print("Reveal data forgotten!\n");
return CR_OK; return CR_OK;
} }

@ -1609,6 +1609,7 @@ IMPLEMENT_HOOKS(df::viewscreen_dwarfmodest, burrow_search);
DFHACK_PLUGIN("search"); DFHACK_PLUGIN("search");
DFHACK_PLUGIN_IS_ENABLED(is_enabled);
#define SEARCH_HOOKS \ #define SEARCH_HOOKS \
HOOK_ACTION(unitlist_search_hook) \ HOOK_ACTION(unitlist_search_hook) \
@ -1624,15 +1625,28 @@ DFHACK_PLUGIN("search");
HOOK_ACTION(burrow_search_hook) \ HOOK_ACTION(burrow_search_hook) \
HOOK_ACTION(stockpile_search_hook) HOOK_ACTION(stockpile_search_hook)
DFhackCExport command_result plugin_init ( color_ostream &out, vector <PluginCommand> &commands) DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable)
{ {
if (!gps || !gview)
return CR_FAILURE;
if (is_enabled != enable)
{
#define HOOK_ACTION(hook) \ #define HOOK_ACTION(hook) \
!INTERPOSE_HOOK(hook, feed).apply() || \ !INTERPOSE_HOOK(hook, feed).apply(enable) || \
!INTERPOSE_HOOK(hook, render).apply() || !INTERPOSE_HOOK(hook, render).apply(enable) ||
if (SEARCH_HOOKS 0)
return CR_FAILURE;
is_enabled = enable;
}
if (!gps || !gview || SEARCH_HOOKS 0) return CR_OK;
out.printerr("Could not insert Search hooks!\n"); }
DFhackCExport command_result plugin_init ( color_ostream &out, vector <PluginCommand> &commands)
{
#undef HOOK_ACTION #undef HOOK_ACTION
const string a[] = {"Meager Quarters", "Modest Quarters", "Quarters", "Decent Quarters", "Fine Quarters", "Great Bedroom", "Grand Bedroom", "Royal Bedroom"}; const string a[] = {"Meager Quarters", "Modest Quarters", "Quarters", "Decent Quarters", "Fine Quarters", "Great Bedroom", "Grand Bedroom", "Royal Bedroom"};

@ -22,7 +22,7 @@ using namespace df::enums;
using df::global::world; using df::global::world;
const int buffer = 20; // seed number buffer - 20 is reasonable const int buffer = 20; // seed number buffer - 20 is reasonable
bool running = false; // whether seedwatch is counting the seeds or not DFHACK_PLUGIN_IS_ENABLED(running); // whether seedwatch is counting the seeds or not
// abbreviations for the standard plants // abbreviations for the standard plants
map<string, string> abbreviations; map<string, string> abbreviations;
@ -96,6 +96,12 @@ string searchAbbreviations(string in)
} }
}; };
DFhackCExport command_result plugin_enable(color_ostream &out, bool enable)
{
running = enable;
return CR_OK;
}
command_result df_seedwatch(color_ostream &out, vector<string>& parameters) command_result df_seedwatch(color_ostream &out, vector<string>& parameters)
{ {
CoreSuspender suspend; CoreSuspender suspend;

@ -1766,7 +1766,7 @@ DFHACK_PLUGIN_LUA_COMMANDS {
DFHACK_LUA_END DFHACK_LUA_END
}; };
static bool is_enabled = false; DFHACK_PLUGIN_IS_ENABLED(is_enabled);
static void enable_hooks(bool enable) static void enable_hooks(bool enable)
{ {
@ -1809,6 +1809,25 @@ static void clear_caches(color_ostream &out)
} }
} }
DFhackCExport command_result plugin_enable(color_ostream &out, bool enable)
{
if (gamemode && *gamemode != game_mode::DWARF)
return CR_FAILURE;
if (enable != is_enabled)
{
if (enable)
enable_plugin();
else
{
World::DeletePersistentData(World::GetPersistentData("siege-engine/enabled"));
enable_hooks(false);
}
}
return CR_OK;
}
DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event) DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event)
{ {
switch (event) { switch (event) {

@ -950,8 +950,12 @@ static bool find_engines(color_ostream &out)
return !engines.empty(); return !engines.empty();
} }
DFHACK_PLUGIN_IS_ENABLED(is_enabled);
static void enable_hooks(bool enable) static void enable_hooks(bool enable)
{ {
is_enabled = enable;
INTERPOSE_HOOK(liquid_hook, getItemDescription).apply(enable); INTERPOSE_HOOK(liquid_hook, getItemDescription).apply(enable);
INTERPOSE_HOOK(liquid_hook, adjustTemperature).apply(enable); INTERPOSE_HOOK(liquid_hook, adjustTemperature).apply(enable);
INTERPOSE_HOOK(liquid_hook, checkTemperatureDamage).apply(enable); INTERPOSE_HOOK(liquid_hook, checkTemperatureDamage).apply(enable);

@ -402,7 +402,8 @@ public:
* GLOBAL VARIABLES * * GLOBAL VARIABLES *
******************************/ ******************************/
static bool enabled = false; DFHACK_PLUGIN_IS_ENABLED(enabled);
static PersistentDataItem config; static PersistentDataItem config;
static int last_tick_frame_count = 0; static int last_tick_frame_count = 0;
@ -1387,10 +1388,13 @@ static void update_data_structures(color_ostream &out)
* LUA API * * LUA API *
*************/ *************/
static bool isEnabled() { return enabled; } DFhackCExport command_result plugin_enable(color_ostream &out, bool enable)
static void setEnabled(color_ostream &out, bool enable)
{ {
if (!Core::getInstance().isWorldLoaded()) {
out.printerr("World is not loaded: please load a game first.\n");
return CR_FAILURE;
}
if (enable && !enabled) if (enable && !enabled)
{ {
enable_plugin(out); enable_plugin(out);
@ -1401,6 +1405,8 @@ static void setEnabled(color_ostream &out, bool enable)
setOptionEnabled(CF_ENABLED, false); setOptionEnabled(CF_ENABLED, false);
stop_protect(out); stop_protect(out);
} }
return CR_OK;
} }
static void push_count_history(lua_State *L, ItemConstraint *icv) static void push_count_history(lua_State *L, ItemConstraint *icv)
@ -1591,8 +1597,6 @@ static int getCountHistory(lua_State *L)
DFHACK_PLUGIN_LUA_FUNCTIONS { DFHACK_PLUGIN_LUA_FUNCTIONS {
DFHACK_LUA_FUNCTION(isEnabled),
DFHACK_LUA_FUNCTION(setEnabled),
DFHACK_LUA_FUNCTION(deleteConstraint), DFHACK_LUA_FUNCTION(deleteConstraint),
DFHACK_LUA_END DFHACK_LUA_END
}; };
@ -1767,10 +1771,10 @@ static command_result workflow_cmd(color_ostream &out, vector <string> & paramet
{ {
bool enable = (cmd == "enable"); bool enable = (cmd == "enable");
if (enable) if (enable)
setEnabled(out, true); plugin_enable(out, true);
else if (parameters.size() == 1) else if (parameters.size() == 1)
{ {
setEnabled(out, false); plugin_enable(out, false);
out << "The plugin is disabled." << endl; out << "The plugin is disabled." << endl;
return CR_OK; return CR_OK;
@ -1805,7 +1809,10 @@ static command_result workflow_cmd(color_ostream &out, vector <string> & paramet
} }
if (!enabled) if (!enabled)
out << "Note: the plugin is not enabled." << endl; {
out.printerr("Error: the plugin is not enabled.\n");
return CR_WRONG_USAGE;
}
if (cmd == "jobs") if (cmd == "jobs")
{ {

@ -88,6 +88,10 @@ command_result df_autobutcher(color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("zone"); DFHACK_PLUGIN("zone");
DFHACK_PLUGIN_IS_ENABLED(is_enabled);
DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable);
const string zone_help = const string zone_help =
"Allows easier management of pens/pastures, pits and cages.\n" "Allows easier management of pens/pastures, pits and cages.\n"
"Options:\n" "Options:\n"
@ -3015,6 +3019,7 @@ command_result df_autobutcher(color_ostream &out, vector <string> & parameters)
} }
else if (p == "start") else if (p == "start")
{ {
plugin_enable(out, true);
enable_autobutcher = true; enable_autobutcher = true;
start_autobutcher(out); start_autobutcher(out);
return autoButcher(out, verbose); return autoButcher(out, verbose);
@ -3485,6 +3490,7 @@ command_result autoButcher( color_ostream &out, bool verbose = false )
command_result start_autobutcher(color_ostream &out) command_result start_autobutcher(color_ostream &out)
{ {
plugin_enable(out, true);
enable_autobutcher = true; enable_autobutcher = true;
if (!config_autobutcher.isValid()) if (!config_autobutcher.isValid())
@ -3545,6 +3551,7 @@ command_result init_autobutcher(color_ostream &out)
if(!enable_autobutcher) if(!enable_autobutcher)
return CR_OK; return CR_OK;
plugin_enable(out, true);
// read watchlist from save // read watchlist from save
std::vector<PersistentDataItem> items; std::vector<PersistentDataItem> items;
@ -3579,6 +3586,7 @@ command_result cleanup_autobutcher(color_ostream &out)
command_result start_autonestbox(color_ostream &out) command_result start_autonestbox(color_ostream &out)
{ {
plugin_enable(out, true);
enable_autonestbox = true; enable_autonestbox = true;
if (!config_autonestbox.isValid()) if (!config_autonestbox.isValid())
@ -3620,6 +3628,8 @@ command_result init_autonestbox(color_ostream &out)
sleep_autonestbox = config_autonestbox.ival(1); sleep_autonestbox = config_autonestbox.ival(1);
} }
} }
if (enable_autonestbox)
plugin_enable(out, true);
return CR_OK; return CR_OK;
} }
@ -3856,6 +3866,9 @@ static void autobutcher_setEnabled(color_ostream &out, bool enable)
config_autobutcher.ival(0) = enable_autobutcher; config_autobutcher.ival(0) = enable_autobutcher;
out << "Autobutcher stopped." << endl; out << "Autobutcher stopped." << endl;
} }
if (enable)
plugin_enable(out, true);
} }
static void autowatch_setEnabled(color_ostream &out, bool enable) static void autowatch_setEnabled(color_ostream &out, bool enable)
@ -4455,12 +4468,25 @@ IMPLEMENT_VMETHOD_INTERPOSE(zone_hook, feed);
IMPLEMENT_VMETHOD_INTERPOSE(zone_hook, render); IMPLEMENT_VMETHOD_INTERPOSE(zone_hook, render);
//END zone filters //END zone filters
DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable)
{
if (!gps)
return CR_FAILURE;
if (enable != is_enabled)
{
if (!INTERPOSE_HOOK(zone_hook, feed).apply(enable) ||
!INTERPOSE_HOOK(zone_hook, render).apply(enable))
return CR_FAILURE;
is_enabled = enable;
}
return CR_OK;
}
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
if (!gps || !INTERPOSE_HOOK(zone_hook, feed).apply() || !INTERPOSE_HOOK(zone_hook, render).apply())
out.printerr("Could not insert jobutils hooks!\n");
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"zone", "manage activity zones.", "zone", "manage activity zones.",
df_zone, false, df_zone, false,