From f3626c100451e6d83bc04d9a95d95482976ee1c5 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 25 Aug 2014 21:24:23 -0400 Subject: [PATCH] embark-tools cleanup Fix #358: Disable "s" keybinding for settings on notes screen --- plugins/embark-tools.cpp | 656 ++++++++++++++++++++++----------------- 1 file changed, 366 insertions(+), 290 deletions(-) diff --git a/plugins/embark-tools.cpp b/plugins/embark-tools.cpp index 148e6787f..44a79f2be 100644 --- a/plugins/embark-tools.cpp +++ b/plugins/embark-tools.cpp @@ -11,98 +11,13 @@ #include #include "ColorText.h" +#include "uicommon.h" #include "df/viewscreen_choose_start_sitest.h" #include "df/interface_key.h" using namespace DFHack; -struct EmbarkTool -{ - std::string id; - std::string name; - std::string desc; - bool enabled; - df::interface_key toggle_key; -}; - -EmbarkTool embark_tools[] = { - {"anywhere", "Embark anywhere", "Allows embarking anywhere on the world map", - false, df::interface_key::CUSTOM_A}, - {"nano", "Nano embark", "Allows the embark size to be decreased below 2x2", - false, df::interface_key::CUSTOM_N}, - {"sand", "Sand indicator", "Displays an indicator when sand is present on the given embark site", - false, df::interface_key::CUSTOM_S}, - {"sticky", "Stable position", "Maintains the selected local area while navigating the world map", - false, df::interface_key::CUSTOM_P}, -}; -#define NUM_TOOLS int(sizeof(embark_tools) / sizeof(EmbarkTool)) - -command_result embark_tools_cmd (color_ostream &out, std::vector & parameters); - -void OutputString (int8_t color, int &x, int y, const std::string &text); - -bool tool_exists (std::string tool_name); -bool tool_enabled (std::string tool_name); -bool tool_enable (std::string tool_name, bool enable_state); -void tool_update (std::string tool_name); - -class embark_tools_settings : public dfhack_viewscreen -{ -public: - embark_tools_settings () { }; - ~embark_tools_settings () { }; - void help () { }; - std::string getFocusString () { return "embark-tools/options"; }; - void render () - { - parent->render(); - int x; - auto dim = Screen::getWindowSize(); - int width = 50, - height = 4 + 1 + NUM_TOOLS, // Padding + lower row - min_x = (dim.x - width) / 2, - max_x = (dim.x + width) / 2, - min_y = (dim.y - height) / 2, - max_y = min_y + height; - Screen::fillRect(Screen::Pen(' ', COLOR_BLACK, COLOR_DARKGREY), min_x, min_y, max_x, max_y); - Screen::fillRect(Screen::Pen(' ', COLOR_BLACK, COLOR_BLACK), min_x + 1, min_y + 1, max_x - 1, max_y - 1); - x = min_x + 2; - OutputString(COLOR_LIGHTRED, x, max_y - 2, Screen::getKeyDisplay(df::interface_key::SELECT)); - OutputString(COLOR_WHITE, x, max_y - 2, "/"); - OutputString(COLOR_LIGHTRED, x, max_y - 2, Screen::getKeyDisplay(df::interface_key::LEAVESCREEN)); - OutputString(COLOR_WHITE, x, max_y - 2, ": Done"); - for (int i = 0, y = min_y + 2; i < NUM_TOOLS; i++, y++) - { - EmbarkTool t = embark_tools[i]; - x = min_x + 2; - OutputString(COLOR_LIGHTRED, x, y, Screen::getKeyDisplay(t.toggle_key)); - OutputString(COLOR_WHITE, x, y, ": " + t.name + (t.enabled ? ": Enabled" : ": Disabled")); - } - }; - void feed (std::set * input) - { - if (input->count(df::interface_key::SELECT) || input->count(df::interface_key::LEAVESCREEN)) - { - Screen::dismiss(this); - return; - } - for (auto iter = input->begin(); iter != input->end(); iter++) - { - df::interface_key key = *iter; - for (int i = 0; i < NUM_TOOLS; i++) - { - if (embark_tools[i].toggle_key == key) - { - embark_tools[i].enabled = !embark_tools[i].enabled; - } - } - } - }; -}; - -/* - * Logic - */ +#define FOR_ITER_TOOLS(iter) for(auto iter = tools.begin(); iter != tools.end(); iter++) void update_embark_sidebar (df::viewscreen_choose_start_sitest * screen) { @@ -159,238 +74,317 @@ void resize_embark (df::viewscreen_choose_start_sitest * screen, int dx, int dy) update_embark_sidebar(screen); } -std::string sand_indicator = ""; -bool sand_dirty = true; // Flag set when update is needed -void sand_update (df::viewscreen_choose_start_sitest * screen) -{ - CoreSuspendClaimer suspend; - buffered_color_ostream out; - Core::getInstance().runCommand(out, "prospect"); - auto fragments = out.fragments(); - sand_indicator = ""; - for (auto iter = fragments.begin(); iter != fragments.end(); iter++) - { - std::string fragment = iter->second; - if (fragment.find("SAND_") != std::string::npos) - { - sand_indicator = "Sand"; - break; - } - } - sand_dirty = false; -} +typedef df::viewscreen_choose_start_sitest start_sitest; +typedef std::set ikey_set; -int sticky_pos[] = {0, 0, 3, 3}; -bool sticky_moved = false; -void sticky_save (df::viewscreen_choose_start_sitest * screen) +class EmbarkTool { - sticky_pos[0] = screen->location.embark_pos_min.x; - sticky_pos[1] = screen->location.embark_pos_max.x; - sticky_pos[2] = screen->location.embark_pos_min.y; - sticky_pos[3] = screen->location.embark_pos_max.y; -} - -void sticky_apply (df::viewscreen_choose_start_sitest * screen) -{ - if (screen->finder.finder_state != -1) - { - // Site finder is active - don't override default local position - return; - } - screen->location.embark_pos_min.x = sticky_pos[0]; - screen->location.embark_pos_max.x = sticky_pos[1]; - screen->location.embark_pos_min.y = sticky_pos[2]; - screen->location.embark_pos_max.y = sticky_pos[3]; - update_embark_sidebar(screen); -} +protected: + bool enabled; +public: + EmbarkTool() + :enabled(false) + { } + virtual bool getEnabled() { return enabled; } + virtual void setEnabled(bool state) { enabled = state; } + virtual void toggleEnabled() { setEnabled(!enabled); } + virtual std::string getId() = 0; + virtual std::string getName() = 0; + virtual std::string getDesc() = 0; + virtual df::interface_key getToggleKey() = 0; + virtual void before_render(start_sitest* screen) { }; + virtual void after_render(start_sitest* screen) { }; + virtual void before_feed(start_sitest* screen, ikey_set* input, bool &cancel) { }; + virtual void after_feed(start_sitest* screen, ikey_set* input) { }; +}; +std::vector tools; /* - * Viewscreen hooks - */ -void OutputString (int8_t color, int &x, int y, const std::string &text) +class SampleTool : public EmbarkTool { - Screen::paintString(Screen::Pen(' ', color, 0), x, y, text); - x += text.length(); -} + virtual std::string getId() { return "id"; } + virtual std::string getName() { return "Name"; } + virtual std::string getDesc() { return "Description"; } + virtual df::interface_key getToggleKey() { return df::interface_key::KEY; } + virtual void before_render(start_sitest* screen) { } + virtual void after_render(start_sitest* screen) { } + virtual void before_feed(start_sitest* screen, ikey_set* input, bool &cancel) { }; + virtual void after_feed(start_sitest* screen, ikey_set* input) { }; +}; -struct choose_start_site_hook : df::viewscreen_choose_start_sitest -{ - typedef df::viewscreen_choose_start_sitest interpose_base; +*/ - DEFINE_VMETHOD_INTERPOSE(void, feed, (std::set *input)) +class EmbarkAnywhere : public EmbarkTool +{ +public: + virtual std::string getId() { return "anywhere"; } + virtual std::string getName() { return "Embark anywhere"; } + virtual std::string getDesc() { return "Allows embarking anywhere on the world map"; } + virtual df::interface_key getToggleKey() { return df::interface_key::CUSTOM_A; } + virtual void after_render(start_sitest* screen) { - bool prevent_default = false; - if (tool_enabled("anywhere")) + auto dim = Screen::getWindowSize(); + int x = 20, y = dim.y - 2; + if (screen->page >= 0 && screen->page <= 4) { - for (auto iter = input->begin(); iter != input->end(); iter++) - { - df::interface_key key = *iter; - if (key == df::interface_key::SETUP_EMBARK) - { - prevent_default = true; - this->in_embark_normal = 1; - } - } + OutputString(COLOR_WHITE, x, y, ": Embark!"); } - - if (input->count(df::interface_key::CUSTOM_S)) + } + virtual void before_feed(start_sitest* screen, ikey_set *input, bool &cancel) + { + if (input->count(df::interface_key::SETUP_EMBARK)) { - Screen::show(new embark_tools_settings); - return; + cancel = true; + screen->in_embark_normal = 1; } + }; +}; - if (tool_enabled("nano")) +class NanoEmbark : public EmbarkTool +{ +public: + virtual std::string getId() { return "nano"; } + virtual std::string getName() { return "Nano embark"; } + virtual std::string getDesc() { return "Allows the embark size to be decreased below 2x2"; } + virtual df::interface_key getToggleKey() { return df::interface_key::CUSTOM_N; } + virtual void before_feed(start_sitest* screen, ikey_set* input, bool &cancel) + { + for (auto iter = input->begin(); iter != input->end(); iter++) { - for (auto iter = input->begin(); iter != input->end(); iter++) + df::interface_key key = *iter; + bool is_resize = true; + int dx = 0, dy = 0; + switch (key) { - df::interface_key key = *iter; - bool is_resize = true; - int dx = 0, dy = 0; - switch (key) - { - case df::interface_key::SETUP_LOCAL_Y_UP: - dy = 1; - break; - case df::interface_key::SETUP_LOCAL_Y_DOWN: - dy = -1; - break; - case df::interface_key::SETUP_LOCAL_X_UP: - dx = 1; - break; - case df::interface_key::SETUP_LOCAL_X_DOWN: - dx = -1; - break; - default: - is_resize = false; - } - if (is_resize) - { - prevent_default = true; - resize_embark(this, dx, dy); - } + case df::interface_key::SETUP_LOCAL_Y_UP: + dy = 1; + break; + case df::interface_key::SETUP_LOCAL_Y_DOWN: + dy = -1; + break; + case df::interface_key::SETUP_LOCAL_X_UP: + dx = 1; + break; + case df::interface_key::SETUP_LOCAL_X_DOWN: + dx = -1; + break; + default: + is_resize = false; + } + if (is_resize) + { + cancel = true; + resize_embark(screen, dx, dy); + return; } } + }; +}; - if (tool_enabled("sticky")) +class SandIndicator : public EmbarkTool +{ +protected: + bool dirty; + std::string indicator; + void update_indicator() + { + CoreSuspendClaimer suspend; + buffered_color_ostream out; + Core::getInstance().runCommand(out, "prospect"); + auto fragments = out.fragments(); + indicator = ""; + for (auto iter = fragments.begin(); iter != fragments.end(); iter++) { - for (auto iter = input->begin(); iter != input->end(); iter++) + std::string fragment = iter->second; + if (fragment.find("SAND_") != std::string::npos) { - df::interface_key key = *iter; - bool is_motion = false; - int dx = 0, dy = 0; - switch (key) - { - case df::interface_key::CURSOR_UP: - case df::interface_key::CURSOR_DOWN: - case df::interface_key::CURSOR_LEFT: - case df::interface_key::CURSOR_RIGHT: - case df::interface_key::CURSOR_UPLEFT: - case df::interface_key::CURSOR_UPRIGHT: - case df::interface_key::CURSOR_DOWNLEFT: - case df::interface_key::CURSOR_DOWNRIGHT: - case df::interface_key::CURSOR_UP_FAST: - case df::interface_key::CURSOR_DOWN_FAST: - case df::interface_key::CURSOR_LEFT_FAST: - case df::interface_key::CURSOR_RIGHT_FAST: - case df::interface_key::CURSOR_UPLEFT_FAST: - case df::interface_key::CURSOR_UPRIGHT_FAST: - case df::interface_key::CURSOR_DOWNLEFT_FAST: - case df::interface_key::CURSOR_DOWNRIGHT_FAST: - is_motion = true; - break; - default: - is_motion = false; - } - if (is_motion && !sticky_moved) - { - sticky_save(this); - sticky_moved = true; - } + indicator = "Sand"; + break; } } - - if (tool_enabled("sand")) + dirty = false; + } +public: + SandIndicator() + :EmbarkTool(), + dirty(true), + indicator("") + { } + virtual void setEnabled(bool state) + { + EmbarkTool::setEnabled(state); + dirty = true; + } + virtual std::string getId() { return "sand"; } + virtual std::string getName() { return "Sand indicator"; } + virtual std::string getDesc() { return "Displays an indicator when sand is present on the given embark site"; } + virtual df::interface_key getToggleKey() { return df::interface_key::CUSTOM_S; } + virtual void after_render(start_sitest* screen) + { + if (dirty) + update_indicator(); + auto dim = Screen::getWindowSize(); + int x = dim.x - 28, + y = 13; + if (screen->page == 0) { - sand_dirty = true; + OutputString(COLOR_YELLOW, x, y, indicator); } - if (!prevent_default) - INTERPOSE_NEXT(feed)(input); } + virtual void after_feed(start_sitest* screen, ikey_set* input) + { + dirty = true; + }; +}; - DEFINE_VMETHOD_INTERPOSE(void, render, ()) +class StablePosition : public EmbarkTool +{ +protected: + int prev_position[4]; + bool moved_position; + void save_position(start_sitest* screen) + { + prev_position[0] = screen->location.embark_pos_min.x; + prev_position[1] = screen->location.embark_pos_max.x; + prev_position[2] = screen->location.embark_pos_min.y; + prev_position[3] = screen->location.embark_pos_max.y; + } + void restore_position(start_sitest* screen) { - if (tool_enabled("sticky") && sticky_moved) + if (screen->finder.finder_state != -1) { - sticky_apply(this); - sticky_moved = false; + // Site finder is active - don't override default local position + return; } - - INTERPOSE_NEXT(render)(); - - auto dim = Screen::getWindowSize(); - int x = 1, - y = dim.y - 5; - OutputString(COLOR_LIGHTRED, x, y, Screen::getKeyDisplay(df::interface_key::CUSTOM_S)); - OutputString(COLOR_WHITE, x, y, ": Enabled: "); - std::list parts; - for (int i = 0; i < NUM_TOOLS; i++) + screen->location.embark_pos_min.x = prev_position[0]; + screen->location.embark_pos_max.x = prev_position[1]; + screen->location.embark_pos_min.y = prev_position[2]; + screen->location.embark_pos_max.y = prev_position[3]; + update_embark_sidebar(screen); + } +public: + StablePosition() + :EmbarkTool(), + moved_position(false) + { + prev_position[0] = 0; + prev_position[1] = 0; + prev_position[2] = 3; + prev_position[3] = 3; + } + virtual std::string getId() { return "sticky"; } + virtual std::string getName() { return "Stable position"; } + virtual std::string getDesc() { return "Maintains the selected local area while navigating the world map"; } + virtual df::interface_key getToggleKey() { return df::interface_key::CUSTOM_P; } + virtual void before_render(start_sitest* screen) { + if (moved_position) { - if (embark_tools[i].enabled) - { - parts.push_back(embark_tools[i].name); - parts.push_back(", "); - } + restore_position(screen); + moved_position = false; } - if (parts.size()) + } + virtual void before_feed(start_sitest* screen, ikey_set* input, bool &cancel) { + for (auto iter = input->begin(); iter != input->end(); iter++) { - parts.pop_back(); // Remove trailing comma - for (auto iter = parts.begin(); iter != parts.end(); iter++) + df::interface_key key = *iter; + bool is_motion = false; + int dx = 0, dy = 0; + switch (key) { - OutputString(COLOR_LIGHTMAGENTA, x, y, *iter); + case df::interface_key::CURSOR_UP: + case df::interface_key::CURSOR_DOWN: + case df::interface_key::CURSOR_LEFT: + case df::interface_key::CURSOR_RIGHT: + case df::interface_key::CURSOR_UPLEFT: + case df::interface_key::CURSOR_UPRIGHT: + case df::interface_key::CURSOR_DOWNLEFT: + case df::interface_key::CURSOR_DOWNRIGHT: + case df::interface_key::CURSOR_UP_FAST: + case df::interface_key::CURSOR_DOWN_FAST: + case df::interface_key::CURSOR_LEFT_FAST: + case df::interface_key::CURSOR_RIGHT_FAST: + case df::interface_key::CURSOR_UPLEFT_FAST: + case df::interface_key::CURSOR_UPRIGHT_FAST: + case df::interface_key::CURSOR_DOWNLEFT_FAST: + case df::interface_key::CURSOR_DOWNRIGHT_FAST: + is_motion = true; + break; + } + if (is_motion && !moved_position) + { + save_position(screen); + moved_position = true; } } - else + }; +}; + +class embark_tools_settings : public dfhack_viewscreen +{ +public: + embark_tools_settings () { }; + ~embark_tools_settings () { }; + void help () { }; + std::string getFocusString () { return "embark-tools/options"; }; + void render () + { + parent->render(); + int x, y; + auto dim = Screen::getWindowSize(); + int width = 50, + height = 4 + 1 + tools.size(), // Padding + lower row + min_x = (dim.x - width) / 2, + max_x = (dim.x + width) / 2, + min_y = (dim.y - height) / 2, + max_y = min_y + height; + Screen::fillRect(Screen::Pen(' ', COLOR_BLACK, COLOR_DARKGREY), min_x, min_y, max_x, max_y); + Screen::fillRect(Screen::Pen(' ', COLOR_BLACK, COLOR_BLACK), min_x + 1, min_y + 1, max_x - 1, max_y - 1); + x = min_x + 2; + y = max_y - 2; + OutputString(COLOR_LIGHTRED, x, y, Screen::getKeyDisplay(df::interface_key::SELECT)); + OutputString(COLOR_WHITE, x, y, "/"); + OutputString(COLOR_LIGHTRED, x, y, Screen::getKeyDisplay(df::interface_key::LEAVESCREEN)); + OutputString(COLOR_WHITE, x, y, ": Done"); + y = min_y + 2; + FOR_ITER_TOOLS(iter) { - OutputString(COLOR_LIGHTMAGENTA, x, y, "(none)"); + EmbarkTool* t = *iter; + x = min_x + 2; + OutputString(COLOR_LIGHTRED, x, y, Screen::getKeyDisplay(t->getToggleKey())); + OutputString(COLOR_WHITE, x, y, ": " + t->getName() + + (t->getEnabled() ? ": Enabled" : ": Disabled")); + y++; } - - if (tool_enabled("anywhere")) + }; + void feed (std::set * input) + { + if (input->count(df::interface_key::SELECT) || input->count(df::interface_key::LEAVESCREEN)) { - x = 20; y = dim.y - 2; - if (this->page >= 0 && this->page <= 4) - { - // Only display on five map pages, not on site finder or notes - OutputString(COLOR_WHITE, x, y, ": Embark!"); - } + Screen::dismiss(this); + return; } - if (tool_enabled("sand")) + for (auto iter = input->begin(); iter != input->end(); iter++) { - if (sand_dirty) - { - sand_update(this); - } - x = dim.x - 28; y = 13; - if (this->page == 0) + df::interface_key key = *iter; + FOR_ITER_TOOLS(iter) { - OutputString(COLOR_YELLOW, x, y, sand_indicator); + EmbarkTool* t = *iter; + if (t->getToggleKey() == key) + { + t->toggleEnabled(); + } } } - } + }; }; -IMPLEMENT_VMETHOD_INTERPOSE(choose_start_site_hook, feed); -IMPLEMENT_VMETHOD_INTERPOSE(choose_start_site_hook, render); - -/* - * Tool management - */ - bool tool_exists (std::string tool_name) { - for (int i = 0; i < NUM_TOOLS; i++) + FOR_ITER_TOOLS(iter) { - if (embark_tools[i].id == tool_name) + EmbarkTool* tool = *iter; + if (tool->getId() == tool_name) return true; } return false; @@ -398,10 +392,11 @@ bool tool_exists (std::string tool_name) bool tool_enabled (std::string tool_name) { - for (int i = 0; i < NUM_TOOLS; i++) + FOR_ITER_TOOLS(iter) { - if (embark_tools[i].id == tool_name) - return embark_tools[i].enabled; + EmbarkTool* tool = *iter; + if (tool->getId() == tool_name) + return tool->getEnabled(); } return false; } @@ -409,42 +404,122 @@ bool tool_enabled (std::string tool_name) bool tool_enable (std::string tool_name, bool enable_state) { int n = 0; - for (int i = 0; i < NUM_TOOLS; i++) + FOR_ITER_TOOLS(iter) { - if (embark_tools[i].id == tool_name || tool_name == "all") + EmbarkTool* tool = *iter; + if (tool->getId() == tool_name || tool_name == "all") { - embark_tools[i].enabled = enable_state; - tool_update(tool_name); + tool->setEnabled(enable_state); n++; } } return (bool)n; } -void tool_update (std::string tool_name) +struct choose_start_site_hook : df::viewscreen_choose_start_sitest { - // Called whenever a tool is enabled/disabled - if (tool_name == "sand") + typedef df::viewscreen_choose_start_sitest interpose_base; + + void display_tool_status() + { + auto dim = Screen::getWindowSize(); + int x = 1, + y = dim.y - 5; + OutputString(COLOR_LIGHTRED, x, y, Screen::getKeyDisplay(df::interface_key::CUSTOM_S)); + OutputString(COLOR_WHITE, x, y, ": Enabled: "); + std::list parts; + FOR_ITER_TOOLS(iter) + { + EmbarkTool* tool = *iter; + if (tool->getEnabled()) + { + parts.push_back(tool->getName()); + parts.push_back(", "); + } + } + if (parts.size()) + { + parts.pop_back(); // Remove trailing comma + for (auto iter = parts.begin(); iter != parts.end(); iter++) + { + OutputString(COLOR_LIGHTMAGENTA, x, y, *iter); + } + } + else + { + OutputString(COLOR_LIGHTMAGENTA, x, y, "(none)"); + } + } + + void display_settings() { - sand_dirty = true; + Screen::show(new embark_tools_settings); } -} -/* - * Plugin management - */ + inline bool is_valid_page() + { + return (page >= 0 && page <= 4); + } + + DEFINE_VMETHOD_INTERPOSE(void, feed, (std::set *input)) + { + bool cancel = false; + FOR_ITER_TOOLS(iter) + { + EmbarkTool* tool = *iter; + if (tool->getEnabled()) + tool->before_feed(this, input, cancel); + } + if (cancel) + return; + INTERPOSE_NEXT(feed)(input); + if (input->count(df::interface_key::CUSTOM_S) && is_valid_page()) + display_settings(); + FOR_ITER_TOOLS(iter) + { + EmbarkTool* tool = *iter; + if (tool->getEnabled()) + tool->after_feed(this, input); + } + } + DEFINE_VMETHOD_INTERPOSE(void, render, ()) + { + FOR_ITER_TOOLS(iter) + { + EmbarkTool* tool = *iter; + if (tool->getEnabled()) + tool->before_render(this); + } + INTERPOSE_NEXT(render)(); + display_tool_status(); + FOR_ITER_TOOLS(iter) + { + EmbarkTool* tool = *iter; + if (tool->getEnabled()) + tool->after_render(this); + } + } +}; +IMPLEMENT_VMETHOD_INTERPOSE(choose_start_site_hook, feed); +IMPLEMENT_VMETHOD_INTERPOSE(choose_start_site_hook, render); DFHACK_PLUGIN("embark-tools"); DFHACK_PLUGIN_IS_ENABLED(is_enabled); +command_result embark_tools_cmd (color_ostream &out, std::vector & parameters); + DFhackCExport command_result plugin_init (color_ostream &out, std::vector &commands) { + tools.push_back(new EmbarkAnywhere); + tools.push_back(new NanoEmbark); + tools.push_back(new SandIndicator); + tools.push_back(new StablePosition); std::string help = ""; help += "embark-tools (enable/disable) tool [tool...]\n" "Tools:\n"; - for (int i = 0; i < NUM_TOOLS; i++) + FOR_ITER_TOOLS(iter) { - help += (" " + embark_tools[i].id + ": " + embark_tools[i].desc + "\n"); + help += (" " + (*iter)->getId() + ": " + (*iter)->getDesc() + "\n"); } commands.push_back(PluginCommand( "embark-tools", @@ -504,10 +579,11 @@ command_result embark_tools_cmd (color_ostream &out, std::vector & if (is_enabled) { out << "Tool status:" << std::endl; - for (int i = 0; i < NUM_TOOLS; i++) + FOR_ITER_TOOLS(iter) { - EmbarkTool t = embark_tools[i]; - out << t.name << " (" << t.id << "): " << (t.enabled ? "Enabled" : "Disabled") << std::endl; + EmbarkTool* t = *iter; + out << t->getName() << " (" << t->getId() << "): " + << (t->getEnabled() ? "Enabled" : "Disabled") << std::endl; } } else