Petr Mrázek 2012-03-10 15:51:45 +01:00
commit 003a0f9eb8
69 changed files with 1797 additions and 1492 deletions

@ -30,7 +30,7 @@ set(DF_VERSION_MINOR "34")
set(DF_VERSION_PATCH "05") set(DF_VERSION_PATCH "05")
set(DF_VERSION "${DF_VERSION_MAJOR}.${DF_VERSION_MINOR}.${DF_VERSION_PATCH}") set(DF_VERSION "${DF_VERSION_MAJOR}.${DF_VERSION_MINOR}.${DF_VERSION_PATCH}")
set(DFHACK_RELEASE "1") set(DFHACK_RELEASE "1d")
set(DFHACK_VERSION "${DF_VERSION_MAJOR}.${DF_VERSION_MINOR}.${DF_VERSION_PATCH}-r${DFHACK_RELEASE}") set(DFHACK_VERSION "${DF_VERSION_MAJOR}.${DF_VERSION_MINOR}.${DF_VERSION_PATCH}-r${DFHACK_RELEASE}")
add_definitions(-DDFHACK_VERSION="${DFHACK_VERSION}") add_definitions(-DDFHACK_VERSION="${DFHACK_VERSION}")

@ -29,6 +29,7 @@ include/Internal.h
include/DFHack.h include/DFHack.h
include/Console.h include/Console.h
include/Core.h include/Core.h
include/ColorText.h
include/DataDefs.h include/DataDefs.h
include/Error.h include/Error.h
include/Export.h include/Export.h
@ -66,6 +67,7 @@ include/modules/Graphic.h
SET(PROJECT_SRCS SET(PROJECT_SRCS
Core.cpp Core.cpp
ColorText.cpp
DataDefs.cpp DataDefs.cpp
DataStatics.cpp DataStatics.cpp
DataStaticsCtor.cpp DataStaticsCtor.cpp

@ -0,0 +1,190 @@
/*
https://github.com/peterix/dfhack
Copyright (c) 2011 Petr Mrázek <peterix@gmail.com>
A thread-safe logging console with a line editor for windows.
Based on linenoise win32 port,
copyright 2010, Jon Griffiths <jon_p_griffiths at yahoo dot com>.
All rights reserved.
Based on linenoise, copyright 2010, Salvatore Sanfilippo <antirez at gmail dot com>.
The original linenoise can be found at: http://github.com/antirez/linenoise
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Redis nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdarg.h>
#include <errno.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <istream>
#include <string>
#include "ColorText.h"
#include "MiscUtils.h"
#include <cstdio>
#include <cstdlib>
#include <sstream>
using namespace DFHack;
#include "tinythread.h"
using namespace tthread;
void color_ostream::flush_buffer(bool flush)
{
auto buffer = buf();
auto str = buffer->str();
if (!str.empty()) {
add_text(cur_color, buffer->str());
buffer->str(std::string());
}
if (flush)
flush_proxy();
}
void color_ostream::begin_batch()
{
flush_buffer(false);
}
void color_ostream::end_batch()
{
flush_proxy();
}
color_ostream::color_ostream() : ostream(new buffer(this)), cur_color(COLOR_RESET)
{
//
}
color_ostream::~color_ostream()
{
delete buf();
}
void color_ostream::print(const char *format, ...)
{
va_list args;
va_start(args, format);
vprint(format, args);
va_end(args);
}
void color_ostream::vprint(const char *format, va_list args)
{
std::string str = stl_vsprintf(format, args);
if (!str.empty()) {
flush_buffer(false);
add_text(cur_color, str);
if (str[str.size()-1] == '\n')
flush_proxy();
}
}
void color_ostream::printerr(const char * format, ...)
{
va_list args;
va_start(args, format);
vprinterr(format, args);
va_end(args);
}
void color_ostream::vprinterr(const char *format, va_list args)
{
color_value save = cur_color;
fprintf(stderr, format, args);
color(COLOR_LIGHTRED);
vprint(format, args);
color(save);
}
void color_ostream::color(color_value c)
{
if (c == cur_color)
return;
flush_buffer(false);
cur_color = c;
}
void color_ostream::reset_color(void)
{
color(COLOR_RESET);
}
void buffered_color_ostream::add_text(color_value color, const std::string &text)
{
if (text.empty())
return;
if (buffer.empty())
{
buffer.push_back(fragment_type(color, text));
}
else
{
auto &back = buffer.back();
if (back.first != color || std::max(back.second.size(), text.size()) > 128)
buffer.push_back(fragment_type(color, text));
else
buffer.back().second += text;
}
}
void color_ostream_proxy::flush_proxy()
{
if (!buffer.empty())
{
target->begin_batch();
for (auto it = buffer.begin(); it != buffer.end(); ++it)
target->add_text(it->first, it->second);
buffer.clear();
target->end_batch();
}
}
color_ostream_proxy::color_ostream_proxy(color_ostream &target)
: target(&target)
{
//
}
color_ostream_proxy::~color_ostream_proxy()
{
*this << std::flush;
}

@ -126,13 +126,14 @@ const char * getANSIColor(const int c)
namespace DFHack namespace DFHack
{ {
class Private : public std::stringbuf class Private
{ {
public: public:
Private() Private()
{ {
dfout_C = NULL; dfout_C = NULL;
rawmode = false; rawmode = false;
in_batch = false;
supported_terminal = false; supported_terminal = false;
state = con_unclaimed; state = con_unclaimed;
}; };
@ -164,68 +165,71 @@ namespace DFHack
return true; return true;
} }
} }
protected:
int sync()
{
print(str().c_str());
str(std::string()); // Clear the string buffer
return 0;
}
public: public:
/// Print a formatted string, like printf void print(const char *data)
int print(const char * format, ...)
{ {
va_list args; fputs(data, dfout_C);
va_start( args, format );
int ret = vprint( format, args );
va_end( args );
return ret;
} }
int vprint(const char * format, va_list vl)
void print_text(color_ostream::color_value clr, const std::string &chunk)
{ {
if(state == con_lineedit) if(!in_batch && state == con_lineedit)
{ {
disable_raw(); disable_raw();
fprintf(dfout_C,"\x1b[1G"); fprintf(dfout_C,"\x1b[1G");
fprintf(dfout_C,"\x1b[0K"); fprintf(dfout_C,"\x1b[0K");
int ret = vfprintf( dfout_C, format, vl );
color(clr);
print(chunk.c_str());
reset_color();
enable_raw(); enable_raw();
prompt_refresh(); prompt_refresh();
return ret;
} }
else return vfprintf( dfout_C, format, vl ); else
{
color(clr);
print(chunk.c_str());
}
} }
int vprinterr(const char * format, va_list vl)
void begin_batch()
{ {
if(state == con_lineedit) assert(!in_batch);
in_batch = true;
if (state == con_lineedit)
{ {
disable_raw(); disable_raw();
color(Console::COLOR_LIGHTRED);
fprintf(dfout_C,"\x1b[1G"); fprintf(dfout_C,"\x1b[1G");
fprintf(dfout_C,"\x1b[0K"); fprintf(dfout_C,"\x1b[0K");
int ret = vfprintf( dfout_C, format, vl );
reset_color();
enable_raw();
prompt_refresh();
return ret;
} }
else }
void end_batch()
{
assert(in_batch);
flush();
in_batch = false;
if (state == con_lineedit)
{ {
color(Console::COLOR_LIGHTRED);
int ret = vfprintf( dfout_C, format, vl );
reset_color(); reset_color();
return ret; enable_raw();
prompt_refresh();
} }
} }
/// Print a formatted string, like printf, in red
int printerr(const char * format, ...) void flush()
{ {
va_list args; if (!rawmode)
va_start( args, format ); fflush(dfout_C);
int ret = vprinterr( format, args );
va_end( args );
return ret;
} }
/// Clear the console, along with its scrollback /// Clear the console, along with its scrollback
void clear() void clear()
{ {
@ -243,7 +247,9 @@ namespace DFHack
/// Position cursor at x,y. 1,1 = top left corner /// Position cursor at x,y. 1,1 = top left corner
void gotoxy(int x, int y) void gotoxy(int x, int y)
{ {
print("\033[%d;%dH", y,x); char tmp[64];
sprintf(tmp,"\033[%d;%dH", y,x);
print(tmp);
} }
/// Set color (ANSI color number) /// Set color (ANSI color number)
void color(Console::color_value index) void color(Console::color_value index)
@ -291,18 +297,19 @@ namespace DFHack
/// beep. maybe? /// beep. maybe?
//void beep (void); //void beep (void);
/// A simple line edit (raw mode) /// A simple line edit (raw mode)
int lineedit(const std::string& prompt, std::string& output, mutex * lock, CommandHistory & ch) int lineedit(const std::string& prompt, std::string& output, recursive_mutex * lock, CommandHistory & ch)
{ {
output.clear(); output.clear();
reset_color();
this->prompt = prompt; this->prompt = prompt;
if (!supported_terminal) if (!supported_terminal)
{ {
print(prompt.c_str()); print(prompt.c_str());
fflush(dfout_C); fflush(dfout_C);
// FIXME: what do we do here??? // FIXME: what do we do here???
//SDL_mutexV(lock); //SDL_recursive_mutexV(lock);
std::getline(std::cin, output); std::getline(std::cin, output);
//SDL_mutexP(lock); //SDL_recursive_mutexP(lock);
return output.size(); return output.size();
} }
else else
@ -396,7 +403,7 @@ namespace DFHack
if (::write(STDIN_FILENO,seq,strlen(seq)) == -1) return; if (::write(STDIN_FILENO,seq,strlen(seq)) == -1) return;
} }
int prompt_loop(mutex * lock, CommandHistory & history) int prompt_loop(recursive_mutex * lock, CommandHistory & history)
{ {
int fd = STDIN_FILENO; int fd = STDIN_FILENO;
size_t plen = prompt.size(); size_t plen = prompt.size();
@ -606,6 +613,7 @@ namespace DFHack
con_unclaimed, con_unclaimed,
con_lineedit con_lineedit
} state; } state;
bool in_batch;
std::string prompt; // current prompt string std::string prompt; // current prompt string
std::string raw_buffer; // current raw mode buffer std::string raw_buffer; // current raw mode buffer
int raw_cursor; // cursor position in the buffer int raw_cursor; // cursor position in the buffer
@ -615,12 +623,12 @@ namespace DFHack
}; };
} }
Console::Console():std::ostream(0), std::ios(0) Console::Console()
{ {
d = 0; d = 0;
inited = false; inited = false;
// we can't create the mutex at this time. the SDL functions aren't hooked yet. // we can't create the mutex at this time. the SDL functions aren't hooked yet.
wlock = new mutex(); wlock = new recursive_mutex();
} }
Console::~Console() Console::~Console()
{ {
@ -643,7 +651,6 @@ bool Console::init(bool sharing)
d = new Private(); d = new Private();
// make our own weird streams so our IO isn't redirected // make our own weird streams so our IO isn't redirected
d->dfout_C = fopen("/dev/tty", "w"); d->dfout_C = fopen("/dev/tty", "w");
rdbuf(d);
std::cin.tie(this); std::cin.tie(this);
clear(); clear();
d->supported_terminal = !isUnsupportedTerm() && isatty(STDIN_FILENO); d->supported_terminal = !isUnsupportedTerm() && isatty(STDIN_FILENO);
@ -660,7 +667,7 @@ bool Console::shutdown(void)
{ {
if(!d) if(!d)
return true; return true;
lock_guard <mutex> g(*wlock); lock_guard <recursive_mutex> g(*wlock);
if(d->rawmode) if(d->rawmode)
d->disable_raw(); d->disable_raw();
d->print("\n"); d->print("\n");
@ -670,46 +677,41 @@ bool Console::shutdown(void)
return true; return true;
} }
int Console::print( const char* format, ... ) void Console::begin_batch()
{ {
va_list args; //color_ostream::begin_batch();
lock_guard <mutex> g(*wlock);
int ret; wlock->lock();
if(!inited) ret = -1;
else if (inited)
{ d->begin_batch();
va_start( args, format );
ret = d->vprint(format, args);
va_end(args);
}
return ret;
} }
int Console::printerr( const char* format, ... ) void Console::end_batch()
{ {
va_list args; if (inited)
lock_guard <mutex> g(*wlock); d->end_batch();
int ret;
// also mirror in error log wlock->unlock();
if(!inited) }
{
va_start( args, format ); void Console::flush_proxy()
ret = vfprintf(stderr, format, args); {
va_end(args); lock_guard <recursive_mutex> g(*wlock);
} if (inited)
else d->flush();
{ }
va_start( args, format );
ret = d->vprinterr(format, args); void Console::add_text(color_value color, const std::string &text)
vfprintf(stderr, format, args); {
va_end(args); lock_guard <recursive_mutex> g(*wlock);
} if (inited)
return ret; d->print_text(color, text);
} }
int Console::get_columns(void) int Console::get_columns(void)
{ {
lock_guard <mutex> g(*wlock); lock_guard <recursive_mutex> g(*wlock);
int ret = -1; int ret = -1;
if(inited) if(inited)
ret = d->get_columns(); ret = d->get_columns();
@ -718,7 +720,7 @@ int Console::get_columns(void)
int Console::get_rows(void) int Console::get_rows(void)
{ {
lock_guard <mutex> g(*wlock); lock_guard <recursive_mutex> g(*wlock);
int ret = -1; int ret = -1;
if(inited) if(inited)
ret = d->get_rows(); ret = d->get_rows();
@ -727,42 +729,28 @@ int Console::get_rows(void)
void Console::clear() void Console::clear()
{ {
lock_guard <mutex> g(*wlock); lock_guard <recursive_mutex> g(*wlock);
if(inited) if(inited)
d->clear(); d->clear();
} }
void Console::gotoxy(int x, int y) void Console::gotoxy(int x, int y)
{ {
lock_guard <mutex> g(*wlock); lock_guard <recursive_mutex> g(*wlock);
if(inited) if(inited)
d->gotoxy(x,y); d->gotoxy(x,y);
} }
void Console::color(color_value index)
{
lock_guard <mutex> g(*wlock);
if(inited)
d->color(index);
}
void Console::reset_color( void )
{
lock_guard <mutex> g(*wlock);
if(inited)
d->reset_color();
}
void Console::cursor(bool enable) void Console::cursor(bool enable)
{ {
lock_guard <mutex> g(*wlock); lock_guard <recursive_mutex> g(*wlock);
if(inited) if(inited)
d->cursor(enable); d->cursor(enable);
} }
int Console::lineedit(const std::string & prompt, std::string & output, CommandHistory & ch) int Console::lineedit(const std::string & prompt, std::string & output, CommandHistory & ch)
{ {
lock_guard <mutex> g(*wlock); lock_guard <recursive_mutex> g(*wlock);
int ret = -2; int ret = -2;
if(inited) if(inited)
ret = d->lineedit(prompt,output,wlock,ch); ret = d->lineedit(prompt,output,wlock,ch);

@ -66,10 +66,10 @@ using namespace tthread;
namespace DFHack namespace DFHack
{ {
class Private : public std::stringbuf class Private
{ {
public: public:
Private() : basic_stringbuf<char>::basic_stringbuf() Private()
{ {
dfout_C = 0; dfout_C = 0;
rawmode = 0; rawmode = 0;
@ -78,69 +78,70 @@ namespace DFHack
ConsoleWindow = 0; ConsoleWindow = 0;
default_attributes = 0; default_attributes = 0;
state = con_unclaimed; state = con_unclaimed;
in_batch = false;
raw_cursor = 0; raw_cursor = 0;
}; };
virtual ~Private() virtual ~Private()
{ {
//sync(); //sync();
} }
protected:
int sync()
{
print (str().c_str());
// Clear the string buffer
str(std::string());
return 0;
}
public: public:
/// Print a formatted string, like printf void print(const char *data)
int print(const char * format, ...)
{ {
va_list args; fputs(data, dfout_C);
va_start( args, format );
int ret = vprint( format, args );
va_end( args );
return ret;
} }
int vprint(const char * format, va_list vl)
void print_text(color_ostream::color_value clr, const std::string &chunk)
{ {
if(state == con_lineedit) if(!in_batch && state == con_lineedit)
{ {
clearline(); clearline();
int ret = vfprintf( dfout_C, format, vl );
color(clr);
print(chunk.c_str());
reset_color();
prompt_refresh(); prompt_refresh();
return ret;
} }
else return vfprintf( dfout_C, format, vl ); else
{
color(clr);
print(chunk.c_str());
} }
int vprinterr(const char * format, va_list vl) }
void begin_batch()
{ {
if(state == con_lineedit) assert(!in_batch);
in_batch = true;
if (state == con_lineedit)
{ {
color(Console::COLOR_LIGHTRED);
clearline(); clearline();
int ret = vfprintf( dfout_C, format, vl );
reset_color();
prompt_refresh();
return ret;
} }
else }
void end_batch()
{
assert(in_batch);
flush();
in_batch = false;
if (state == con_lineedit)
{ {
color(Console::COLOR_LIGHTRED);
int ret = vfprintf( dfout_C, format, vl );
reset_color(); reset_color();
return ret; prompt_refresh();
} }
} }
/// Print a formatted string, like printf, in red
int printerr(const char * format, ...) void flush()
{ {
va_list args; fflush(dfout_C);
va_start( args, format );
int ret = vprinterr( format, args );
va_end( args );
return ret;
} }
int get_columns(void) int get_columns(void)
{ {
CONSOLE_SCREEN_BUFFER_INFO inf = { 0 }; CONSOLE_SCREEN_BUFFER_INFO inf = { 0 };
@ -250,7 +251,7 @@ namespace DFHack
SetConsoleCursorPosition(console_out, inf.dwCursorPosition); SetConsoleCursorPosition(console_out, inf.dwCursorPosition);
} }
int prompt_loop(mutex * lock, CommandHistory & history) int prompt_loop(recursive_mutex * lock, CommandHistory & history)
{ {
raw_buffer.clear(); // make sure the buffer is empty! raw_buffer.clear(); // make sure the buffer is empty!
size_t plen = prompt.size(); size_t plen = prompt.size();
@ -359,9 +360,10 @@ namespace DFHack
} }
} }
} }
int lineedit(const std::string & prompt, std::string & output, mutex * lock, CommandHistory & ch) int lineedit(const std::string & prompt, std::string & output, recursive_mutex * lock, CommandHistory & ch)
{ {
output.clear(); output.clear();
reset_color();
int count; int count;
state = con_lineedit; state = con_lineedit;
this->prompt = prompt; this->prompt = prompt;
@ -386,6 +388,7 @@ namespace DFHack
con_unclaimed, con_unclaimed,
con_lineedit con_lineedit
} state; } state;
bool in_batch;
std::string prompt; // current prompt string std::string prompt; // current prompt string
std::string raw_buffer; // current raw mode buffer std::string raw_buffer; // current raw mode buffer
int raw_cursor; // cursor position in the buffer int raw_cursor; // cursor position in the buffer
@ -393,7 +396,7 @@ namespace DFHack
} }
Console::Console():std::ostream(0), std::ios(0) Console::Console()
{ {
d = 0; d = 0;
wlock = 0; wlock = 0;
@ -453,7 +456,7 @@ bool Console::init(bool)
// Allocate a console! // Allocate a console!
AllocConsole(); AllocConsole();
d->ConsoleWindow = GetConsoleWindow(); d->ConsoleWindow = GetConsoleWindow();
wlock = new mutex(); wlock = new recursive_mutex();
HMENU hm = GetSystemMenu(d->ConsoleWindow,false); HMENU hm = GetSystemMenu(d->ConsoleWindow,false);
DeleteMenu(hm, SC_CLOSE, MF_BYCOMMAND); DeleteMenu(hm, SC_CLOSE, MF_BYCOMMAND);
@ -484,7 +487,6 @@ bool Console::init(bool)
std::ios::sync_with_stdio(); std::ios::sync_with_stdio();
// make our own weird streams so our IO isn't redirected // make our own weird streams so our IO isn't redirected
rdbuf(d);
std::cin.tie(this); std::cin.tie(this);
clear(); clear();
inited = true; inited = true;
@ -495,51 +497,47 @@ bool Console::init(bool)
// FIXME: looks awfully empty, doesn't it? // FIXME: looks awfully empty, doesn't it?
bool Console::shutdown(void) bool Console::shutdown(void)
{ {
lock_guard <mutex> g(*wlock); lock_guard <recursive_mutex> g(*wlock);
FreeConsole(); FreeConsole();
inited = false; inited = false;
return true; return true;
} }
int Console::print( const char* format, ... )
void Console::begin_batch()
{ {
va_list args; //color_ostream::begin_batch();
lock_guard <mutex> g(*wlock);
int ret; wlock->lock();
if(!inited) ret = -1;
else if (inited)
{ d->begin_batch();
va_start( args, format );
ret = d->vprint(format, args);
va_end(args);
}
return ret;
} }
int Console::printerr( const char* format, ... ) void Console::end_batch()
{ {
va_list args; if (inited)
lock_guard <mutex> g(*wlock); d->end_batch();
int ret;
// also mirror in error log wlock->unlock();
if(!inited) }
{
va_start( args, format ); void Console::flush_proxy()
ret = vfprintf(stderr, format, args); {
va_end(args); lock_guard <recursive_mutex> g(*wlock);
} if (inited)
else d->flush();
{ }
va_start( args, format );
ret = d->vprinterr(format, args); void Console::add_text(color_value color, const std::string &text)
vfprintf(stderr, format, args); {
va_end(args); lock_guard <recursive_mutex> g(*wlock);
} if (inited)
return ret; d->print_text(color, text);
} }
int Console::get_columns(void) int Console::get_columns(void)
{ {
lock_guard <mutex> g(*wlock); lock_guard <recursive_mutex> g(*wlock);
int ret = -1; int ret = -1;
if(inited) if(inited)
ret = d->get_columns(); ret = d->get_columns();
@ -548,7 +546,7 @@ int Console::get_columns(void)
int Console::get_rows(void) int Console::get_rows(void)
{ {
lock_guard <mutex> g(*wlock); lock_guard <recursive_mutex> g(*wlock);
int ret = -1; int ret = -1;
if(inited) if(inited)
ret = d->get_rows(); ret = d->get_rows();
@ -557,35 +555,21 @@ int Console::get_rows(void)
void Console::clear() void Console::clear()
{ {
lock_guard <mutex> g(*wlock); lock_guard <recursive_mutex> g(*wlock);
if(inited) if(inited)
d->clear(); d->clear();
} }
void Console::gotoxy(int x, int y) void Console::gotoxy(int x, int y)
{ {
lock_guard <mutex> g(*wlock); lock_guard <recursive_mutex> g(*wlock);
if(inited) if(inited)
d->gotoxy(x,y); d->gotoxy(x,y);
} }
void Console::color(color_value index)
{
lock_guard <mutex> g(*wlock);
if(inited)
d->color(index);
}
void Console::reset_color( void )
{
lock_guard <mutex> g(*wlock);
if(inited)
d->reset_color();
}
void Console::cursor(bool enable) void Console::cursor(bool enable)
{ {
lock_guard <mutex> g(*wlock); lock_guard <recursive_mutex> g(*wlock);
if(inited) if(inited)
d->cursor(enable); d->cursor(enable);
} }

@ -154,20 +154,22 @@ void fHKthread(void * iodata)
std::string stuff = core->getHotkeyCmd(); // waits on mutex! std::string stuff = core->getHotkeyCmd(); // waits on mutex!
if(!stuff.empty()) if(!stuff.empty())
{ {
color_ostream_proxy out(core->getConsole());
vector <string> args; vector <string> args;
cheap_tokenise(stuff, args); cheap_tokenise(stuff, args);
if (args.empty()) { if (args.empty()) {
core->con.printerr("Empty hotkey command.\n"); out.printerr("Empty hotkey command.\n");
continue; continue;
} }
string first = args[0]; string first = args[0];
args.erase(args.begin()); args.erase(args.begin());
command_result cr = plug_mgr->InvokeCommand(first, args, false); command_result cr = plug_mgr->InvokeCommand(out, first, args, false);
if(cr == CR_WOULD_BREAK) if(cr == CR_WOULD_BREAK)
{ {
core->con.printerr("It isn't possible to run an interactive command outside the console.\n"); out.printerr("It isn't possible to run an interactive command outside the console.\n");
} }
} }
} }
@ -190,7 +192,7 @@ struct sortable
static void runInteractiveCommand(Core *core, PluginManager *plug_mgr, int &clueless_counter, const string &command) static void runInteractiveCommand(Core *core, PluginManager *plug_mgr, int &clueless_counter, const string &command)
{ {
Console & con = core->con; Console & con = core->getConsole();
if (!command.empty()) if (!command.empty())
{ {
@ -469,7 +471,7 @@ static void runInteractiveCommand(Core *core, PluginManager *plug_mgr, int &clue
} }
else else
{ {
command_result res = plug_mgr->InvokeCommand(first, parts); command_result res = plug_mgr->InvokeCommand(con, first, parts);
if(res == CR_NOT_IMPLEMENTED) if(res == CR_NOT_IMPLEMENTED)
{ {
con.printerr("%s is not a recognized command.\n", first.c_str()); con.printerr("%s is not a recognized command.\n", first.c_str());
@ -504,7 +506,7 @@ void fIOthread(void * iodata)
CommandHistory main_history; CommandHistory main_history;
main_history.load("dfhack.history"); main_history.load("dfhack.history");
Console & con = core->con; Console & con = core->getConsole();
if(plug_mgr == 0 || core == 0) if(plug_mgr == 0 || core == 0)
{ {
con.printerr("Something horrible happened in Core's constructor...\n"); con.printerr("Something horrible happened in Core's constructor...\n");
@ -711,6 +713,16 @@ std::string Core::getHotkeyCmd( void )
return returner; return returner;
} }
void Core::printerr(const char *format, ...)
{
color_ostream_proxy proxy(getInstance().con);
va_list args;
va_start(args,format);
proxy.vprinterr(format,args);
va_end(args);
}
void Core::RegisterData( void *p, std::string key ) void Core::RegisterData( void *p, std::string key )
{ {
misc_data_mutex->lock(); misc_data_mutex->lock();
@ -772,6 +784,8 @@ int Core::Update()
if(errorstate) if(errorstate)
return -1; return -1;
color_ostream_proxy out(con);
// detect if the game was loaded or unloaded in the meantime // detect if the game was loaded or unloaded in the meantime
void *new_wdata = NULL; void *new_wdata = NULL;
if (df::global::world) { if (df::global::world) {
@ -783,7 +797,7 @@ int Core::Update()
if (new_wdata != last_world_data_ptr) { if (new_wdata != last_world_data_ptr) {
last_world_data_ptr = new_wdata; last_world_data_ptr = new_wdata;
plug_mgr->OnStateChange(new_wdata ? SC_GAME_LOADED : SC_GAME_UNLOADED); plug_mgr->OnStateChange(out, new_wdata ? SC_GAME_LOADED : SC_GAME_UNLOADED);
} }
// detect if the viewscreen changed // detect if the viewscreen changed
@ -795,12 +809,14 @@ int Core::Update()
if (screen != top_viewscreen) if (screen != top_viewscreen)
{ {
top_viewscreen = screen; top_viewscreen = screen;
plug_mgr->OnStateChange(SC_VIEWSCREEN_CHANGED); plug_mgr->OnStateChange(out, SC_VIEWSCREEN_CHANGED);
} }
} }
// notify all the plugins that a game tick is finished // notify all the plugins that a game tick is finished
plug_mgr->OnUpdate(); plug_mgr->OnUpdate(out);
out << std::flush;
// wake waiting tools // wake waiting tools
// do not allow more tools to join in while we process stuff here // do not allow more tools to join in while we process stuff here

@ -140,7 +140,6 @@ Plugin::Plugin(Core * core, const std::string & filepath, const std::string & _f
break; break;
name.append(1,ch); name.append(1,ch);
} }
Console & con = core->con;
plugin_lib = 0; plugin_lib = 0;
plugin_init = 0; plugin_init = 0;
plugin_shutdown = 0; plugin_shutdown = 0;
@ -172,7 +171,7 @@ bool Plugin::load()
return true; return true;
} }
Core & c = Core::getInstance(); Core & c = Core::getInstance();
Console & con = c.con; Console & con = c.getConsole();
DFLibrary * plug = OpenPlugin(filename.c_str()); DFLibrary * plug = OpenPlugin(filename.c_str());
if(!plug) if(!plug)
{ {
@ -197,7 +196,7 @@ bool Plugin::load()
state = PS_BROKEN; state = PS_BROKEN;
return false; return false;
} }
plugin_init = (command_result (*)(Core *, std::vector <PluginCommand> &)) LookupPlugin(plug, "plugin_init"); plugin_init = (command_result (*)(color_ostream &, std::vector <PluginCommand> &)) LookupPlugin(plug, "plugin_init");
if(!plugin_init) if(!plugin_init)
{ {
con.printerr("Plugin %s has no init function.\n", filename.c_str()); con.printerr("Plugin %s has no init function.\n", filename.c_str());
@ -205,13 +204,13 @@ bool Plugin::load()
state = PS_BROKEN; state = PS_BROKEN;
return false; return false;
} }
plugin_status = (command_result (*)(Core *, std::string &)) LookupPlugin(plug, "plugin_status"); plugin_status = (command_result (*)(color_ostream &, std::string &)) LookupPlugin(plug, "plugin_status");
plugin_onupdate = (command_result (*)(Core *)) LookupPlugin(plug, "plugin_onupdate"); plugin_onupdate = (command_result (*)(color_ostream &)) LookupPlugin(plug, "plugin_onupdate");
plugin_shutdown = (command_result (*)(Core *)) LookupPlugin(plug, "plugin_shutdown"); plugin_shutdown = (command_result (*)(color_ostream &)) LookupPlugin(plug, "plugin_shutdown");
plugin_onstatechange = (command_result (*)(Core *, state_change_event)) LookupPlugin(plug, "plugin_onstatechange"); plugin_onstatechange = (command_result (*)(color_ostream &, state_change_event)) LookupPlugin(plug, "plugin_onstatechange");
this->name = *plug_name; this->name = *plug_name;
plugin_lib = plug; plugin_lib = plug;
if(plugin_init(&c,commands) == CR_OK) if(plugin_init(con,commands) == CR_OK)
{ {
state = PS_LOADED; state = PS_LOADED;
parent->registerCommands(this); parent->registerCommands(this);
@ -229,14 +228,14 @@ bool Plugin::load()
bool Plugin::unload() bool Plugin::unload()
{ {
Core & c = Core::getInstance(); Core & c = Core::getInstance();
Console & con = c.con; Console & con = c.getConsole();
// get the mutex // get the mutex
access->lock(); access->lock();
// if we are actually loaded // if we are actually loaded
if(state == PS_LOADED) if(state == PS_LOADED)
{ {
// notify plugin about shutdown // notify plugin about shutdown
command_result cr = plugin_shutdown(&Core::getInstance()); command_result cr = plugin_shutdown(con);
// wait for all calls to finish // wait for all calls to finish
access->wait(); access->wait();
// cleanup... // cleanup...
@ -276,7 +275,7 @@ bool Plugin::reload()
return true; return true;
} }
command_result Plugin::invoke( std::string & command, std::vector <std::string> & parameters, bool interactive_) command_result Plugin::invoke(color_ostream &out, std::string & command, std::vector <std::string> & parameters, bool interactive_)
{ {
Core & c = Core::getInstance(); Core & c = Core::getInstance();
command_result cr = CR_NOT_IMPLEMENTED; command_result cr = CR_NOT_IMPLEMENTED;
@ -289,7 +288,7 @@ command_result Plugin::invoke( std::string & command, std::vector <std::string>
if(cmd.name == command) if(cmd.name == command)
{ {
// running interactive things from some other source than the console would break it // running interactive things from some other source than the console would break it
if(!interactive_ && cmd.interactive) if(!(interactive_ && out.is_console()) && cmd.interactive)
cr = CR_WOULD_BREAK; cr = CR_WOULD_BREAK;
else if (cmd.guard) else if (cmd.guard)
{ {
@ -300,22 +299,22 @@ command_result Plugin::invoke( std::string & command, std::vector <std::string>
CoreSuspender suspend(&c); CoreSuspender suspend(&c);
df::viewscreen *top = c.getTopViewscreen(); df::viewscreen *top = c.getTopViewscreen();
if (!cmd.guard(&c, top)) if (!cmd.guard(top))
{ {
c.con.printerr("Could not invoke %s: unsuitable UI state.\n", command.c_str()); out.printerr("Could not invoke %s: unsuitable UI state.\n", command.c_str());
cr = CR_WRONG_USAGE; cr = CR_WRONG_USAGE;
} }
else else
{ {
cr = cmd.function(&c, parameters); cr = cmd.function(out, parameters);
} }
} }
else else
{ {
cr = cmd.function(&c, parameters); cr = cmd.function(out, parameters);
} }
if (cr == CR_WRONG_USAGE && !cmd.usage.empty()) if (cr == CR_WRONG_USAGE && !cmd.usage.empty())
c.con << "Usage:\n" << cmd.usage << flush; out << "Usage:\n" << cmd.usage << flush;
break; break;
} }
} }
@ -339,9 +338,9 @@ bool Plugin::can_invoke_hotkey( std::string & command, df::viewscreen *top )
if (cmd.interactive) if (cmd.interactive)
cr = false; cr = false;
else if (cmd.guard) else if (cmd.guard)
cr = cmd.guard(&c, top); cr = cmd.guard(top);
else else
cr = Gui::default_hotkey(&c, top); cr = Gui::default_hotkey(top);
break; break;
} }
} }
@ -350,27 +349,25 @@ bool Plugin::can_invoke_hotkey( std::string & command, df::viewscreen *top )
return cr; return cr;
} }
command_result Plugin::on_update() command_result Plugin::on_update(color_ostream &out)
{ {
Core & c = Core::getInstance();
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)
{ {
cr = plugin_onupdate(&c); cr = plugin_onupdate(out);
} }
access->lock_sub(); access->lock_sub();
return cr; return cr;
} }
command_result Plugin::on_state_change(state_change_event event) command_result Plugin::on_state_change(color_ostream &out, state_change_event event)
{ {
Core & c = Core::getInstance();
command_result cr = CR_NOT_IMPLEMENTED; command_result cr = CR_NOT_IMPLEMENTED;
access->lock_add(); access->lock_add();
if(state == PS_LOADED && plugin_onstatechange) if(state == PS_LOADED && plugin_onstatechange)
{ {
cr = plugin_onstatechange(&c, event); cr = plugin_onstatechange(out, event);
} }
access->lock_sub(); access->lock_sub();
return cr; return cr;
@ -436,10 +433,10 @@ Plugin *PluginManager::getPluginByCommand(const std::string &command)
} }
// FIXME: handle name collisions... // FIXME: handle name collisions...
command_result PluginManager::InvokeCommand( std::string & command, std::vector <std::string> & parameters, bool interactive) command_result PluginManager::InvokeCommand(color_ostream &out, std::string & command, std::vector <std::string> & parameters, bool interactive)
{ {
Plugin *plugin = getPluginByCommand(command); Plugin *plugin = getPluginByCommand(command);
return plugin ? plugin->invoke(command, parameters, interactive) : CR_NOT_IMPLEMENTED; return plugin ? plugin->invoke(out, command, parameters, interactive) : CR_NOT_IMPLEMENTED;
} }
bool PluginManager::CanInvokeHotkey(std::string &command, df::viewscreen *top) bool PluginManager::CanInvokeHotkey(std::string &command, df::viewscreen *top)
@ -448,19 +445,19 @@ bool PluginManager::CanInvokeHotkey(std::string &command, df::viewscreen *top)
return plugin ? plugin->can_invoke_hotkey(command, top) : false; return plugin ? plugin->can_invoke_hotkey(command, top) : false;
} }
void PluginManager::OnUpdate( void ) void PluginManager::OnUpdate(color_ostream &out)
{ {
for(size_t i = 0; i < all_plugins.size(); i++) for(size_t i = 0; i < all_plugins.size(); i++)
{ {
all_plugins[i]->on_update(); all_plugins[i]->on_update(out);
} }
} }
void PluginManager::OnStateChange( state_change_event event ) void PluginManager::OnStateChange(color_ostream &out, state_change_event event)
{ {
for(size_t i = 0; i < all_plugins.size(); i++) for(size_t i = 0; i < all_plugins.size(); i++)
{ {
all_plugins[i]->on_state_change(event); all_plugins[i]->on_state_change(out, event);
} }
} }

@ -0,0 +1,144 @@
/*
https://github.com/peterix/dfhack
Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#pragma once
#include "Pragma.h"
#include "Export.h"
#include <list>
#include <fstream>
#include <assert.h>
#include <iostream>
#include <string>
#include <stdarg.h>
#include <sstream>
namespace DFHack
{
class DFHACK_EXPORT color_ostream : public std::ostream
{
public:
enum color_value
{
COLOR_RESET = -1,
COLOR_BLACK = 0,
COLOR_BLUE,
COLOR_GREEN,
COLOR_CYAN,
COLOR_RED,
COLOR_MAGENTA,
COLOR_BROWN,
COLOR_GREY,
COLOR_DARKGREY,
COLOR_LIGHTBLUE,
COLOR_LIGHTGREEN,
COLOR_LIGHTCYAN,
COLOR_LIGHTRED,
COLOR_LIGHTMAGENTA,
COLOR_YELLOW,
COLOR_WHITE,
COLOR_MAX = COLOR_WHITE
};
private:
color_value cur_color;
class buffer : public std::stringbuf
{
public:
color_ostream *owner;
buffer(color_ostream *owner) : owner(owner) {}
virtual ~buffer() { }
protected:
virtual int sync() {
owner->flush_buffer(true);
}
};
buffer *buf() { return (buffer*)rdbuf(); }
void flush_buffer(bool flush);
protected:
// These must be strictly balanced, because
// they might grab and hold mutexes.
virtual void begin_batch();
virtual void end_batch();
virtual void add_text(color_value color, const std::string &text) = 0;
virtual void flush_proxy() {};
friend class color_ostream_proxy;
public:
color_ostream();
virtual ~color_ostream();
/// Print a formatted string, like printf
void print(const char *format, ...);
void vprint(const char *format, va_list args);
/// Print a formatted string, like printf, in red
void printerr(const char *format, ...);
void vprinterr(const char *format, va_list args);
/// Set color (ANSI color number)
void color(color_value c);
/// Reset color to default
void reset_color(void);
virtual bool is_console() { return false; }
};
class DFHACK_EXPORT buffered_color_ostream : public color_ostream
{
protected:
virtual void add_text(color_value color, const std::string &text);
public:
typedef std::pair<color_value,std::string> fragment_type;
buffered_color_ostream() {}
~buffered_color_ostream() {}
const std::list<fragment_type> &fragments() { return buffer; }
protected:
std::list<fragment_type> buffer;
};
class DFHACK_EXPORT color_ostream_proxy : public buffered_color_ostream
{
protected:
color_ostream *target;
virtual void flush_proxy();
public:
color_ostream_proxy(color_ostream &target);
~color_ostream_proxy();
};
}

@ -25,6 +25,7 @@ distribution.
#pragma once #pragma once
#include "Pragma.h" #include "Pragma.h"
#include "Export.h" #include "Export.h"
#include "ColorText.h"
#include <deque> #include <deque>
#include <fstream> #include <fstream>
#include <assert.h> #include <assert.h>
@ -33,6 +34,7 @@ distribution.
namespace tthread namespace tthread
{ {
class mutex; class mutex;
class recursive_mutex;
class condition_variable; class condition_variable;
class thread; class thread;
} }
@ -106,31 +108,18 @@ namespace DFHack
std::size_t capacity; std::size_t capacity;
std::deque <std::string> history; std::deque <std::string> history;
}; };
class Private; class Private;
class DFHACK_EXPORT Console : public std::ostream class DFHACK_EXPORT Console : public color_ostream
{ {
protected:
virtual void begin_batch();
virtual void add_text(color_value color, const std::string &text);
virtual void end_batch();
virtual void flush_proxy();
public: public:
enum color_value
{
COLOR_RESET = -1,
COLOR_BLACK = 0,
COLOR_BLUE,
COLOR_GREEN,
COLOR_CYAN,
COLOR_RED,
COLOR_MAGENTA,
COLOR_BROWN,
COLOR_GREY,
COLOR_DARKGREY,
COLOR_LIGHTBLUE,
COLOR_LIGHTGREEN,
COLOR_LIGHTCYAN,
COLOR_LIGHTRED,
COLOR_LIGHTMAGENTA,
COLOR_YELLOW,
COLOR_WHITE,
COLOR_MAX = COLOR_WHITE
};
///ctor, NOT thread-safe ///ctor, NOT thread-safe
Console(); Console();
///dtor, NOT thread-safe ///dtor, NOT thread-safe
@ -140,18 +129,10 @@ namespace DFHack
/// shutdown the console. NOT thread-safe /// shutdown the console. NOT thread-safe
bool shutdown( void ); bool shutdown( void );
/// Print a formatted string, like printf
int print(const char * format, ...);
/// Print a formatted string, like printf, in red
int printerr(const char * format, ...);
/// Clear the console, along with its scrollback /// Clear the console, along with its scrollback
void clear(); void clear();
/// Position cursor at x,y. 1,1 = top left corner /// Position cursor at x,y. 1,1 = top left corner
void gotoxy(int x, int y); void gotoxy(int x, int y);
/// Set color (ANSI color number)
void color(color_value c);
/// Reset color to default
void reset_color(void);
/// Enable or disable the caret/cursor /// Enable or disable the caret/cursor
void cursor(bool enable = true); void cursor(bool enable = true);
/// Waits given number of milliseconds before continuing. /// Waits given number of milliseconds before continuing.
@ -165,9 +146,11 @@ namespace DFHack
/// A simple line edit (raw mode) /// A simple line edit (raw mode)
int lineedit(const std::string& prompt, std::string& output, CommandHistory & history ); int lineedit(const std::string& prompt, std::string& output, CommandHistory & history );
bool isInited (void) { return inited; }; bool isInited (void) { return inited; };
bool is_console() { return true; }
private: private:
Private * d; Private * d;
tthread::mutex * wlock; tthread::recursive_mutex * wlock;
bool inited; bool inited;
}; };
} }

@ -125,13 +125,20 @@ namespace DFHack
std::vector<std::string> ListKeyBindings(std::string keyspec); std::vector<std::string> ListKeyBindings(std::string keyspec);
bool isWorldLoaded() { return (last_world_data_ptr != NULL); } bool isWorldLoaded() { return (last_world_data_ptr != NULL); }
df::viewscreen *getTopViewscreen() { return top_viewscreen; }
static df::viewscreen *getTopViewscreen() { return getInstance().top_viewscreen; }
DFHack::Console &getConsole() { return con; }
DFHack::Process * p; DFHack::Process * p;
DFHack::VersionInfo * vinfo; DFHack::VersionInfo * vinfo;
DFHack::Console con;
DFHack::Windows::df_window * screen_window; DFHack::Windows::df_window * screen_window;
static void printerr(const char *format, ...);
private: private:
DFHack::Console con;
Core(); Core();
bool Init(); bool Init();
int Update (void); int Update (void);
@ -193,6 +200,7 @@ namespace DFHack
class CoreSuspender { class CoreSuspender {
Core *core; Core *core;
public: public:
CoreSuspender() : core(&Core::getInstance()) { core->Suspend(); }
CoreSuspender(Core *core) : core(core) { core->Suspend(); } CoreSuspender(Core *core) : core(core) { core->Suspend(); }
~CoreSuspender() { core->Resume(); } ~CoreSuspender() { core->Resume(); }
}; };

@ -35,7 +35,7 @@ distribution.
using namespace std; using namespace std;
template <typename T> template <typename T>
void print_bits ( T val, DFHack::Console& out ) void print_bits ( T val, ostream& out )
{ {
stringstream strs; stringstream strs;
T n_bits = sizeof ( val ) * CHAR_BIT; T n_bits = sizeof ( val ) * CHAR_BIT;
@ -63,7 +63,7 @@ void print_bits ( T val, DFHack::Console& out )
val >>= 1; val >>= 1;
} }
strs << endl; strs << endl;
out.print(strs.str().c_str()); out << strs.str();
} }
/* /*

@ -26,6 +26,7 @@ distribution.
#include "Export.h" #include "Export.h"
#include "Hooks.h" #include "Hooks.h"
#include "ColorText.h"
#include <map> #include <map>
#include <string> #include <string>
#include <vector> #include <vector>
@ -61,8 +62,8 @@ namespace DFHack
}; };
struct DFHACK_EXPORT PluginCommand struct DFHACK_EXPORT PluginCommand
{ {
typedef command_result (*command_function)(Core *, std::vector <std::string> &); typedef command_result (*command_function)(color_ostream &out, std::vector <std::string> &);
typedef bool (*command_hotkey_guard)(Core *, df::viewscreen *); typedef bool (*command_hotkey_guard)(df::viewscreen *);
/// create a command with a name, description, function pointer to its code /// create a command with a name, description, function pointer to its code
/// and saying if it needs an interactive terminal /// and saying if it needs an interactive terminal
@ -112,13 +113,13 @@ namespace DFHack
friend class PluginManager; friend class PluginManager;
Plugin(DFHack::Core* core, const std::string& filepath, const std::string& filename, PluginManager * pm); Plugin(DFHack::Core* core, const std::string& filepath, const std::string& filename, PluginManager * pm);
~Plugin(); ~Plugin();
command_result on_update(); command_result on_update(color_ostream &out);
command_result on_state_change(state_change_event event); command_result on_state_change(color_ostream &out, state_change_event event);
public: public:
bool load(); bool load();
bool unload(); bool unload();
bool reload(); bool reload();
command_result invoke( std::string & command, std::vector <std::string> & parameters, bool interactive ); command_result invoke(color_ostream &out, std::string & command, std::vector <std::string> & parameters, bool interactive );
bool can_invoke_hotkey( std::string & command, df::viewscreen *top ); bool can_invoke_hotkey( std::string & command, df::viewscreen *top );
plugin_state getState () const; plugin_state getState () const;
const PluginCommand& operator[] (std::size_t index) const const PluginCommand& operator[] (std::size_t index) const
@ -141,11 +142,11 @@ namespace DFHack
DFLibrary * plugin_lib; DFLibrary * plugin_lib;
PluginManager * parent; PluginManager * parent;
plugin_state state; plugin_state state;
command_result (*plugin_init)(Core *, std::vector <PluginCommand> &); command_result (*plugin_init)(color_ostream &, std::vector <PluginCommand> &);
command_result (*plugin_status)(Core *, std::string &); command_result (*plugin_status)(color_ostream &, std::string &);
command_result (*plugin_shutdown)(Core *); command_result (*plugin_shutdown)(color_ostream &);
command_result (*plugin_onupdate)(Core *); command_result (*plugin_onupdate)(color_ostream &);
command_result (*plugin_onstatechange)(Core *, state_change_event); command_result (*plugin_onstatechange)(color_ostream &, state_change_event);
}; };
class DFHACK_EXPORT PluginManager class DFHACK_EXPORT PluginManager
{ {
@ -154,15 +155,15 @@ namespace DFHack
friend class Plugin; friend class Plugin;
PluginManager(Core * core); PluginManager(Core * core);
~PluginManager(); ~PluginManager();
void OnUpdate( void ); void OnUpdate(color_ostream &out);
void OnStateChange( state_change_event event ); void OnStateChange(color_ostream &out, state_change_event event);
void registerCommands( Plugin * p ); void registerCommands( Plugin * p );
void unregisterCommands( Plugin * p ); void unregisterCommands( Plugin * p );
// PUBLIC METHODS // PUBLIC METHODS
public: public:
Plugin *getPluginByName (const std::string & name); Plugin *getPluginByName (const std::string & name);
Plugin *getPluginByCommand (const std::string &command); Plugin *getPluginByCommand (const std::string &command);
command_result InvokeCommand( std::string & command, std::vector <std::string> & parameters, bool interactive = true ); command_result InvokeCommand(color_ostream &out, std::string & command, std::vector <std::string> & parameters, bool interactive = true );
bool CanInvokeHotkey(std::string &command, df::viewscreen *top); bool CanInvokeHotkey(std::string &command, df::viewscreen *top);
Plugin* operator[] (std::size_t index) Plugin* operator[] (std::size_t index)
{ {
@ -185,9 +186,9 @@ namespace DFHack
namespace Gui namespace Gui
{ {
// Predefined hotkey guards // Predefined hotkey guards
DFHACK_EXPORT bool default_hotkey(Core *, df::viewscreen *); DFHACK_EXPORT bool default_hotkey(df::viewscreen *);
DFHACK_EXPORT bool dwarfmode_hotkey(Core *, df::viewscreen *); DFHACK_EXPORT bool dwarfmode_hotkey(df::viewscreen *);
DFHACK_EXPORT bool cursor_hotkey(Core *, df::viewscreen *); DFHACK_EXPORT bool cursor_hotkey(df::viewscreen *);
} }
}; };

@ -80,7 +80,7 @@ DFHACK_EXPORT bool Read (const uint32_t index, t_building & building);
* read mapping from custom_type value to building RAW name * read mapping from custom_type value to building RAW name
* custom_type of -1 implies ordinary building * custom_type of -1 implies ordinary building
*/ */
DFHACK_EXPORT bool ReadCustomWorkshopTypes(std::map <uint32_t, std::string> & btypes); DFHACK_EXPORT bool ReadCustomWorkshopTypes(color_ostream &out, std::map <uint32_t, std::string> & btypes);
} }
} }

@ -27,6 +27,7 @@ distribution.
#include "Module.h" #include "Module.h"
#include "Virtual.h" #include "Virtual.h"
#include "BitArray.h" #include "BitArray.h"
#include "ColorText.h"
#include <string> #include <string>
#include "DataDefs.h" #include "DataDefs.h"
@ -56,37 +57,37 @@ namespace DFHack
namespace Gui namespace Gui
{ {
// Full-screen item details view // Full-screen item details view
DFHACK_EXPORT bool item_details_hotkey(Core *, df::viewscreen *top); DFHACK_EXPORT bool item_details_hotkey(df::viewscreen *top);
// 'u'nits or 'j'obs full-screen view // 'u'nits or 'j'obs full-screen view
DFHACK_EXPORT bool unitjobs_hotkey(Core *, df::viewscreen *top); DFHACK_EXPORT bool unitjobs_hotkey(df::viewscreen *top);
// A job is selected in a workshop // A job is selected in a workshop
DFHACK_EXPORT bool workshop_job_hotkey(Core *c, df::viewscreen *top); DFHACK_EXPORT bool workshop_job_hotkey(df::viewscreen *top);
// Building material selection mode // Building material selection mode
DFHACK_EXPORT bool build_selector_hotkey(Core *c, df::viewscreen *top); DFHACK_EXPORT bool build_selector_hotkey(df::viewscreen *top);
// A unit is selected in the 'v' mode // A unit is selected in the 'v' mode
DFHACK_EXPORT bool view_unit_hotkey(Core *c, df::viewscreen *top); DFHACK_EXPORT bool view_unit_hotkey(df::viewscreen *top);
// Above + the inventory page is selected. // Above + the inventory page is selected.
DFHACK_EXPORT bool unit_inventory_hotkey(Core *c, df::viewscreen *top); DFHACK_EXPORT bool unit_inventory_hotkey(df::viewscreen *top);
// In workshop_job_hotkey, returns the job // In workshop_job_hotkey, returns the job
DFHACK_EXPORT df::job *getSelectedWorkshopJob(Core *c, bool quiet = false); DFHACK_EXPORT df::job *getSelectedWorkshopJob(color_ostream &out, bool quiet = false);
// A job is selected in a workshop, or unitjobs // A job is selected in a workshop, or unitjobs
DFHACK_EXPORT bool any_job_hotkey(Core *c, df::viewscreen *top); DFHACK_EXPORT bool any_job_hotkey(df::viewscreen *top);
DFHACK_EXPORT df::job *getSelectedJob(Core *c, bool quiet = false); DFHACK_EXPORT df::job *getSelectedJob(color_ostream &out, bool quiet = false);
// A unit is selected via 'v', 'k', unitjobs, or // A unit is selected via 'v', 'k', unitjobs, or
// a full-screen item view of a cage or suchlike // a full-screen item view of a cage or suchlike
DFHACK_EXPORT bool any_unit_hotkey(Core *c, df::viewscreen *top); DFHACK_EXPORT bool any_unit_hotkey(df::viewscreen *top);
DFHACK_EXPORT df::unit *getSelectedUnit(Core *c, bool quiet = false); DFHACK_EXPORT df::unit *getSelectedUnit(color_ostream &out, bool quiet = false);
// An item is selected via 'v'->inventory, 'k', 't', or // An item is selected via 'v'->inventory, 'k', 't', or
// a full-screen item view of a container. Note that in the // a full-screen item view of a container. Note that in the
// last case, the highlighted contained item is returned, not // last case, the highlighted contained item is returned, not
// the container itself. // the container itself.
DFHACK_EXPORT bool any_item_hotkey(Core *c, df::viewscreen *top); DFHACK_EXPORT bool any_item_hotkey(df::viewscreen *top);
DFHACK_EXPORT df::item *getSelectedItem(Core *c, bool quiet = false); DFHACK_EXPORT df::item *getSelectedItem(color_ostream &out, bool quiet = false);
// Show a plain announcement, or a titan-style popup message // Show a plain announcement, or a titan-style popup message
DFHACK_EXPORT void showAnnouncement(std::string message, int color = 7, bool bright = true); DFHACK_EXPORT void showAnnouncement(std::string message, int color = 7, bool bright = true);

@ -49,7 +49,7 @@ namespace DFHack
DFHACK_EXPORT bool operator== (const df::job_item &a, const df::job_item &b); DFHACK_EXPORT bool operator== (const df::job_item &a, const df::job_item &b);
DFHACK_EXPORT bool operator== (const df::job &a, const df::job &b); DFHACK_EXPORT bool operator== (const df::job &a, const df::job &b);
DFHACK_EXPORT void printJobDetails(Core *c, df::job *job); DFHACK_EXPORT void printJobDetails(color_ostream &out, df::job *job);
DFHACK_EXPORT df::building *getJobHolder(df::job *job); DFHACK_EXPORT df::building *getJobHolder(df::job *job);

@ -58,7 +58,7 @@ const t_exclusionType limitExclusion = 4; // used to store limit as an entry in
*/ */
// print the exclusion list, with the material index also translated into its token (for organics) - for debug really // print the exclusion list, with the material index also translated into its token (for organics) - for debug really
DFHACK_EXPORT void debug_print(Core &); DFHACK_EXPORT void debug_print(color_ostream &out);
// remove this material from the exclusion list if it is in it // remove this material from the exclusion list if it is in it
DFHACK_EXPORT void allowPlantSeedCookery(t_materialIndex materialIndex); DFHACK_EXPORT void allowPlantSeedCookery(t_materialIndex materialIndex);

@ -72,20 +72,18 @@ bool Buildings::Read (const uint32_t index, t_building & building)
return true; return true;
} }
bool Buildings::ReadCustomWorkshopTypes(map <uint32_t, string> & btypes) bool Buildings::ReadCustomWorkshopTypes(color_ostream &out, map <uint32_t, string> & btypes)
{ {
Core & c = Core::getInstance();
vector <building_def *> & bld_def = world->raws.buildings.all; vector <building_def *> & bld_def = world->raws.buildings.all;
uint32_t size = bld_def.size(); uint32_t size = bld_def.size();
btypes.clear(); btypes.clear();
c.con.print("Probing vector at 0x%x for custom workshops.\n", &bld_def); out.print("Probing vector at 0x%x for custom workshops.\n", &bld_def);
for (auto iter = bld_def.begin(); iter != bld_def.end();iter++) for (auto iter = bld_def.begin(); iter != bld_def.end();iter++)
{ {
building_def * temp = *iter; building_def * temp = *iter;
btypes[temp->id] = temp->code; btypes[temp->id] = temp->code;
c.con.print("%d : %s\n",temp->id, temp->code.c_str()); out.print("%d : %s\n",temp->id, temp->code.c_str());
} }
return true; return true;
} }

@ -45,6 +45,7 @@ using namespace DFHack;
#include "df/world.h" #include "df/world.h"
#include "df/global_objects.h" #include "df/global_objects.h"
#include "df/viewscreen_dwarfmodest.h" #include "df/viewscreen_dwarfmodest.h"
#include "df/viewscreen_dungeonmodest.h"
#include "df/viewscreen_joblistst.h" #include "df/viewscreen_joblistst.h"
#include "df/viewscreen_unitlistst.h" #include "df/viewscreen_unitlistst.h"
#include "df/viewscreen_itemst.h" #include "df/viewscreen_itemst.h"
@ -69,37 +70,41 @@ using df::global::gps;
// Predefined common guard functions // Predefined common guard functions
bool Gui::default_hotkey(Core *, df::viewscreen *top) bool Gui::default_hotkey(df::viewscreen *top)
{ {
// Default hotkey guard function // Default hotkey guard function
for (;top ;top = top->parent) for (;top ;top = top->parent)
{
if (strict_virtual_cast<df::viewscreen_dwarfmodest>(top)) if (strict_virtual_cast<df::viewscreen_dwarfmodest>(top))
return true; return true;
if (strict_virtual_cast<df::viewscreen_dungeonmodest>(top))
return true;
}
return false; return false;
} }
bool Gui::dwarfmode_hotkey(Core *, df::viewscreen *top) bool Gui::dwarfmode_hotkey(df::viewscreen *top)
{ {
// Require the main dwarf mode screen // Require the main dwarf mode screen
return !!strict_virtual_cast<df::viewscreen_dwarfmodest>(top); return !!strict_virtual_cast<df::viewscreen_dwarfmodest>(top);
} }
bool Gui::unitjobs_hotkey(Core *, df::viewscreen *top) bool Gui::unitjobs_hotkey(df::viewscreen *top)
{ {
// Require the unit or jobs list // Require the unit or jobs list
return !!strict_virtual_cast<df::viewscreen_joblistst>(top) || return !!strict_virtual_cast<df::viewscreen_joblistst>(top) ||
!!strict_virtual_cast<df::viewscreen_unitlistst>(top); !!strict_virtual_cast<df::viewscreen_unitlistst>(top);
} }
bool Gui::item_details_hotkey(Core *, df::viewscreen *top) bool Gui::item_details_hotkey(df::viewscreen *top)
{ {
// Require the main dwarf mode screen // Require the main dwarf mode screen
return !!strict_virtual_cast<df::viewscreen_itemst>(top); return !!strict_virtual_cast<df::viewscreen_itemst>(top);
} }
bool Gui::cursor_hotkey(Core *c, df::viewscreen *top) bool Gui::cursor_hotkey(df::viewscreen *top)
{ {
if (!dwarfmode_hotkey(c, top)) if (!dwarfmode_hotkey(top))
return false; return false;
// Also require the cursor. // Also require the cursor.
@ -109,7 +114,7 @@ bool Gui::cursor_hotkey(Core *c, df::viewscreen *top)
return true; return true;
} }
bool Gui::workshop_job_hotkey(Core *c, df::viewscreen *top) bool Gui::workshop_job_hotkey(df::viewscreen *top)
{ {
using namespace ui_sidebar_mode; using namespace ui_sidebar_mode;
using df::global::ui; using df::global::ui;
@ -117,7 +122,7 @@ bool Gui::workshop_job_hotkey(Core *c, df::viewscreen *top)
using df::global::ui_workshop_in_add; using df::global::ui_workshop_in_add;
using df::global::ui_workshop_job_cursor; using df::global::ui_workshop_job_cursor;
if (!dwarfmode_hotkey(c,top)) if (!dwarfmode_hotkey(top))
return false; return false;
switch (ui->main.mode) { switch (ui->main.mode) {
@ -147,13 +152,13 @@ bool Gui::workshop_job_hotkey(Core *c, df::viewscreen *top)
} }
} }
bool Gui::build_selector_hotkey(Core *c, df::viewscreen *top) bool Gui::build_selector_hotkey(df::viewscreen *top)
{ {
using namespace ui_sidebar_mode; using namespace ui_sidebar_mode;
using df::global::ui; using df::global::ui;
using df::global::ui_build_selector; using df::global::ui_build_selector;
if (!dwarfmode_hotkey(c,top)) if (!dwarfmode_hotkey(top))
return false; return false;
switch (ui->main.mode) { switch (ui->main.mode) {
@ -175,13 +180,13 @@ bool Gui::build_selector_hotkey(Core *c, df::viewscreen *top)
} }
} }
bool Gui::view_unit_hotkey(Core *c, df::viewscreen *top) bool Gui::view_unit_hotkey(df::viewscreen *top)
{ {
using df::global::ui; using df::global::ui;
using df::global::world; using df::global::world;
using df::global::ui_selected_unit; using df::global::ui_selected_unit;
if (!dwarfmode_hotkey(c,top)) if (!dwarfmode_hotkey(top))
return false; return false;
if (ui->main.mode != ui_sidebar_mode::ViewUnits) if (ui->main.mode != ui_sidebar_mode::ViewUnits)
return false; return false;
@ -191,11 +196,11 @@ bool Gui::view_unit_hotkey(Core *c, df::viewscreen *top)
return vector_get(world->units.other[0], *ui_selected_unit) != NULL; return vector_get(world->units.other[0], *ui_selected_unit) != NULL;
} }
bool Gui::unit_inventory_hotkey(Core *c, df::viewscreen *top) bool Gui::unit_inventory_hotkey(df::viewscreen *top)
{ {
using df::global::ui_unit_view_mode; using df::global::ui_unit_view_mode;
if (!view_unit_hotkey(c,top)) if (!view_unit_hotkey(top))
return false; return false;
if (!ui_unit_view_mode) if (!ui_unit_view_mode)
return false; return false;
@ -203,14 +208,14 @@ bool Gui::unit_inventory_hotkey(Core *c, df::viewscreen *top)
return ui_unit_view_mode->value == df::ui_unit_view_mode::Inventory; return ui_unit_view_mode->value == df::ui_unit_view_mode::Inventory;
} }
df::job *Gui::getSelectedWorkshopJob(Core *c, bool quiet) df::job *Gui::getSelectedWorkshopJob(color_ostream &out, bool quiet)
{ {
using df::global::world; using df::global::world;
using df::global::ui_workshop_job_cursor; using df::global::ui_workshop_job_cursor;
if (!workshop_job_hotkey(c, c->getTopViewscreen())) { if (!workshop_job_hotkey(Core::getTopViewscreen())) {
if (!quiet) if (!quiet)
c->con.printerr("Not in a workshop, or no job is highlighted.\n"); out.printerr("Not in a workshop, or no job is highlighted.\n");
return NULL; return NULL;
} }
@ -219,14 +224,14 @@ df::job *Gui::getSelectedWorkshopJob(Core *c, bool quiet)
if (idx < 0 || idx >= selected->jobs.size()) if (idx < 0 || idx >= selected->jobs.size())
{ {
c->con.printerr("Invalid job cursor index: %d\n", idx); out.printerr("Invalid job cursor index: %d\n", idx);
return NULL; return NULL;
} }
return selected->jobs[idx]; return selected->jobs[idx];
} }
bool Gui::any_job_hotkey(Core *c, df::viewscreen *top) bool Gui::any_job_hotkey(df::viewscreen *top)
{ {
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_joblistst, top)) if (VIRTUAL_CAST_VAR(screen, df::viewscreen_joblistst, top))
return vector_get(screen->jobs, screen->cursor_pos) != NULL; return vector_get(screen->jobs, screen->cursor_pos) != NULL;
@ -234,19 +239,19 @@ bool Gui::any_job_hotkey(Core *c, df::viewscreen *top)
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_unitlistst, top)) if (VIRTUAL_CAST_VAR(screen, df::viewscreen_unitlistst, top))
return vector_get(screen->jobs[screen->page], screen->cursor_pos[screen->page]) != NULL; return vector_get(screen->jobs[screen->page], screen->cursor_pos[screen->page]) != NULL;
return workshop_job_hotkey(c,top); return workshop_job_hotkey(top);
} }
df::job *Gui::getSelectedJob(Core *c, bool quiet) df::job *Gui::getSelectedJob(color_ostream &out, bool quiet)
{ {
df::viewscreen *top = c->getTopViewscreen(); df::viewscreen *top = Core::getTopViewscreen();
if (VIRTUAL_CAST_VAR(joblist, df::viewscreen_joblistst, top)) if (VIRTUAL_CAST_VAR(joblist, df::viewscreen_joblistst, top))
{ {
df::job *job = vector_get(joblist->jobs, joblist->cursor_pos); df::job *job = vector_get(joblist->jobs, joblist->cursor_pos);
if (!job && !quiet) if (!job && !quiet)
c->con.printerr("Selected unit has no job\n"); out.printerr("Selected unit has no job\n");
return job; return job;
} }
@ -256,15 +261,15 @@ df::job *Gui::getSelectedJob(Core *c, bool quiet)
df::job *job = vector_get(unitlist->jobs[page], unitlist->cursor_pos[page]); df::job *job = vector_get(unitlist->jobs[page], unitlist->cursor_pos[page]);
if (!job && !quiet) if (!job && !quiet)
c->con.printerr("Selected unit has no job\n"); out.printerr("Selected unit has no job\n");
return job; return job;
} }
else else
return getSelectedWorkshopJob(c, quiet); return getSelectedWorkshopJob(out, quiet);
} }
static df::unit *getAnyUnit(Core *c, df::viewscreen *top) static df::unit *getAnyUnit(df::viewscreen *top)
{ {
using namespace ui_sidebar_mode; using namespace ui_sidebar_mode;
using df::global::ui; using df::global::ui;
@ -285,7 +290,7 @@ static df::unit *getAnyUnit(Core *c, df::viewscreen *top)
return ref ? ref->getUnit() : NULL; return ref ? ref->getUnit() : NULL;
} }
if (!Gui::dwarfmode_hotkey(c,top)) if (!Gui::dwarfmode_hotkey(top))
return NULL; return NULL;
switch (ui->main.mode) { switch (ui->main.mode) {
@ -312,22 +317,22 @@ static df::unit *getAnyUnit(Core *c, df::viewscreen *top)
} }
} }
bool Gui::any_unit_hotkey(Core *c, df::viewscreen *top) bool Gui::any_unit_hotkey(df::viewscreen *top)
{ {
return getAnyUnit(c, top) != NULL; return getAnyUnit(top) != NULL;
} }
df::unit *Gui::getSelectedUnit(Core *c, bool quiet) df::unit *Gui::getSelectedUnit(color_ostream &out, bool quiet)
{ {
df::unit *unit = getAnyUnit(c, c->getTopViewscreen()); df::unit *unit = getAnyUnit(Core::getTopViewscreen());
if (!unit && !quiet) if (!unit && !quiet)
c->con.printerr("No unit is selected in the UI.\n"); out.printerr("No unit is selected in the UI.\n");
return unit; return unit;
} }
static df::item *getAnyItem(Core *c, df::viewscreen *top) static df::item *getAnyItem(df::viewscreen *top)
{ {
using namespace ui_sidebar_mode; using namespace ui_sidebar_mode;
using df::global::ui; using df::global::ui;
@ -344,7 +349,7 @@ static df::item *getAnyItem(Core *c, df::viewscreen *top)
return ref ? ref->getItem() : NULL; return ref ? ref->getItem() : NULL;
} }
if (!Gui::dwarfmode_hotkey(c,top)) if (!Gui::dwarfmode_hotkey(top))
return NULL; return NULL;
switch (ui->main.mode) { switch (ui->main.mode) {
@ -387,17 +392,17 @@ static df::item *getAnyItem(Core *c, df::viewscreen *top)
} }
} }
bool Gui::any_item_hotkey(Core *c, df::viewscreen *top) bool Gui::any_item_hotkey(df::viewscreen *top)
{ {
return getAnyItem(c, top) != NULL; return getAnyItem(top) != NULL;
} }
df::item *Gui::getSelectedItem(Core *c, bool quiet) df::item *Gui::getSelectedItem(color_ostream &out, bool quiet)
{ {
df::item *item = getAnyItem(c, c->getTopViewscreen()); df::item *item = getAnyItem(Core::getTopViewscreen());
if (!item && !quiet) if (!item && !quiet)
c->con.printerr("No item is selected in the UI.\n"); out.printerr("No item is selected in the UI.\n");
return item; return item;
} }

@ -382,7 +382,7 @@ bool ItemTypeInfo::matches(const df::job_item &item, MaterialInfo *mat)
if ((item_ok1.whole & ~item_mask1.whole) || if ((item_ok1.whole & ~item_mask1.whole) ||
(item_ok2.whole & ~item_mask2.whole) || (item_ok2.whole & ~item_mask2.whole) ||
(item_ok3.whole & ~item_mask3.whole)) (item_ok3.whole & ~item_mask3.whole))
Core::getInstance().con.printerr("ItemTypeInfo.matches inconsistent\n"); Core::printerr("ItemTypeInfo.matches inconsistent\n");
#undef OK #undef OK
#undef RQ #undef RQ

@ -139,48 +139,48 @@ bool DFHack::operator== (const df::job &a, const df::job &b)
return true; return true;
} }
static void print_job_item_details(Core *c, df::job *job, unsigned idx, df::job_item *item) static void print_job_item_details(color_ostream &out, df::job *job, unsigned idx, df::job_item *item)
{ {
ItemTypeInfo info(item); ItemTypeInfo info(item);
c->con << " Input Item " << (idx+1) << ": " << info.toString(); out << " Input Item " << (idx+1) << ": " << info.toString();
if (item->quantity != 1) if (item->quantity != 1)
c->con << "; quantity=" << item->quantity; out << "; quantity=" << item->quantity;
if (item->min_dimension >= 0) if (item->min_dimension >= 0)
c->con << "; min_dimension=" << item->min_dimension; out << "; min_dimension=" << item->min_dimension;
c->con << endl; out << endl;
MaterialInfo mat(item); MaterialInfo mat(item);
if (mat.isValid() || item->metal_ore >= 0) { if (mat.isValid() || item->metal_ore >= 0) {
c->con << " material: " << mat.toString(); out << " material: " << mat.toString();
if (item->metal_ore >= 0) if (item->metal_ore >= 0)
c->con << "; ore of " << MaterialInfo(0,item->metal_ore).toString(); out << "; ore of " << MaterialInfo(0,item->metal_ore).toString();
c->con << endl; out << endl;
} }
if (item->flags1.whole) if (item->flags1.whole)
c->con << " flags1: " << bitfieldToString(item->flags1) << endl; out << " flags1: " << bitfieldToString(item->flags1) << endl;
if (item->flags2.whole) if (item->flags2.whole)
c->con << " flags2: " << bitfieldToString(item->flags2) << endl; out << " flags2: " << bitfieldToString(item->flags2) << endl;
if (item->flags3.whole) if (item->flags3.whole)
c->con << " flags3: " << bitfieldToString(item->flags3) << endl; out << " flags3: " << bitfieldToString(item->flags3) << endl;
if (!item->reaction_class.empty()) if (!item->reaction_class.empty())
c->con << " reaction class: " << item->reaction_class << endl; out << " reaction class: " << item->reaction_class << endl;
if (!item->has_material_reaction_product.empty()) if (!item->has_material_reaction_product.empty())
c->con << " reaction product: " << item->has_material_reaction_product << endl; out << " reaction product: " << item->has_material_reaction_product << endl;
if (item->has_tool_use >= 0) if (item->has_tool_use >= 0)
c->con << " tool use: " << ENUM_KEY_STR(tool_uses, item->has_tool_use) << endl; out << " tool use: " << ENUM_KEY_STR(tool_uses, item->has_tool_use) << endl;
} }
void DFHack::printJobDetails(Core *c, df::job *job) void DFHack::printJobDetails(color_ostream &out, df::job *job)
{ {
c->con.color(job->flags.bits.suspend ? Console::COLOR_DARKGREY : Console::COLOR_GREY); out.color(job->flags.bits.suspend ? Console::COLOR_DARKGREY : Console::COLOR_GREY);
c->con << "Job " << job->id << ": " << ENUM_KEY_STR(job_type,job->job_type); out << "Job " << job->id << ": " << ENUM_KEY_STR(job_type,job->job_type);
if (job->flags.whole) if (job->flags.whole)
c->con << " (" << bitfieldToString(job->flags) << ")"; out << " (" << bitfieldToString(job->flags) << ")";
c->con << endl; out << endl;
c->con.reset_color(); out.reset_color();
df::item_type itype = ENUM_ATTR(job_type, item, job->job_type); df::item_type itype = ENUM_ATTR(job_type, item, job->job_type);
@ -190,28 +190,28 @@ void DFHack::printJobDetails(Core *c, df::job *job)
if (mat.isValid() || job->material_category.whole) if (mat.isValid() || job->material_category.whole)
{ {
c->con << " material: " << mat.toString(); out << " material: " << mat.toString();
if (job->material_category.whole) if (job->material_category.whole)
c->con << " (" << bitfieldToString(job->material_category) << ")"; out << " (" << bitfieldToString(job->material_category) << ")";
c->con << endl; out << endl;
} }
if (job->item_subtype >= 0 || job->item_category.whole) if (job->item_subtype >= 0 || job->item_category.whole)
{ {
ItemTypeInfo iinfo(itype, job->item_subtype); ItemTypeInfo iinfo(itype, job->item_subtype);
c->con << " item: " << iinfo.toString() out << " item: " << iinfo.toString()
<< " (" << bitfieldToString(job->item_category) << ")" << endl; << " (" << bitfieldToString(job->item_category) << ")" << endl;
} }
if (job->hist_figure_id >= 0) if (job->hist_figure_id >= 0)
c->con << " figure: " << job->hist_figure_id << endl; out << " figure: " << job->hist_figure_id << endl;
if (!job->reaction_name.empty()) if (!job->reaction_name.empty())
c->con << " reaction: " << job->reaction_name << endl; out << " reaction: " << job->reaction_name << endl;
for (size_t i = 0; i < job->job_items.size(); i++) for (size_t i = 0; i < job->job_items.size(); i++)
print_job_item_details(c, job, i, job->job_items[i]); print_job_item_details(out, job, i, job->job_items[i]);
} }
df::building *DFHack::getJobHolder(df::job *job) df::building *DFHack::getJobHolder(df::job *job)

@ -28,12 +28,12 @@ using namespace df::enums;
using df::global::world; using df::global::world;
using df::global::ui; using df::global::ui;
void Kitchen::debug_print(Core &core) void Kitchen::debug_print(color_ostream &out)
{ {
core.con.print("Kitchen Exclusions\n"); out.print("Kitchen Exclusions\n");
for(std::size_t i = 0; i < size(); ++i) for(std::size_t i = 0; i < size(); ++i)
{ {
core.con.print("%2u: IT:%2i IS:%i MT:%3i MI:%2i ET:%i %s\n", out.print("%2u: IT:%2i IS:%i MT:%3i MI:%2i ET:%i %s\n",
i, i,
ui->kitchen.item_types[i], ui->kitchen.item_types[i],
ui->kitchen.item_subtypes[i], ui->kitchen.item_subtypes[i],
@ -43,7 +43,7 @@ void Kitchen::debug_print(Core &core)
(ui->kitchen.mat_types[i] >= 419 && ui->kitchen.mat_types[i] <= 618) ? world->raws.plants.all[ui->kitchen.mat_indices[i]]->id.c_str() : "n/a" (ui->kitchen.mat_types[i] >= 419 && ui->kitchen.mat_types[i] <= 618) ? world->raws.plants.all[ui->kitchen.mat_indices[i]]->id.c_str() : "n/a"
); );
} }
core.con.print("\n"); out.print("\n");
} }
void Kitchen::allowPlantSeedCookery(t_materialIndex materialIndex) void Kitchen::allowPlantSeedCookery(t_materialIndex materialIndex)

@ -46,14 +46,14 @@ using namespace DFHack::Translation;
* PLUGIN INTERFACE * * PLUGIN INTERFACE *
*********************/ *********************/
static bool bodyswap_hotkey(Core *c, df::viewscreen *top); static bool bodyswap_hotkey(df::viewscreen *top);
command_result adv_bodyswap (Core * c, std::vector <std::string> & parameters); command_result adv_bodyswap (color_ostream &out, std::vector <std::string> & parameters);
command_result adv_tools (Core * c, std::vector <std::string> & parameters); command_result adv_tools (color_ostream &out, std::vector <std::string> & parameters);
DFHACK_PLUGIN("advtools"); DFHACK_PLUGIN("advtools");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.clear(); commands.clear();
@ -91,16 +91,16 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
df::nemesis_record *getPlayerNemesis(Core *c, bool restore_swap); df::nemesis_record *getPlayerNemesis(color_ostream &out, bool restore_swap);
static bool in_transient_swap = false; static bool in_transient_swap = false;
DFhackCExport command_result plugin_onstatechange(Core* c, state_change_event event) DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event)
{ {
switch (event) { switch (event) {
case SC_GAME_LOADED: case SC_GAME_LOADED:
@ -113,12 +113,12 @@ DFhackCExport command_result plugin_onstatechange(Core* c, state_change_event ev
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_onupdate ( Core * c ) DFhackCExport command_result plugin_onupdate ( color_ostream &out )
{ {
// Revert transient swaps before trouble happens // Revert transient swaps before trouble happens
if (in_transient_swap) if (in_transient_swap)
{ {
auto screen = c->getTopViewscreen(); auto screen = Core::getTopViewscreen();
bool revert = false; bool revert = false;
if (strict_virtual_cast<df::viewscreen_dungeonmodest>(screen)) if (strict_virtual_cast<df::viewscreen_dungeonmodest>(screen))
@ -143,7 +143,7 @@ DFhackCExport command_result plugin_onupdate ( Core * c )
if (revert) if (revert)
{ {
getPlayerNemesis(c, true); getPlayerNemesis(out, true);
in_transient_swap = false; in_transient_swap = false;
} }
} }
@ -155,15 +155,15 @@ DFhackCExport command_result plugin_onupdate ( Core * c )
* UTILITY FUNCTIONS * * UTILITY FUNCTIONS *
*********************/ *********************/
static bool bodyswap_hotkey(Core *c, df::viewscreen *top) static bool bodyswap_hotkey(df::viewscreen *top)
{ {
return !!virtual_cast<df::viewscreen_dungeonmodest>(top) || return !!virtual_cast<df::viewscreen_dungeonmodest>(top) ||
!!virtual_cast<df::viewscreen_dungeon_monsterstatusst>(top); !!virtual_cast<df::viewscreen_dungeon_monsterstatusst>(top);
} }
df::unit *getCurUnit(Core *c) df::unit *getCurUnit()
{ {
auto top = c->getTopViewscreen(); auto top = Core::getTopViewscreen();
if (VIRTUAL_CAST_VAR(ms, df::viewscreen_dungeon_monsterstatusst, top)) if (VIRTUAL_CAST_VAR(ms, df::viewscreen_dungeon_monsterstatusst, top))
return ms->unit; return ms->unit;
@ -186,11 +186,11 @@ df::nemesis_record *getNemesis(df::unit *unit)
return NULL; return NULL;
} }
bool bodySwap(Core *c, df::unit *player) bool bodySwap(color_ostream &out, df::unit *player)
{ {
if (!player) if (!player)
{ {
c->con.printerr("Unit to swap is NULL\n"); out.printerr("Unit to swap is NULL\n");
return false; return false;
} }
@ -199,7 +199,7 @@ bool bodySwap(Core *c, df::unit *player)
int idx = linear_index(vec, player); int idx = linear_index(vec, player);
if (idx < 0) if (idx < 0)
{ {
c->con.printerr("Unit to swap not found: %d\n", player->id); out.printerr("Unit to swap not found: %d\n", player->id);
return false; return false;
} }
@ -209,12 +209,12 @@ bool bodySwap(Core *c, df::unit *player)
return true; return true;
} }
df::nemesis_record *getPlayerNemesis(Core *c, bool restore_swap) df::nemesis_record *getPlayerNemesis(color_ostream &out, bool restore_swap)
{ {
auto real_nemesis = vector_get(world->nemesis.all, ui_advmode->player_id); auto real_nemesis = vector_get(world->nemesis.all, ui_advmode->player_id);
if (!real_nemesis || !real_nemesis->unit) if (!real_nemesis || !real_nemesis->unit)
{ {
c->con.printerr("Invalid player nemesis id: %d\n", ui_advmode->player_id); out.printerr("Invalid player nemesis id: %d\n", ui_advmode->player_id);
return NULL; return NULL;
} }
@ -225,11 +225,11 @@ df::nemesis_record *getPlayerNemesis(Core *c, bool restore_swap)
if (ctl_nemesis != real_nemesis) if (ctl_nemesis != real_nemesis)
{ {
if (!bodySwap(c, real_nemesis->unit)) if (!bodySwap(out, real_nemesis->unit))
return NULL; return NULL;
auto name = TranslateName(&real_nemesis->unit->name, false); auto name = TranslateName(&real_nemesis->unit->name, false);
c->con.print("Returned into the body of %s.\n", name.c_str()); out.print("Returned into the body of %s.\n", name.c_str());
} }
real_nemesis->unit->relations.group_leader_id = -1; real_nemesis->unit->relations.group_leader_id = -1;
@ -318,9 +318,9 @@ void sortCompanionNemesis(std::vector<nemesis_record*> *list, int player_id = -1
list->swap(output); list->swap(output);
} }
void listCompanions(Core *c, std::vector<nemesis_record*> *list, bool units = true) void listCompanions(color_ostream &out, std::vector<nemesis_record*> *list, bool units = true)
{ {
nemesis_record *player = getPlayerNemesis(c, false); nemesis_record *player = getPlayerNemesis(out, false);
if (!player) if (!player)
return; return;
@ -485,23 +485,23 @@ void joinCounts(std::map<df::coord, int> &counts)
* FORMATTING * * FORMATTING *
*********************/ *********************/
static void printCompanionHeader(Core *c, size_t i, df::unit *unit) static void printCompanionHeader(color_ostream &out, size_t i, df::unit *unit)
{ {
c->con.color(Console::COLOR_GREY); out.color(Console::COLOR_GREY);
if (i < 28) if (i < 28)
c->con << char('a'+i); out << char('a'+i);
else else
c->con << i; out << i;
c->con << ": " << getUnitNameProfession(unit); out << ": " << getUnitNameProfession(unit);
if (unit->flags1.bits.dead) if (unit->flags1.bits.dead)
c->con << " (DEAD)"; out << " (DEAD)";
if (unit->flags3.bits.ghostly) if (unit->flags3.bits.ghostly)
c->con << " (GHOST)"; out << " (GHOST)";
c->con << endl; out << endl;
c->con.reset_color(); out.reset_color();
} }
static size_t formatSize(std::vector<std::string> *out, const std::map<std::string, int> in, size_t *cnt) static size_t formatSize(std::vector<std::string> *out, const std::map<std::string, int> in, size_t *cnt)
@ -560,7 +560,7 @@ static std::string formatDirection(df::coord delta)
return stl_sprintf("%d away %s %+d", dist, dir.c_str(), delta.z); return stl_sprintf("%d away %s %+d", dist, dir.c_str(), delta.z);
} }
static void printEquipped(Core *c, df::unit *unit, bool all) static void printEquipped(color_ostream &out, df::unit *unit, bool all)
{ {
std::vector<inv_item> items; std::vector<inv_item> items;
listUnitInventory(&items, unit); listUnitInventory(&items, unit);
@ -636,10 +636,10 @@ static void printEquipped(Core *c, df::unit *unit, bool all)
for (int j = 0; j < 4; j++) for (int j = 0; j < 4; j++)
{ {
size_t sz = std::max(sizes[j], size_t(18)); size_t sz = std::max(sizes[j], size_t(18));
c->con << "| " << std::left << std::setw(sz) << vector_get(cols[j],i) << " "; out << "| " << std::left << std::setw(sz) << vector_get(cols[j],i) << " ";
} }
c->con << "|" << std::endl; out << "|" << std::endl;
} }
} }
@ -647,7 +647,7 @@ static void printEquipped(Core *c, df::unit *unit, bool all)
* COMMANDS * * COMMANDS *
*********************/ *********************/
command_result adv_bodyswap (Core * c, std::vector <std::string> & parameters) command_result adv_bodyswap (color_ostream &out, std::vector <std::string> & parameters)
{ {
// HOTKEY COMMAND; CORE IS SUSPENDED // HOTKEY COMMAND; CORE IS SUSPENDED
bool force = false; bool force = false;
@ -669,19 +669,19 @@ command_result adv_bodyswap (Core * c, std::vector <std::string> & parameters)
} }
// Get the real player; undo previous transient swap // Get the real player; undo previous transient swap
auto real_nemesis = getPlayerNemesis(c, true); auto real_nemesis = getPlayerNemesis(out, true);
if (!real_nemesis) if (!real_nemesis)
return CR_FAILURE; return CR_FAILURE;
// Get the unit to swap to // Get the unit to swap to
auto new_unit = getCurUnit(c); auto new_unit = getCurUnit();
auto new_nemesis = getNemesis(new_unit); auto new_nemesis = getNemesis(new_unit);
if (!new_nemesis) if (!new_nemesis)
{ {
if (new_unit) if (new_unit)
{ {
c->con.printerr("Cannot swap into a non-historical unit.\n"); out.printerr("Cannot swap into a non-historical unit.\n");
return CR_FAILURE; return CR_FAILURE;
} }
@ -694,16 +694,16 @@ command_result adv_bodyswap (Core * c, std::vector <std::string> & parameters)
// Verify it's a companion // Verify it's a companion
if (!force && linear_index(real_nemesis->companions, new_nemesis->id) < 0) if (!force && linear_index(real_nemesis->companions, new_nemesis->id) < 0)
{ {
c->con.printerr("This is not your companion - use force to bodyswap.\n"); out.printerr("This is not your companion - use force to bodyswap.\n");
return CR_FAILURE; return CR_FAILURE;
} }
// Swap // Swap
if (!bodySwap(c, new_nemesis->unit)) if (!bodySwap(out, new_nemesis->unit))
return CR_FAILURE; return CR_FAILURE;
auto name = TranslateName(&new_nemesis->unit->name, false); auto name = TranslateName(&new_nemesis->unit->name, false);
c->con.print("Swapped into the body of %s.\n", name.c_str()); out.print("Swapped into the body of %s.\n", name.c_str());
// Permanently re-link everything // Permanently re-link everything
if (permanent) if (permanent)
@ -739,12 +739,12 @@ command_result adv_bodyswap (Core * c, std::vector <std::string> & parameters)
return CR_OK; return CR_OK;
} }
command_result adv_tools (Core * c, std::vector <std::string> & parameters) command_result adv_tools (color_ostream &out, std::vector <std::string> & parameters)
{ {
if (parameters.empty()) if (parameters.empty())
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
CoreSuspender suspend(c); CoreSuspender suspend;
const auto &command = parameters[0]; const auto &command = parameters[0];
if (command == "list-equipped") if (command == "list-equipped")
@ -760,7 +760,7 @@ command_result adv_tools (Core * c, std::vector <std::string> & parameters)
std::vector<nemesis_record*> list; std::vector<nemesis_record*> list;
listCompanions(c, &list); listCompanions(out, &list);
sortCompanionNemesis(&list); sortCompanionNemesis(&list);
for (size_t i = 0; i < list.size(); i++) for (size_t i = 0; i < list.size(); i++)
@ -768,8 +768,8 @@ command_result adv_tools (Core * c, std::vector <std::string> & parameters)
auto item = list[i]; auto item = list[i];
auto unit = item->unit; auto unit = item->unit;
printCompanionHeader(c, i, unit); printCompanionHeader(out, i, unit);
printEquipped(c, unit, all); printEquipped(out, unit, all);
} }
return CR_OK; return CR_OK;
@ -787,7 +787,7 @@ command_result adv_tools (Core * c, std::vector <std::string> & parameters)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
auto *player = getPlayerNemesis(c, false); auto *player = getPlayerNemesis(out, false);
if (!player) if (!player)
return CR_FAILURE; return CR_FAILURE;
@ -821,14 +821,14 @@ command_result adv_tools (Core * c, std::vector <std::string> & parameters)
joinCounts(counts); joinCounts(counts);
c->con.print("%d items of metal merchandise found in the vicinity.\n", total); out.print("%d items of metal merchandise found in the vicinity.\n", total);
for (auto it = counts.begin(); it != counts.end(); it++) for (auto it = counts.begin(); it != counts.end(); it++)
{ {
if (!it->second) if (!it->second)
continue; continue;
df::coord delta = it->first * 10; df::coord delta = it->first * 10;
c->con.print(" %s: %d\n", formatDirection(delta).c_str(), it->second); out.print(" %s: %d\n", formatDirection(delta).c_str(), it->second);
} }
return CR_OK; return CR_OK;

@ -34,11 +34,11 @@ using df::global::world;
DFHACK_PLUGIN("autodump"); DFHACK_PLUGIN("autodump");
command_result df_autodump(Core * c, vector <string> & parameters); command_result df_autodump(color_ostream &out, vector <string> & parameters);
command_result df_autodump_destroy_here(Core * c, vector <string> & parameters); command_result df_autodump_destroy_here(color_ostream &out, vector <string> & parameters);
command_result df_autodump_destroy_item(Core * c, vector <string> & parameters); command_result df_autodump_destroy_item(color_ostream &out, vector <string> & parameters);
DFhackCExport command_result plugin_init ( Core * c, vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"autodump", "Teleport items marked for dumping to the cursor.", "autodump", "Teleport items marked for dumping to the cursor.",
@ -69,14 +69,14 @@ DFhackCExport command_result plugin_init ( Core * c, vector <PluginCommand> &com
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
typedef map <DFCoord, uint32_t> coordmap; typedef map <DFCoord, uint32_t> coordmap;
static command_result autodump_main(Core * c, vector <string> & parameters) static command_result autodump_main(color_ostream &out, vector <string> & parameters)
{ {
// Command line options // Command line options
bool destroy = false; bool destroy = false;
@ -103,14 +103,14 @@ static command_result autodump_main(Core * c, vector <string> & parameters)
if (need_visible && need_hidden) if (need_visible && need_hidden)
{ {
c->con.printerr("An item can't be both hidden and visible.\n"); out.printerr("An item can't be both hidden and visible.\n");
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
DFHack::VersionInfo *mem = c->vinfo; //DFHack::VersionInfo *mem = Core::getInstance().vinfo;
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
size_t numItems = world->items.all.size(); size_t numItems = world->items.all.size();
@ -125,7 +125,7 @@ static command_result autodump_main(Core * c, vector <string> & parameters)
{ {
if (!Gui::getCursorCoords(cx,cy,cz)) if (!Gui::getCursorCoords(cx,cy,cz))
{ {
c->con.printerr("Cursor position not found. Please enabled the cursor.\n"); out.printerr("Cursor position not found. Please enabled the cursor.\n");
return CR_FAILURE; return CR_FAILURE;
} }
pos_cursor = DFCoord(cx,cy,cz); pos_cursor = DFCoord(cx,cy,cz);
@ -136,13 +136,13 @@ static command_result autodump_main(Core * c, vector <string> & parameters)
Block * b = MC.BlockAt(pos_cursor / 16); Block * b = MC.BlockAt(pos_cursor / 16);
if(!b) if(!b)
{ {
c->con.printerr("Cursor is in an invalid/uninitialized area. Place it over a floor.\n"); out.printerr("Cursor is in an invalid/uninitialized area. Place it over a floor.\n");
return CR_FAILURE; return CR_FAILURE;
} }
df::tiletype ttype = MC.tiletypeAt(pos_cursor); df::tiletype ttype = MC.tiletypeAt(pos_cursor);
if(!DFHack::isFloorTerrain(ttype)) if(!DFHack::isFloorTerrain(ttype))
{ {
c->con.printerr("Cursor should be placed over a floor.\n"); out.printerr("Cursor should be placed over a floor.\n");
return CR_FAILURE; return CR_FAILURE;
} }
} }
@ -274,18 +274,18 @@ static command_result autodump_main(Core * c, vector <string> & parameters)
// Is this necessary? Is "forbid" a dirtyable attribute like "dig" is? // Is this necessary? Is "forbid" a dirtyable attribute like "dig" is?
Maps::WriteDirtyBit(cx/16, cy/16, cz, true); Maps::WriteDirtyBit(cx/16, cy/16, cz, true);
} }
c->con.print("Done. %d items %s.\n", dumped_total, destroy ? "marked for destruction" : "quickdumped"); out.print("Done. %d items %s.\n", dumped_total, destroy ? "marked for destruction" : "quickdumped");
return CR_OK; return CR_OK;
} }
command_result df_autodump(Core * c, vector <string> & parameters) command_result df_autodump(color_ostream &out, vector <string> & parameters)
{ {
CoreSuspender suspend(c); CoreSuspender suspend;
return autodump_main(c, parameters); return autodump_main(out, parameters);
} }
command_result df_autodump_destroy_here(Core * c, vector <string> & parameters) command_result df_autodump_destroy_here(color_ostream &out, vector <string> & parameters)
{ {
// HOTKEY COMMAND; CORE ALREADY SUSPENDED // HOTKEY COMMAND; CORE ALREADY SUSPENDED
if (!parameters.empty()) if (!parameters.empty())
@ -294,19 +294,19 @@ command_result df_autodump_destroy_here(Core * c, vector <string> & parameters)
vector<string> args; vector<string> args;
args.push_back("destroy-here"); args.push_back("destroy-here");
return autodump_main(c, args); return autodump_main(out, args);
} }
static map<int, df::item_flags> pending_destroy; static map<int, df::item_flags> pending_destroy;
static int last_frame = 0; static int last_frame = 0;
command_result df_autodump_destroy_item(Core * c, vector <string> & parameters) command_result df_autodump_destroy_item(color_ostream &out, vector <string> & parameters)
{ {
// HOTKEY COMMAND; CORE ALREADY SUSPENDED // HOTKEY COMMAND; CORE ALREADY SUSPENDED
if (!parameters.empty()) if (!parameters.empty())
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
df::item *item = Gui::getSelectedItem(c); df::item *item = Gui::getSelectedItem(out);
if (!item) if (!item)
return CR_FAILURE; return CR_FAILURE;
@ -332,7 +332,7 @@ command_result df_autodump_destroy_item(Core * c, vector <string> & parameters)
// Check the item is good to destroy // Check the item is good to destroy
if (item->flags.bits.garbage_colect) if (item->flags.bits.garbage_colect)
{ {
c->con.printerr("Item is already marked for destroy.\n"); out.printerr("Item is already marked for destroy.\n");
return CR_FAILURE; return CR_FAILURE;
} }
@ -340,7 +340,7 @@ command_result df_autodump_destroy_item(Core * c, vector <string> & parameters)
item->flags.bits.in_building || item->flags.bits.in_building ||
item->flags.bits.artifact1) item->flags.bits.artifact1)
{ {
c->con.printerr("Choosing not to destroy buildings, constructions and artifacts.\n"); out.printerr("Choosing not to destroy buildings, constructions and artifacts.\n");
return CR_FAILURE; return CR_FAILURE;
} }
@ -349,7 +349,7 @@ command_result df_autodump_destroy_item(Core * c, vector <string> & parameters)
df::general_ref *ref = item->itemrefs[i]; df::general_ref *ref = item->itemrefs[i];
if (ref->getType() == general_ref_type::UNIT_HOLDER) if (ref->getType() == general_ref_type::UNIT_HOLDER)
{ {
c->con.printerr("Choosing not to destroy items in unit inventory.\n"); out.printerr("Choosing not to destroy items in unit inventory.\n");
return CR_FAILURE; return CR_FAILURE;
} }
} }

@ -18,42 +18,42 @@ using namespace df::enums;
using df::global::world; using df::global::world;
using df::global::cursor; using df::global::cursor;
command_result df_changevein (Core * c, vector <string> & parameters) command_result df_changevein (color_ostream &out, vector <string> & parameters)
{ {
if (parameters.size() != 1) if (parameters.size() != 1)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
CoreSuspender suspend(c); CoreSuspender suspend;
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
if (!cursor || cursor->x == -30000) if (!cursor || cursor->x == -30000)
{ {
c->con.printerr("No cursor detected - please place the cursor over a mineral vein.\n"); out.printerr("No cursor detected - please place the cursor over a mineral vein.\n");
return CR_FAILURE; return CR_FAILURE;
} }
MaterialInfo mi; MaterialInfo mi;
if (!mi.findInorganic(parameters[0])) if (!mi.findInorganic(parameters[0]))
{ {
c->con.printerr("No such material!\n"); out.printerr("No such material!\n");
return CR_FAILURE; return CR_FAILURE;
} }
if (mi.inorganic->material.flags.is_set(material_flags::IS_METAL) || if (mi.inorganic->material.flags.is_set(material_flags::IS_METAL) ||
mi.inorganic->material.flags.is_set(material_flags::NO_STONE_STOCKPILE) || mi.inorganic->material.flags.is_set(material_flags::NO_STONE_STOCKPILE) ||
mi.inorganic->flags.is_set(inorganic_flags::SOIL_ANY)) mi.inorganic->flags.is_set(inorganic_flags::SOIL_ANY))
{ {
c->con.printerr("Invalid material - you must select a type of stone or gem\n"); out.printerr("Invalid material - you must select a type of stone or gem\n");
return CR_FAILURE; return CR_FAILURE;
} }
df::map_block *block = Maps::getBlockAbs(cursor->x, cursor->y, cursor->z); df::map_block *block = Maps::getBlockAbs(cursor->x, cursor->y, cursor->z);
if (!block) if (!block)
{ {
c->con.printerr("Invalid tile selected.\n"); out.printerr("Invalid tile selected.\n");
return CR_FAILURE; return CR_FAILURE;
} }
df::block_square_event_mineralst *mineral = NULL; df::block_square_event_mineralst *mineral = NULL;
@ -70,7 +70,7 @@ command_result df_changevein (Core * c, vector <string> & parameters)
} }
if (!mineral) if (!mineral)
{ {
c->con.printerr("Selected tile does not contain a mineral vein.\n"); out.printerr("Selected tile does not contain a mineral vein.\n");
return CR_FAILURE; return CR_FAILURE;
} }
mineral->inorganic_mat = mi.index; mineral->inorganic_mat = mi.index;
@ -80,7 +80,7 @@ command_result df_changevein (Core * c, vector <string> & parameters)
DFHACK_PLUGIN("changevein"); DFHACK_PLUGIN("changevein");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand("changevein", commands.push_back(PluginCommand("changevein",
"Changes the material of a mineral inclusion.", "Changes the material of a mineral inclusion.",
@ -89,7 +89,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }

@ -23,7 +23,7 @@ using df::global::cursor;
DFHACK_PLUGIN("cleaners"); DFHACK_PLUGIN("cleaners");
command_result cleanmap (Core * c, bool snow, bool mud) command_result cleanmap (color_ostream &out, bool snow, bool mud)
{ {
// Invoked from clean(), already suspended // Invoked from clean(), already suspended
int num_blocks = 0, blocks_total = world->map.map_blocks.size(); int num_blocks = 0, blocks_total = world->map.map_blocks.size();
@ -67,11 +67,11 @@ command_result cleanmap (Core * c, bool snow, bool mud)
} }
if(num_blocks) if(num_blocks)
c->con.print("Cleaned %d of %d map blocks.\n", num_blocks, blocks_total); out.print("Cleaned %d of %d map blocks.\n", num_blocks, blocks_total);
return CR_OK; return CR_OK;
} }
command_result cleanitems (Core * c) command_result cleanitems (color_ostream &out)
{ {
// Invoked from clean(), already suspended // Invoked from clean(), already suspended
int cleaned_items = 0, cleaned_total = 0; int cleaned_items = 0, cleaned_total = 0;
@ -89,11 +89,11 @@ command_result cleanitems (Core * c)
} }
} }
if (cleaned_total) if (cleaned_total)
c->con.print("Removed %d contaminants from %d items.\n", cleaned_total, cleaned_items); out.print("Removed %d contaminants from %d items.\n", cleaned_total, cleaned_items);
return CR_OK; return CR_OK;
} }
command_result cleanunits (Core * c) command_result cleanunits (color_ostream &out)
{ {
// Invoked from clean(), already suspended // Invoked from clean(), already suspended
int cleaned_units = 0, cleaned_total = 0; int cleaned_units = 0, cleaned_total = 0;
@ -110,27 +110,27 @@ command_result cleanunits (Core * c)
} }
} }
if (cleaned_total) if (cleaned_total)
c->con.print("Removed %d contaminants from %d creatures.\n", cleaned_total, cleaned_units); out.print("Removed %d contaminants from %d creatures.\n", cleaned_total, cleaned_units);
return CR_OK; return CR_OK;
} }
command_result spotclean (Core * c, vector <string> & parameters) command_result spotclean (color_ostream &out, vector <string> & parameters)
{ {
// HOTKEY COMMAND: CORE ALREADY SUSPENDED // HOTKEY COMMAND: CORE ALREADY SUSPENDED
if (cursor->x == -30000) if (cursor->x == -30000)
{ {
c->con.printerr("The cursor is not active.\n"); out.printerr("The cursor is not active.\n");
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available.\n"); out.printerr("Map is not available.\n");
return CR_FAILURE; return CR_FAILURE;
} }
df::map_block *block = Maps::getBlockAbs(cursor->x, cursor->y, cursor->z); df::map_block *block = Maps::getBlockAbs(cursor->x, cursor->y, cursor->z);
if (block == NULL) if (block == NULL)
{ {
c->con.printerr("Invalid map block selected!\n"); out.printerr("Invalid map block selected!\n");
return CR_FAILURE; return CR_FAILURE;
} }
@ -146,7 +146,7 @@ command_result spotclean (Core * c, vector <string> & parameters)
return CR_OK; return CR_OK;
} }
command_result clean (Core * c, vector <string> & parameters) command_result clean (color_ostream &out, vector <string> & parameters)
{ {
bool map = false; bool map = false;
bool snow = false; bool snow = false;
@ -177,17 +177,18 @@ command_result clean (Core * c, vector <string> & parameters)
if(!map && !units && !items) if(!map && !units && !items)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
CoreSuspender suspend(c); CoreSuspender suspend;
if(map) if(map)
cleanmap(c,snow,mud); cleanmap(out,snow,mud);
if(units) if(units)
cleanunits(c); cleanunits(out);
if(items) if(items)
cleanitems(c); cleanitems(out);
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"clean","Removes contaminants from map tiles, items and creatures.", "clean","Removes contaminants from map tiles, items and creatures.",
@ -212,7 +213,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }

@ -25,11 +25,11 @@ using namespace df::enums;
using df::global::world; using df::global::world;
command_result df_cleanowned (Core * c, vector <string> & parameters); command_result df_cleanowned (color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("cleanowned"); DFHACK_PLUGIN("cleanowned");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"cleanowned", "Confiscates and dumps garbage owned by dwarfs.", "cleanowned", "Confiscates and dumps garbage owned by dwarfs.",
@ -51,12 +51,12 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
command_result df_cleanowned (Core * c, vector <string> & parameters) command_result df_cleanowned (color_ostream &out, vector <string> & parameters)
{ {
bool dump_scattered = false; bool dump_scattered = false;
bool confiscate_all = false; bool confiscate_all = false;
@ -80,15 +80,15 @@ command_result df_cleanowned (Core * c, vector <string> & parameters)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
CoreSuspender suspend(c); CoreSuspender suspend;
if (!Translation::IsValid()) if (!Translation::IsValid())
{ {
c->con.printerr("Translation data unavailable!\n"); out.printerr("Translation data unavailable!\n");
return CR_FAILURE; return CR_FAILURE;
} }
c->con.print("Found total %d items.\n", world->items.all.size()); out.print("Found total %d items.\n", world->items.all.size());
for (std::size_t i=0; i < world->items.all.size(); i++) for (std::size_t i=0; i < world->items.all.size(); i++)
{ {
@ -101,7 +101,7 @@ command_result df_cleanowned (Core * c, vector <string> & parameters)
int32_t owner = Items::getItemOwnerID(item); int32_t owner = Items::getItemOwnerID(item);
if (owner >= 0) if (owner >= 0)
{ {
c->con.print("Fixing a misflagged item: \t"); out.print("Fixing a misflagged item: \t");
confiscate = true; confiscate = true;
} }
else else
@ -112,7 +112,7 @@ command_result df_cleanowned (Core * c, vector <string> & parameters)
if (item->flags.bits.rotten) if (item->flags.bits.rotten)
{ {
c->con.print("Confiscating a rotten item: \t"); out.print("Confiscating a rotten item: \t");
confiscate = true; confiscate = true;
} }
else if (item->flags.bits.on_ground) else if (item->flags.bits.on_ground)
@ -130,30 +130,30 @@ command_result df_cleanowned (Core * c, vector <string> & parameters)
confiscate = true; confiscate = true;
if(dump_scattered) if(dump_scattered)
{ {
c->con.print("Dumping a dropped item: \t"); out.print("Dumping a dropped item: \t");
dump = true; dump = true;
} }
else else
{ {
c->con.print("Confiscating a dropped item: \t"); out.print("Confiscating a dropped item: \t");
} }
} }
else if(dump_scattered) else if(dump_scattered)
{ {
c->con.print("Confiscating and dumping litter: \t"); out.print("Confiscating and dumping litter: \t");
confiscate = true; confiscate = true;
dump = true; dump = true;
} }
} }
else if (item->getWear() >= wear_dump_level) else if (item->getWear() >= wear_dump_level)
{ {
c->con.print("Confiscating and dumping a worn item: \t"); out.print("Confiscating and dumping a worn item: \t");
confiscate = true; confiscate = true;
dump = true; dump = true;
} }
else if (confiscate_all) else if (confiscate_all)
{ {
c->con.print("Confiscating: \t"); out.print("Confiscating: \t");
confiscate = true; confiscate = true;
} }
@ -161,7 +161,7 @@ command_result df_cleanowned (Core * c, vector <string> & parameters)
{ {
std::string description; std::string description;
item->getItemDescription(&description, 0); item->getItemDescription(&description, 0);
c->con.print( out.print(
"0x%x %s (wear %d)", "0x%x %s (wear %d)",
item, item,
description.c_str(), description.c_str(),
@ -171,16 +171,16 @@ command_result df_cleanowned (Core * c, vector <string> & parameters)
df::unit *owner = Items::getItemOwner(item); df::unit *owner = Items::getItemOwner(item);
if (owner) if (owner)
c->con.print(", owner %s", Translation::TranslateName(&owner->name,false).c_str()); out.print(", owner %s", Translation::TranslateName(&owner->name,false).c_str());
if (!dry_run) if (!dry_run)
{ {
if (!Items::removeItemOwner(item)) if (!Items::removeItemOwner(item))
c->con.print("(unsuccessfully) "); out.print("(unsuccessfully) ");
if (dump) if (dump)
item->flags.bits.dump = 1; item->flags.bits.dump = 1;
} }
c->con.print("\n"); out.print("\n");
} }
} }
return CR_OK; return CR_OK;

@ -11,11 +11,11 @@ using std::vector;
using std::string; using std::string;
using namespace DFHack; using namespace DFHack;
command_result colonies (Core * c, vector <string> & parameters); command_result colonies (color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("colonies"); DFHACK_PLUGIN("colonies");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"colonies", "List or change wild colonies (ants hills and such)", "colonies", "List or change wild colonies (ants hills and such)",
@ -28,16 +28,16 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
void destroyColonies(); void destroyColonies();
void convertColonies(Materials *Materials); void convertColonies(Materials *Materials);
void showColonies(Core *c, Materials *Materials); void showColonies(color_ostream &out, Materials *Materials);
command_result colonies (Core * c, vector <string> & parameters) command_result colonies (color_ostream &out, vector <string> & parameters)
{ {
bool destroy = false; bool destroy = false;
bool convert = false; bool convert = false;
@ -53,12 +53,13 @@ command_result colonies (Core * c, vector <string> & parameters)
} }
if (destroy && convert) if (destroy && convert)
{ {
c->con.printerr("Kill or make bees? DECIDE!\n"); out.printerr("Kill or make bees? DECIDE!\n");
return CR_FAILURE; return CR_FAILURE;
} }
CoreSuspender suspend(c);
Materials * materials = c->getMaterials(); CoreSuspender suspend;
Materials * materials = Core::getInstance().getMaterials();
materials->ReadCreatureTypesEx(); materials->ReadCreatureTypesEx();
@ -67,7 +68,7 @@ command_result colonies (Core * c, vector <string> & parameters)
else if (convert) else if (convert)
convertColonies(materials); convertColonies(materials);
else else
showColonies(c, materials); showColonies(out, materials);
materials->Finish(); materials->Finish();
@ -124,7 +125,7 @@ void convertColonies(Materials *Materials)
} }
} }
void showColonies(Core *c, Materials *Materials) void showColonies(color_ostream &out, Materials *Materials)
{ {
uint32_t numSpawnPoints = Vermin::getNumVermin(); uint32_t numSpawnPoints = Vermin::getNumVermin();
int numColonies = 0; int numColonies = 0;
@ -141,11 +142,11 @@ void showColonies(Core *c, Materials *Materials)
if(sp.race != -1) if(sp.race != -1)
race = Materials->raceEx[sp.race].id; race = Materials->raceEx[sp.race].id;
c->con.print("Colony %u: %s at %d:%d:%d\n", i, out.print("Colony %u: %s at %d:%d:%d\n", i,
race.c_str(), sp.x, sp.y, sp.z); race.c_str(), sp.x, sp.y, sp.z);
} }
} }
if (numColonies == 0) if (numColonies == 0)
c->con << "No colonies present." << std::endl; out << "No colonies present." << std::endl;
} }

@ -18,16 +18,16 @@ using df::global::world;
DFHACK_PLUGIN("deramp"); DFHACK_PLUGIN("deramp");
command_result df_deramp (Core * c, vector <string> & parameters) command_result df_deramp (color_ostream &out, vector <string> & parameters)
{ {
if (!parameters.empty()) if (!parameters.empty())
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
CoreSuspender suspend(c); CoreSuspender suspend;
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
@ -75,13 +75,13 @@ command_result df_deramp (Core * c, vector <string> & parameters)
} }
} }
if (count) if (count)
c->con.print("Found and changed %d tiles.\n", count); out.print("Found and changed %d tiles.\n", count);
if (countbad) if (countbad)
c->con.print("Fixed %d bad down ramps.\n", countbad); out.print("Fixed %d bad down ramps.\n", countbad);
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"deramp", "De-ramp. All ramps marked for removal are replaced with floors.", "deramp", "De-ramp. All ramps marked for removal are replaced with floors.",
@ -93,7 +93,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }

@ -18,40 +18,38 @@ using std::string;
using std::stack; using std::stack;
using namespace DFHack; using namespace DFHack;
command_result readFlag (Core * c, vector <string> & parameters); command_result readFlag (color_ostream &out, vector <string> & parameters);
command_result writeFlag (Core * c, vector <string> & parameters); command_result writeFlag (color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("buildprobe"); DFHACK_PLUGIN("buildprobe");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand("bshow","Output building occupancy value",readFlag)); commands.push_back(PluginCommand("bshow","Output building occupancy value",readFlag));
commands.push_back(PluginCommand("bset","Set building occupancy value",writeFlag)); commands.push_back(PluginCommand("bset","Set building occupancy value",writeFlag));
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
command_result readFlag (Core * c, vector <string> & parameters) command_result readFlag (color_ostream &out, vector <string> & parameters)
{ {
c->Suspend(); CoreSuspender suspend;
// init the map // init the map
if(!Maps::IsValid()) if(!Maps::IsValid())
{ {
c->con.printerr("Can't init map. Make sure you have a map loaded in DF.\n"); out.printerr("Can't init map. Make sure you have a map loaded in DF.\n");
c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
int32_t cx, cy, cz; int32_t cx, cy, cz;
if(!Gui::getCursorCoords(cx,cy,cz)) if(!Gui::getCursorCoords(cx,cy,cz))
{ {
c->con.printerr("Cursor is not active.\n"); out.printerr("Cursor is not active.\n");
c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
@ -60,23 +58,21 @@ command_result readFlag (Core * c, vector <string> & parameters)
MapExtras::MapCache * MCache = new MapExtras::MapCache(); MapExtras::MapCache * MCache = new MapExtras::MapCache();
t_occupancy oc = MCache->occupancyAt(cursor); t_occupancy oc = MCache->occupancyAt(cursor);
c->con.print("Current Value: %d\n", oc.bits.building); out.print("Current Value: %d\n", oc.bits.building);
c->Resume();
return CR_OK; return CR_OK;
} }
command_result writeFlag (Core * c, vector <string> & parameters) command_result writeFlag (color_ostream &out, vector <string> & parameters)
{ {
if (parameters.size() == 0) if (parameters.size() == 0)
{ {
c->con.print("No value specified\n"); out.print("No value specified\n");
return CR_FAILURE; return CR_FAILURE;
} }
if (parameters[0] == "help" || parameters[0] == "?") if (parameters[0] == "help" || parameters[0] == "?")
{ {
c->con.print("Set the building occupancy flag.\n" out.print("Set the building occupancy flag.\n"
"Value must be between 0 and 7, inclusive.\n"); "Value must be between 0 and 7, inclusive.\n");
return CR_OK; return CR_OK;
} }
@ -97,26 +93,24 @@ command_result writeFlag (Core * c, vector <string> & parameters)
break; break;
default: default:
c->con.print("Invalid value specified\n"); out.print("Invalid value specified\n");
return CR_FAILURE; return CR_FAILURE;
break; //Redundant. break; //Redundant.
} }
c->Suspend(); CoreSuspender suspend;
// init the map // init the map
if(!Maps::IsValid()) if(!Maps::IsValid())
{ {
c->con.printerr("Can't init map. Make sure you have a map loaded in DF.\n"); out.printerr("Can't init map. Make sure you have a map loaded in DF.\n");
c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
int32_t cx, cy, cz; int32_t cx, cy, cz;
if(!Gui::getCursorCoords(cx,cy,cz)) if(!Gui::getCursorCoords(cx,cy,cz))
{ {
c->con.printerr("Cursor is not active.\n"); out.printerr("Cursor is not active.\n");
c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
@ -129,6 +123,5 @@ command_result writeFlag (Core * c, vector <string> & parameters)
MCache->setOccupancyAt(cursor, oc); MCache->setOccupancyAt(cursor, oc);
MCache->WriteAll(); MCache->WriteAll();
c->Resume();
return CR_OK; return CR_OK;
} }

@ -25,12 +25,12 @@ using namespace std;
using namespace DFHack; using namespace DFHack;
command_result catsplosion (Core * c, std::vector <std::string> & parameters); command_result catsplosion (color_ostream &out, std::vector <std::string> & parameters);
DFHACK_PLUGIN("catsplosion"); DFHACK_PLUGIN("catsplosion");
// Mandatory init function. If you have some global state, create it here. // Mandatory init function. If you have some global state, create it here.
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
// Fill the command list with your commands. // Fill the command list with your commands.
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
@ -41,13 +41,13 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
typedef df::unit::T_relations::T_pregnancy_ptr pregstruct; typedef df::unit::T_relations::T_pregnancy_ptr pregstruct;
command_result catsplosion (Core * c, std::vector <std::string> & parameters) command_result catsplosion (color_ostream &out, std::vector <std::string> & parameters)
{ {
list<string> s_creatures; list<string> s_creatures;
// only cats for now. // only cats for now.
@ -55,7 +55,7 @@ command_result catsplosion (Core * c, std::vector <std::string> & parameters)
// make the creature list unique ... with cats. they are always unique // make the creature list unique ... with cats. they are always unique
s_creatures.unique(); s_creatures.unique();
// SUSPEND THE CORE! ::Evil laugh:: // SUSPEND THE CORE! ::Evil laugh::
CoreSuspender susp(c); CoreSuspender susp;
uint32_t numCreatures; uint32_t numCreatures;
if(!(numCreatures = Units::getNumCreatures())) if(!(numCreatures = Units::getNumCreatures()))
@ -95,10 +95,10 @@ command_result catsplosion (Core * c, std::vector <std::string> & parameters)
// print (optional) // print (optional)
//if (showcreatures == 1) //if (showcreatures == 1)
{ {
c->con.print("Type Male # Female #\n"); out.print("Type Male # Female #\n");
for(auto it1 = male_counts.begin();it1!=male_counts.end();it1++) for(auto it1 = male_counts.begin();it1!=male_counts.end();it1++)
{ {
c->con.print("%20s %6d %8d\n", it1->first.c_str(), it1->second.size(), female_counts[it1->first].size()); out.print("%20s %6d %8d\n", it1->first.c_str(), it1->second.size(), female_counts[it1->first].size());
} }
} }
@ -133,9 +133,9 @@ command_result catsplosion (Core * c, std::vector <std::string> & parameters)
} }
} }
if(totalchanged) if(totalchanged)
c->con.print("%d pregnancies accelerated.\n", totalchanged); out.print("%d pregnancies accelerated.\n", totalchanged);
if(totalcreated) if(totalcreated)
c->con.print("%d pregnancies created.\n", totalcreated); out.print("%d pregnancies created.\n", totalcreated);
c->con.print("Total creatures checked: %d\n", totalcount); out.print("Total creatures checked: %d\n", totalcount);
return CR_OK; return CR_OK;
} }

@ -19,22 +19,22 @@ using namespace df::enums;
using df::global::world; using df::global::world;
command_result df_dumpmats (Core *c, vector<string> &parameters) command_result df_dumpmats (color_ostream &out, vector<string> &parameters)
{ {
if (!parameters.empty()) if (!parameters.empty())
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
CoreSuspender suspend(c); CoreSuspender suspend;
c->con.print("hardcoded_materials\n\n"); out.print("hardcoded_materials\n\n");
c->con.print("[OBJECT:MATERIAL]\n"); out.print("[OBJECT:MATERIAL]\n");
FOR_ENUM_ITEMS(builtin_mats, mat_num) FOR_ENUM_ITEMS(builtin_mats, mat_num)
{ {
df::material *mat = world->raws.mat_table.builtin[mat_num]; df::material *mat = world->raws.mat_table.builtin[mat_num];
if (!mat) if (!mat)
continue; continue;
c->con.print("\n[MATERIAL:%s] - reconstructed from data extracted from memory\n", mat->id.c_str()); out.print("\n[MATERIAL:%s] - reconstructed from data extracted from memory\n", mat->id.c_str());
int32_t def_color[6] = {-1,-1,-1,-1,-1,-1}; int32_t def_color[6] = {-1,-1,-1,-1,-1,-1};
bool name_all = false; bool name_all = false;
@ -58,10 +58,10 @@ command_result df_dumpmats (Core *c, vector<string> &parameters)
{ {
def_color[matter_state::Liquid] = solid_color; def_color[matter_state::Liquid] = solid_color;
def_color[matter_state::Gas] = solid_color; def_color[matter_state::Gas] = solid_color;
c->con.print("\t[STATE_COLOR:ALL:%s]\n", world->raws.language.colors[solid_color]->id.c_str()); out.print("\t[STATE_COLOR:ALL:%s]\n", world->raws.language.colors[solid_color]->id.c_str());
} }
else else
c->con.print("\t[STATE_COLOR:ALL_SOLID:%s]\n", world->raws.language.colors[solid_color]->id.c_str()); out.print("\t[STATE_COLOR:ALL_SOLID:%s]\n", world->raws.language.colors[solid_color]->id.c_str());
} }
string solid_name = mat->state_name[matter_state::Solid]; string solid_name = mat->state_name[matter_state::Solid];
@ -88,10 +88,10 @@ command_result df_dumpmats (Core *c, vector<string> &parameters)
def_name[matter_state::Gas] = solid_name; def_name[matter_state::Gas] = solid_name;
def_adj[matter_state::Liquid] = solid_name; def_adj[matter_state::Liquid] = solid_name;
def_adj[matter_state::Gas] = solid_name; def_adj[matter_state::Gas] = solid_name;
c->con.print("\t[STATE_NAME_ADJ:ALL:%s]\n", solid_name.c_str()); out.print("\t[STATE_NAME_ADJ:ALL:%s]\n", solid_name.c_str());
} }
else else
c->con.print("\t[STATE_NAME_ADJ:ALL_SOLID:%s]\n", solid_name.c_str()); out.print("\t[STATE_NAME_ADJ:ALL_SOLID:%s]\n", solid_name.c_str());
} }
} }
else else
@ -110,10 +110,10 @@ command_result df_dumpmats (Core *c, vector<string> &parameters)
{ {
def_name[matter_state::Liquid] = solid_name; def_name[matter_state::Liquid] = solid_name;
def_name[matter_state::Gas] = solid_name; def_name[matter_state::Gas] = solid_name;
c->con.print("\t[STATE_NAME:ALL:%s]\n", solid_name.c_str()); out.print("\t[STATE_NAME:ALL:%s]\n", solid_name.c_str());
} }
else else
c->con.print("\t[STATE_NAME:ALL_SOLID:%s]\n", solid_name.c_str()); out.print("\t[STATE_NAME:ALL_SOLID:%s]\n", solid_name.c_str());
} }
if (solid_adj == mat->state_adj[matter_state::Powder] || if (solid_adj == mat->state_adj[matter_state::Powder] ||
solid_adj == mat->state_adj[matter_state::Paste] || solid_adj == mat->state_adj[matter_state::Paste] ||
@ -129,148 +129,148 @@ command_result df_dumpmats (Core *c, vector<string> &parameters)
{ {
def_adj[matter_state::Liquid] = solid_adj; def_adj[matter_state::Liquid] = solid_adj;
def_adj[matter_state::Gas] = solid_adj; def_adj[matter_state::Gas] = solid_adj;
c->con.print("\t[STATE_ADJ:ALL:%s]\n", solid_adj.c_str()); out.print("\t[STATE_ADJ:ALL:%s]\n", solid_adj.c_str());
} }
else else
c->con.print("\t[STATE_ADJ:ALL_SOLID:%s]\n", solid_adj.c_str()); out.print("\t[STATE_ADJ:ALL_SOLID:%s]\n", solid_adj.c_str());
} }
} }
char *state_names[6] = {"SOLID", "LIQUID", "GAS", "SOLID_POWDER", "SOLID_PASTE", "SOLID_PRESSED"}; const char *state_names[6] = {"SOLID", "LIQUID", "GAS", "SOLID_POWDER", "SOLID_PASTE", "SOLID_PRESSED"};
FOR_ENUM_ITEMS(matter_state, state) FOR_ENUM_ITEMS(matter_state, state)
{ {
if (mat->state_color[state] != -1 && mat->state_color[state] != def_color[state]) if (mat->state_color[state] != -1 && mat->state_color[state] != def_color[state])
c->con.print("\t[STATE_COLOR:%s:%s]\n", state_names[state], world->raws.language.colors[mat->state_color[state]]->id.c_str()); out.print("\t[STATE_COLOR:%s:%s]\n", state_names[state], world->raws.language.colors[mat->state_color[state]]->id.c_str());
if (mat->state_name[state] == mat->state_adj[state]) if (mat->state_name[state] == mat->state_adj[state])
{ {
if (mat->state_name[state].size() && mat->state_name[state] != def_name[state] || mat->state_adj[state].size() && mat->state_adj[state] != def_adj[state]) if (mat->state_name[state].size() && mat->state_name[state] != def_name[state] || mat->state_adj[state].size() && mat->state_adj[state] != def_adj[state])
c->con.print("\t[STATE_NAME_ADJ:%s:%s]\n", state_names[state], mat->state_name[state].c_str()); out.print("\t[STATE_NAME_ADJ:%s:%s]\n", state_names[state], mat->state_name[state].c_str());
} }
else else
{ {
if (mat->state_name[state].size() && mat->state_name[state] != def_name[state]) if (mat->state_name[state].size() && mat->state_name[state] != def_name[state])
c->con.print("\t[STATE_NAME:%s:%s]\n", state_names[state], mat->state_name[state].c_str()); out.print("\t[STATE_NAME:%s:%s]\n", state_names[state], mat->state_name[state].c_str());
if (mat->state_adj[state].size() && mat->state_adj[state] != def_adj[state]) if (mat->state_adj[state].size() && mat->state_adj[state] != def_adj[state])
c->con.print("\t[STATE_ADJ:%s:%s]\n", state_names[state], mat->state_adj[state].c_str()); out.print("\t[STATE_ADJ:%s:%s]\n", state_names[state], mat->state_adj[state].c_str());
} }
} }
if (mat->basic_color[0] != 7 || mat->basic_color[1] != 0) if (mat->basic_color[0] != 7 || mat->basic_color[1] != 0)
c->con.print("\t[BASIC_COLOR:%i:%i]\n", mat->basic_color[0], mat->basic_color[1]); out.print("\t[BASIC_COLOR:%i:%i]\n", mat->basic_color[0], mat->basic_color[1]);
if (mat->build_color[0] != 7 || mat->build_color[1] != 7 || mat->build_color[2] != 0) if (mat->build_color[0] != 7 || mat->build_color[1] != 7 || mat->build_color[2] != 0)
c->con.print("\t[BUILD_COLOR:%i:%i:%i]\n", mat->build_color[0], mat->build_color[1], mat->build_color[2]); out.print("\t[BUILD_COLOR:%i:%i:%i]\n", mat->build_color[0], mat->build_color[1], mat->build_color[2]);
if (mat->tile_color[0] != 7 || mat->tile_color[1] != 7 || mat->tile_color[2] != 0) if (mat->tile_color[0] != 7 || mat->tile_color[1] != 7 || mat->tile_color[2] != 0)
c->con.print("\t[TILE_COLOR:%i:%i:%i]\n", mat->tile_color[0], mat->tile_color[1], mat->tile_color[2]); out.print("\t[TILE_COLOR:%i:%i:%i]\n", mat->tile_color[0], mat->tile_color[1], mat->tile_color[2]);
if (mat->tile != 0xdb) if (mat->tile != 0xdb)
c->con.print("\t[TILE:%i]\n", mat->tile); out.print("\t[TILE:%i]\n", mat->tile);
if (mat->item_symbol != 0x07) if (mat->item_symbol != 0x07)
c->con.print("\t[ITEM_SYMBOL:%i]\n", mat->item_symbol); out.print("\t[ITEM_SYMBOL:%i]\n", mat->item_symbol);
if (mat->material_value != 1) if (mat->material_value != 1)
c->con.print("\t[MATERIAL_VALUE:%i]\n", mat->material_value); out.print("\t[MATERIAL_VALUE:%i]\n", mat->material_value);
if (mat->gem_name1.size()) if (mat->gem_name1.size())
c->con.print("\t[IS_GEM:%s:%s]\n", mat->gem_name1.c_str(), mat->gem_name2.c_str()); out.print("\t[IS_GEM:%s:%s]\n", mat->gem_name1.c_str(), mat->gem_name2.c_str());
if (mat->stone_name.size()) if (mat->stone_name.size())
c->con.print("\t[STONE_NAME:%s]\n", mat->stone_name.c_str()); out.print("\t[STONE_NAME:%s]\n", mat->stone_name.c_str());
if (mat->heat.spec_heat != 60001) if (mat->heat.spec_heat != 60001)
c->con.print("\t[SPEC_HEAT:%i]\n", mat->heat.spec_heat); out.print("\t[SPEC_HEAT:%i]\n", mat->heat.spec_heat);
if (mat->heat.heatdam_point != 60001) if (mat->heat.heatdam_point != 60001)
c->con.print("\t[HEATDAM_POINT:%i]\n", mat->heat.heatdam_point); out.print("\t[HEATDAM_POINT:%i]\n", mat->heat.heatdam_point);
if (mat->heat.colddam_point != 60001) if (mat->heat.colddam_point != 60001)
c->con.print("\t[COLDDAM_POINT:%i]\n", mat->heat.colddam_point); out.print("\t[COLDDAM_POINT:%i]\n", mat->heat.colddam_point);
if (mat->heat.ignite_point != 60001) if (mat->heat.ignite_point != 60001)
c->con.print("\t[IGNITE_POINT:%i]\n", mat->heat.ignite_point); out.print("\t[IGNITE_POINT:%i]\n", mat->heat.ignite_point);
if (mat->heat.melting_point != 60001) if (mat->heat.melting_point != 60001)
c->con.print("\t[MELTING_POINT:%i]\n", mat->heat.melting_point); out.print("\t[MELTING_POINT:%i]\n", mat->heat.melting_point);
if (mat->heat.boiling_point != 60001) if (mat->heat.boiling_point != 60001)
c->con.print("\t[BOILING_POINT:%i]\n", mat->heat.boiling_point); out.print("\t[BOILING_POINT:%i]\n", mat->heat.boiling_point);
if (mat->heat.mat_fixed_temp != 60001) if (mat->heat.mat_fixed_temp != 60001)
c->con.print("\t[MAT_FIXED_TEMP:%i]\n", mat->heat.mat_fixed_temp); out.print("\t[MAT_FIXED_TEMP:%i]\n", mat->heat.mat_fixed_temp);
if (mat->solid_density != 0xFBBC7818) if (mat->solid_density != 0xFBBC7818)
c->con.print("\t[SOLID_DENSITY:%i]\n", mat->solid_density); out.print("\t[SOLID_DENSITY:%i]\n", mat->solid_density);
if (mat->liquid_density != 0xFBBC7818) if (mat->liquid_density != 0xFBBC7818)
c->con.print("\t[LIQUID_DENSITY:%i]\n", mat->liquid_density); out.print("\t[LIQUID_DENSITY:%i]\n", mat->liquid_density);
if (mat->molar_mass != 0xFBBC7818) if (mat->molar_mass != 0xFBBC7818)
c->con.print("\t[MOLAR_MASS:%i]\n", mat->molar_mass); out.print("\t[MOLAR_MASS:%i]\n", mat->molar_mass);
if (mat->strength.impact_yield != 10000) if (mat->strength.impact_yield != 10000)
c->con.print("\t[IMPACT_YIELD:%i]\n", mat->strength.impact_yield); out.print("\t[IMPACT_YIELD:%i]\n", mat->strength.impact_yield);
if (mat->strength.impact_fracture != 10000) if (mat->strength.impact_fracture != 10000)
c->con.print("\t[IMPACT_FRACTURE:%i]\n", mat->strength.impact_fracture); out.print("\t[IMPACT_FRACTURE:%i]\n", mat->strength.impact_fracture);
if (mat->strength.impact_strain_at_yield != 0) if (mat->strength.impact_strain_at_yield != 0)
c->con.print("\t[IMPACT_STRAIN_AT_YIELD:%i]\n", mat->strength.impact_strain_at_yield); out.print("\t[IMPACT_STRAIN_AT_YIELD:%i]\n", mat->strength.impact_strain_at_yield);
if (mat->strength.compressive_yield != 10000) if (mat->strength.compressive_yield != 10000)
c->con.print("\t[COMPRESSIVE_YIELD:%i]\n", mat->strength.compressive_yield); out.print("\t[COMPRESSIVE_YIELD:%i]\n", mat->strength.compressive_yield);
if (mat->strength.compressive_fracture != 10000) if (mat->strength.compressive_fracture != 10000)
c->con.print("\t[COMPRESSIVE_FRACTURE:%i]\n", mat->strength.compressive_fracture); out.print("\t[COMPRESSIVE_FRACTURE:%i]\n", mat->strength.compressive_fracture);
if (mat->strength.compressive_strain_at_yield != 0) if (mat->strength.compressive_strain_at_yield != 0)
c->con.print("\t[COMPRESSIVE_STRAIN_AT_YIELD:%i]\n", mat->strength.compressive_strain_at_yield); out.print("\t[COMPRESSIVE_STRAIN_AT_YIELD:%i]\n", mat->strength.compressive_strain_at_yield);
if (mat->strength.tensile_yield != 10000) if (mat->strength.tensile_yield != 10000)
c->con.print("\t[TENSILE_YIELD:%i]\n", mat->strength.tensile_yield); out.print("\t[TENSILE_YIELD:%i]\n", mat->strength.tensile_yield);
if (mat->strength.tensile_fracture != 10000) if (mat->strength.tensile_fracture != 10000)
c->con.print("\t[TENSILE_FRACTURE:%i]\n", mat->strength.tensile_fracture); out.print("\t[TENSILE_FRACTURE:%i]\n", mat->strength.tensile_fracture);
if (mat->strength.tensile_strain_at_yield != 0) if (mat->strength.tensile_strain_at_yield != 0)
c->con.print("\t[TENSILE_STRAIN_AT_YIELD:%i]\n", mat->strength.tensile_strain_at_yield); out.print("\t[TENSILE_STRAIN_AT_YIELD:%i]\n", mat->strength.tensile_strain_at_yield);
if (mat->strength.torsion_yield != 10000) if (mat->strength.torsion_yield != 10000)
c->con.print("\t[TORSION_YIELD:%i]\n", mat->strength.torsion_yield); out.print("\t[TORSION_YIELD:%i]\n", mat->strength.torsion_yield);
if (mat->strength.torsion_fracture != 10000) if (mat->strength.torsion_fracture != 10000)
c->con.print("\t[TORSION_FRACTURE:%i]\n", mat->strength.torsion_fracture); out.print("\t[TORSION_FRACTURE:%i]\n", mat->strength.torsion_fracture);
if (mat->strength.torsion_strain_at_yield != 0) if (mat->strength.torsion_strain_at_yield != 0)
c->con.print("\t[TORSION_STRAIN_AT_YIELD:%i]\n", mat->strength.torsion_strain_at_yield); out.print("\t[TORSION_STRAIN_AT_YIELD:%i]\n", mat->strength.torsion_strain_at_yield);
if (mat->strength.shear_yield != 10000) if (mat->strength.shear_yield != 10000)
c->con.print("\t[SHEAR_YIELD:%i]\n", mat->strength.shear_yield); out.print("\t[SHEAR_YIELD:%i]\n", mat->strength.shear_yield);
if (mat->strength.shear_fracture != 10000) if (mat->strength.shear_fracture != 10000)
c->con.print("\t[SHEAR_FRACTURE:%i]\n", mat->strength.shear_fracture); out.print("\t[SHEAR_FRACTURE:%i]\n", mat->strength.shear_fracture);
if (mat->strength.shear_strain_at_yield != 0) if (mat->strength.shear_strain_at_yield != 0)
c->con.print("\t[SHEAR_STRAIN_AT_YIELD:%i]\n", mat->strength.shear_strain_at_yield); out.print("\t[SHEAR_STRAIN_AT_YIELD:%i]\n", mat->strength.shear_strain_at_yield);
if (mat->strength.bending_yield != 10000) if (mat->strength.bending_yield != 10000)
c->con.print("\t[BENDING_YIELD:%i]\n", mat->strength.bending_yield); out.print("\t[BENDING_YIELD:%i]\n", mat->strength.bending_yield);
if (mat->strength.bending_fracture != 10000) if (mat->strength.bending_fracture != 10000)
c->con.print("\t[BENDING_FRACTURE:%i]\n", mat->strength.bending_fracture); out.print("\t[BENDING_FRACTURE:%i]\n", mat->strength.bending_fracture);
if (mat->strength.bending_strain_at_yield != 0) if (mat->strength.bending_strain_at_yield != 0)
c->con.print("\t[BENDING_STRAIN_AT_YIELD:%i]\n", mat->strength.bending_strain_at_yield); out.print("\t[BENDING_STRAIN_AT_YIELD:%i]\n", mat->strength.bending_strain_at_yield);
if (mat->strength.max_edge != 0) if (mat->strength.max_edge != 0)
c->con.print("\t[MAX_EDGE:%i]\n", mat->strength.max_edge); out.print("\t[MAX_EDGE:%i]\n", mat->strength.max_edge);
if (mat->strength.absorption != 0) if (mat->strength.absorption != 0)
c->con.print("\t[ABSORPTION:%i]\n", mat->strength.absorption); out.print("\t[ABSORPTION:%i]\n", mat->strength.absorption);
FOR_ENUM_ITEMS(material_flags, i) FOR_ENUM_ITEMS(material_flags, i)
{ {
if (mat->flags.is_set(i)) if (mat->flags.is_set(i))
c->con.print("\t[%s]\n", ENUM_KEY_STR(material_flags, i)); out.print("\t[%s]\n", ENUM_KEY_STR(material_flags, i));
} }
if (mat->extract_storage != item_type::BARREL) if (mat->extract_storage != item_type::BARREL)
c->con.print("\t[EXTRACT_STORAGE:%s]\n", ENUM_KEY_STR(item_type, mat->extract_storage)); out.print("\t[EXTRACT_STORAGE:%s]\n", ENUM_KEY_STR(item_type, mat->extract_storage));
if (mat->butcher_special_type != item_type::NONE || mat->butcher_special_subtype != -1) if (mat->butcher_special_type != item_type::NONE || mat->butcher_special_subtype != -1)
c->con.print("\t[BUTCHER_SPECIAL:%s:%s]\n", ENUM_KEY_STR(item_type, mat->butcher_special_type), (mat->butcher_special_subtype == -1) ? "NONE" : "?"); out.print("\t[BUTCHER_SPECIAL:%s:%s]\n", ENUM_KEY_STR(item_type, mat->butcher_special_type), (mat->butcher_special_subtype == -1) ? "NONE" : "?");
if (mat->meat_name[0].size() || mat->meat_name[1].size() || mat->meat_name[2].size()) if (mat->meat_name[0].size() || mat->meat_name[1].size() || mat->meat_name[2].size())
c->con.print("\t[MEAT_NAME:%s:%s:%s]\n", mat->meat_name[0].c_str(), mat->meat_name[1].c_str(), mat->meat_name[2].c_str()); out.print("\t[MEAT_NAME:%s:%s:%s]\n", mat->meat_name[0].c_str(), mat->meat_name[1].c_str(), mat->meat_name[2].c_str());
if (mat->block_name[0].size() || mat->block_name[1].size()) if (mat->block_name[0].size() || mat->block_name[1].size())
c->con.print("\t[BLOCK_NAME:%s:%s]\n", mat->block_name[0].c_str(), mat->block_name[1].c_str()); out.print("\t[BLOCK_NAME:%s:%s]\n", mat->block_name[0].c_str(), mat->block_name[1].c_str());
for (int i = 0; i < mat->reaction_class.size(); i++) for (int i = 0; i < mat->reaction_class.size(); i++)
c->con.print("\t[REACTION_CLASS:%s]\n", mat->reaction_class[i]->c_str()); out.print("\t[REACTION_CLASS:%s]\n", mat->reaction_class[i]->c_str());
for (int i = 0; i < mat->reaction_product.id.size(); i++) for (int i = 0; i < mat->reaction_product.id.size(); i++)
c->con.print("\t[MATERIAL_REACTION_PRODUCT:%s:%s:%s%s%s]\n", mat->reaction_product.id[i]->c_str(), mat->reaction_product.str[0][i]->c_str(), mat->reaction_product.str[1][i]->c_str(), mat->reaction_product.str[2][i]->size() ? ":" : "", mat->reaction_product.str[2][i]->c_str()); out.print("\t[MATERIAL_REACTION_PRODUCT:%s:%s:%s%s%s]\n", mat->reaction_product.id[i]->c_str(), mat->reaction_product.str[0][i]->c_str(), mat->reaction_product.str[1][i]->c_str(), mat->reaction_product.str[2][i]->size() ? ":" : "", mat->reaction_product.str[2][i]->c_str());
if (mat->hardens_with_water.mat_type != -1) if (mat->hardens_with_water.mat_type != -1)
c->con.print("\t[HARDENS_WITH_WATER:%s:%s%s%s]\n", mat->hardens_with_water.str[0].c_str(), mat->hardens_with_water.str[1].c_str(), mat->hardens_with_water.str[2].size() ? ":" : "", mat->hardens_with_water.str[2].c_str()); out.print("\t[HARDENS_WITH_WATER:%s:%s%s%s]\n", mat->hardens_with_water.str[0].c_str(), mat->hardens_with_water.str[1].c_str(), mat->hardens_with_water.str[2].size() ? ":" : "", mat->hardens_with_water.str[2].c_str());
if (mat->powder_dye != -1) if (mat->powder_dye != -1)
c->con.print("\t[POWDER_DYE:%s]\n", world->raws.language.colors[mat->powder_dye]->id.c_str()); out.print("\t[POWDER_DYE:%s]\n", world->raws.language.colors[mat->powder_dye]->id.c_str());
if (mat->soap_level != -0) if (mat->soap_level != -0)
c->con.print("\t[SOAP_LEVEL:%o]\n", mat->soap_level); out.print("\t[SOAP_LEVEL:%o]\n", mat->soap_level);
for (int i = 0; i < mat->syndrome.size(); i++) for (int i = 0; i < mat->syndrome.size(); i++)
c->con.print("\t[SYNDROME] ...\n"); out.print("\t[SYNDROME] ...\n");
} }
return CR_OK; return CR_OK;
} }

@ -41,54 +41,54 @@ int changeLiquid (df::tile_liquid type)
return tiles; return tiles;
} }
command_result df_frozenlava (Core * c, vector <string> & parameters) command_result df_frozenlava (color_ostream &out, vector <string> & parameters)
{ {
if (parameters.size()) if (parameters.size())
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
CoreSuspender suspend(c); CoreSuspender suspend;
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
int tiles = changeLiquid(tile_liquid::Magma); int tiles = changeLiquid(tile_liquid::Magma);
if (tiles) if (tiles)
c->con.print("Changed %i tiles of ice into frozen lava.\n", tiles); out.print("Changed %i tiles of ice into frozen lava.\n", tiles);
return CR_OK; return CR_OK;
} }
command_result df_frozenwater (Core * c, vector <string> & parameters) command_result df_frozenwater (color_ostream &out, vector <string> & parameters)
{ {
if (parameters.size()) if (parameters.size())
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
CoreSuspender suspend(c); CoreSuspender suspend;
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
int tiles = changeLiquid(tile_liquid::Water); int tiles = changeLiquid(tile_liquid::Water);
if (tiles) if (tiles)
c->con.print("Changed %i tiles of ice into frozen water.\n", tiles); out.print("Changed %i tiles of ice into frozen water.\n", tiles);
return CR_OK; return CR_OK;
} }
DFHACK_PLUGIN("frozen"); DFHACK_PLUGIN("frozen");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand("frozenlava", "Changes all ice into frozen magma.", df_frozenlava)); commands.push_back(PluginCommand("frozenlava", "Changes all ice into frozen magma.", df_frozenlava));
commands.push_back(PluginCommand("frozenwater", "Changes all ice into frozen water.", df_frozenwater)); commands.push_back(PluginCommand("frozenwater", "Changes all ice into frozen water.", df_frozenwater));
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }

@ -27,16 +27,16 @@ int32_t last_mouse[2] = {-1, -1};
uint32_t last_menu = 0; uint32_t last_menu = 0;
uint64_t timeLast = 0; uint64_t timeLast = 0;
command_result kittens (Core * c, vector <string> & parameters); command_result kittens (color_ostream &out, vector <string> & parameters);
command_result ktimer (Core * c, vector <string> & parameters); command_result ktimer (color_ostream &out, vector <string> & parameters);
command_result trackmenu (Core * c, vector <string> & parameters); command_result trackmenu (color_ostream &out, vector <string> & parameters);
command_result trackpos (Core * c, vector <string> & parameters); command_result trackpos (color_ostream &out, vector <string> & parameters);
command_result colormods (Core * c, vector <string> & parameters); command_result colormods (color_ostream &out, vector <string> & parameters);
command_result zoom (Core * c, vector <string> & parameters); command_result zoom (color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("kittens"); DFHACK_PLUGIN("kittens");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand("nyan","NYAN CAT INVASION!",kittens, true)); commands.push_back(PluginCommand("nyan","NYAN CAT INVASION!",kittens, true));
commands.push_back(PluginCommand("ktimer","Measure time between game updates and console lag (toggle).",ktimer)); commands.push_back(PluginCommand("ktimer","Measure time between game updates and console lag (toggle).",ktimer));
@ -47,17 +47,17 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
shutdown_flag = true; shutdown_flag = true;
while(!final_flag) while(!final_flag)
{ {
c->con.msleep(60); Core::getInstance().getConsole().msleep(60);
} }
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_onupdate ( Core * c ) DFhackCExport command_result plugin_onupdate ( color_ostream &out )
{ {
if(timering == true) if(timering == true)
{ {
@ -66,14 +66,14 @@ DFhackCExport command_result plugin_onupdate ( Core * c )
uint64_t delta = time2-timeLast; uint64_t delta = time2-timeLast;
// harmless potential data race here... // harmless potential data race here...
timeLast = time2; timeLast = time2;
c->con.print("Time delta = %d ms\n", delta); out.print("Time delta = %d ms\n", delta);
} }
if(trackmenu_flg) if(trackmenu_flg)
{ {
if (last_menu != df::global::ui->main.mode) if (last_menu != df::global::ui->main.mode)
{ {
last_menu = df::global::ui->main.mode; last_menu = df::global::ui->main.mode;
c->con.print("Menu: %d\n",last_menu); out.print("Menu: %d\n",last_menu);
} }
} }
if(trackpos_flg) if(trackpos_flg)
@ -85,7 +85,7 @@ DFhackCExport command_result plugin_onupdate ( Core * c )
last_designation[0] = desig_x; last_designation[0] = desig_x;
last_designation[1] = desig_y; last_designation[1] = desig_y;
last_designation[2] = desig_z; last_designation[2] = desig_z;
c->con.print("Designation: %d %d %d\n",desig_x, desig_y, desig_z); out.print("Designation: %d %d %d\n",desig_x, desig_y, desig_z);
} }
int mouse_x, mouse_y; int mouse_x, mouse_y;
Gui::getMousePos(mouse_x,mouse_y); Gui::getMousePos(mouse_x,mouse_y);
@ -93,13 +93,13 @@ DFhackCExport command_result plugin_onupdate ( Core * c )
{ {
last_mouse[0] = mouse_x; last_mouse[0] = mouse_x;
last_mouse[1] = mouse_y; last_mouse[1] = mouse_y;
c->con.print("Mouse: %d %d\n",mouse_x, mouse_y); out.print("Mouse: %d %d\n",mouse_x, mouse_y);
} }
} }
return CR_OK; return CR_OK;
} }
command_result trackmenu (Core * c, vector <string> & parameters) command_result trackmenu (color_ostream &out, vector <string> & parameters)
{ {
if(trackmenu_flg) if(trackmenu_flg)
{ {
@ -112,42 +112,41 @@ command_result trackmenu (Core * c, vector <string> & parameters)
{ {
trackmenu_flg = true; trackmenu_flg = true;
last_menu = df::global::ui->main.mode; last_menu = df::global::ui->main.mode;
c->con.print("Menu: %d\n",last_menu); out.print("Menu: %d\n",last_menu);
return CR_OK; return CR_OK;
} }
else else
{ {
c->con.printerr("Can't read menu state\n"); out.printerr("Can't read menu state\n");
return CR_FAILURE; return CR_FAILURE;
} }
} }
} }
command_result trackpos (Core * c, vector <string> & parameters) command_result trackpos (color_ostream &out, vector <string> & parameters)
{ {
trackpos_flg = !trackpos_flg; trackpos_flg = !trackpos_flg;
return CR_OK; return CR_OK;
} }
command_result colormods (Core * c, vector <string> & parameters) command_result colormods (color_ostream &out, vector <string> & parameters)
{ {
c->Suspend(); CoreSuspender suspend;
auto & vec = df::global::world->raws.creatures.alphabetic; auto & vec = df::global::world->raws.creatures.alphabetic;
for(int i = 0; i < vec.size();i++) for(int i = 0; i < vec.size();i++)
{ {
df::creature_raw* rawlion = vec[i]; df::creature_raw* rawlion = vec[i];
df::caste_raw * caste = rawlion->caste[0]; df::caste_raw * caste = rawlion->caste[0];
c->con.print("%s\nCaste addr 0x%x\n",rawlion->creature_id.c_str(), &caste->color_modifiers); out.print("%s\nCaste addr 0x%x\n",rawlion->creature_id.c_str(), &caste->color_modifiers);
for(int j = 0; j < caste->color_modifiers.size();j++) for(int j = 0; j < caste->color_modifiers.size();j++)
{ {
c->con.print("mod %d: 0x%x\n", j, caste->color_modifiers[j]); out.print("mod %d: 0x%x\n", j, caste->color_modifiers[j]);
} }
} }
c->Resume();
return CR_OK; return CR_OK;
} }
// FIXME: move cursor properly relative to view position // FIXME: move cursor properly relative to view position
command_result zoom (Core * c, vector <string> & parameters) command_result zoom (color_ostream &out, vector <string> & parameters)
{ {
if(parameters.size() < 3) if(parameters.size() < 3)
return CR_FAILURE; return CR_FAILURE;
@ -155,7 +154,7 @@ command_result zoom (Core * c, vector <string> & parameters)
int y = atoi( parameters[1].c_str()); int y = atoi( parameters[1].c_str());
int z = atoi( parameters[2].c_str()); int z = atoi( parameters[2].c_str());
int xi, yi, zi; int xi, yi, zi;
CoreSuspender cs (c); CoreSuspender cs;
if(Gui::getCursorCoords(xi, yi, zi)) if(Gui::getCursorCoords(xi, yi, zi))
{ {
Gui::setCursorCoords(x,y,z); Gui::setCursorCoords(x,y,z);
@ -163,7 +162,7 @@ command_result zoom (Core * c, vector <string> & parameters)
Gui::setViewCoords(x,y,z); Gui::setViewCoords(x,y,z);
} }
command_result ktimer (Core * c, vector <string> & parameters) command_result ktimer (color_ostream &out, vector <string> & parameters)
{ {
if(timering) if(timering)
{ {
@ -171,20 +170,22 @@ command_result ktimer (Core * c, vector <string> & parameters)
return CR_OK; return CR_OK;
} }
uint64_t timestart = GetTimeMs64(); uint64_t timestart = GetTimeMs64();
c->Suspend(); {
c->Resume(); CoreSuspender suspend;
}
uint64_t timeend = GetTimeMs64(); uint64_t timeend = GetTimeMs64();
c->con.print("Time to suspend = %d ms\n",timeend - timestart); out.print("Time to suspend = %d ms\n",timeend - timestart);
// harmless potential data race here... // harmless potential data race here...
timeLast = timeend; timeLast = timeend;
timering = true; timering = true;
return CR_OK; return CR_OK;
} }
command_result kittens (Core * c, vector <string> & parameters) command_result kittens (color_ostream &out, vector <string> & parameters)
{ {
final_flag = false; final_flag = false;
Console & con = c->con; assert(out.is_console());
Console &con = static_cast<Console&>(out);
// http://evilzone.org/creative-arts/nyan-cat-ascii/ // http://evilzone.org/creative-arts/nyan-cat-ascii/
const char * nyan []= const char * nyan []=
{ {

@ -28,11 +28,11 @@ enum HEXVIEW_STATES
{ {
STATE_OFF,STATE_ON STATE_OFF,STATE_ON
}; };
command_result memview (Core * c, vector <string> & parameters); command_result memview (color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("memview"); DFHACK_PLUGIN("memview");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand("memview","Shows memory in real time. Params: adrr length refresh_rate. If addr==0 then stop viewing",memview)); commands.push_back(PluginCommand("memview","Shows memory in real time. Params: adrr length refresh_rate. If addr==0 then stop viewing",memview));
memdata.state=STATE_OFF; memdata.state=STATE_OFF;
@ -58,15 +58,13 @@ bool isAddr(uint32_t *trg,vector<t_memrange> & ranges)
return false; return false;
} }
void outputHex(uint8_t *buf,uint8_t *lbuf,size_t len,size_t start,Core *c,vector<t_memrange> & ranges) void outputHex(uint8_t *buf,uint8_t *lbuf,size_t len,size_t start,color_ostream &con,vector<t_memrange> & ranges)
{ {
Console &con=c->con;
const size_t page_size=16; const size_t page_size=16;
con.clear();
for(size_t i=0;i<len;i+=page_size) for(size_t i=0;i<len;i+=page_size)
{ {
con.gotoxy(1,i/page_size+1); //con.gotoxy(1,i/page_size+1);
con.print("0x%08X ",i+start); con.print("0x%08X ",i+start);
for(size_t j=0;(j<page_size) && (i+j<len);j++) for(size_t j=0;(j<page_size) && (i+j<len);j++)
{ {
@ -93,8 +91,6 @@ void outputHex(uint8_t *buf,uint8_t *lbuf,size_t len,size_t start,Core *c,vector
//con.print("\n"); //con.print("\n");
} }
con.print("\n"); con.print("\n");
con.flush();
} }
void Deinit() void Deinit()
{ {
@ -105,7 +101,7 @@ void Deinit()
delete [] memdata.lbuf; delete [] memdata.lbuf;
} }
} }
DFhackCExport command_result plugin_onupdate ( Core * c ) DFhackCExport command_result plugin_onupdate (color_ostream &out)
{ {
mymutex->lock(); mymutex->lock();
@ -114,7 +110,7 @@ DFhackCExport command_result plugin_onupdate ( Core * c )
mymutex->unlock(); mymutex->unlock();
return CR_OK; return CR_OK;
} }
//Console &con=c->con; //Console &con=out;
uint64_t time2 = GetTimeMs64(); uint64_t time2 = GetTimeMs64();
uint64_t delta = time2-timeLast; uint64_t delta = time2-timeLast;
@ -126,8 +122,8 @@ DFhackCExport command_result plugin_onupdate ( Core * c )
} }
timeLast = time2; timeLast = time2;
c->p->read(memdata.addr,memdata.len,memdata.buf); Core::getInstance().p->read(memdata.addr,memdata.len,memdata.buf);
outputHex(memdata.buf,memdata.lbuf,memdata.len,(size_t)memdata.addr,c,memdata.ranges); outputHex(memdata.buf,memdata.lbuf,memdata.len,(size_t)memdata.addr,out,memdata.ranges);
memcpy(memdata.lbuf, memdata.buf, memdata.len); memcpy(memdata.lbuf, memdata.buf, memdata.len);
if(memdata.refresh==0) if(memdata.refresh==0)
Deinit(); Deinit();
@ -135,10 +131,10 @@ DFhackCExport command_result plugin_onupdate ( Core * c )
return CR_OK; return CR_OK;
} }
command_result memview (Core * c, vector <string> & parameters) command_result memview (color_ostream &out, vector <string> & parameters)
{ {
mymutex->lock(); mymutex->lock();
c->p->getMemRanges(memdata.ranges); Core::getInstance().p->getMemRanges(memdata.ranges);
memdata.addr=(void *)convert(parameters[0],true); memdata.addr=(void *)convert(parameters[0],true);
if(memdata.addr==0) if(memdata.addr==0)
{ {
@ -156,7 +152,7 @@ command_result memview (Core * c, vector <string> & parameters)
isValid=true; isValid=true;
if(!isValid) if(!isValid)
{ {
c->con.printerr("Invalid address:%x\n",memdata.addr); out.printerr("Invalid address:%x\n",memdata.addr);
mymutex->unlock(); mymutex->unlock();
return CR_OK; return CR_OK;
} }
@ -176,11 +172,11 @@ command_result memview (Core * c, vector <string> & parameters)
uint8_t *buf,*lbuf; uint8_t *buf,*lbuf;
memdata.buf=new uint8_t[memdata.len]; memdata.buf=new uint8_t[memdata.len];
memdata.lbuf=new uint8_t[memdata.len]; memdata.lbuf=new uint8_t[memdata.len];
c->p->getMemRanges(memdata.ranges); Core::getInstance().p->getMemRanges(memdata.ranges);
mymutex->unlock(); mymutex->unlock();
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown (color_ostream &out)
{ {
mymutex->lock(); mymutex->lock();
Deinit(); Deinit();

@ -10,11 +10,11 @@ using std::vector;
using std::string; using std::string;
using namespace DFHack; using namespace DFHack;
command_result df_notes (Core * c, vector <string> & parameters); command_result df_notes (color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("notes"); DFHACK_PLUGIN("notes");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand("dumpnotes", commands.push_back(PluginCommand("dumpnotes",
"Dumps in-game notes", "Dumps in-game notes",
@ -22,30 +22,27 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
command_result df_notes (Core * c, vector <string> & parameters) command_result df_notes (color_ostream &con, vector <string> & parameters)
{ {
Console & con = c->con; CoreSuspender suspend;
c->Suspend();
DFHack::Notes * note_mod = c->getNotes(); DFHack::Notes * note_mod = Core::getInstance().getNotes();
std::vector<t_note*>* note_list = note_mod->notes; std::vector<t_note*>* note_list = note_mod->notes;
if (note_list == NULL) if (note_list == NULL)
{ {
con.printerr("Notes are not supported under this version of DF.\n"); con.printerr("Notes are not supported under this version of DF.\n");
c->Resume();
return CR_OK; return CR_OK;
} }
if (note_list->empty()) if (note_list->empty())
{ {
con << "There are no notes." << std::endl; con << "There are no notes." << std::endl;
c->Resume();
return CR_OK; return CR_OK;
} }
@ -71,6 +68,5 @@ command_result df_notes (Core * c, vector <string> & parameters)
con << std::endl; con << std::endl;
} }
c->Resume();
return CR_OK; return CR_OK;
} }

@ -17,12 +17,12 @@ using namespace DFHack;
using df::global::world; using df::global::world;
command_result df_regrass (Core * c, vector <string> & parameters) command_result df_regrass (color_ostream &out, vector <string> & parameters)
{ {
if (!parameters.empty()) if (!parameters.empty())
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
CoreSuspender suspend(c); CoreSuspender suspend;
int count = 0; int count = 0;
for (size_t i = 0; i < world->map.map_blocks.size(); i++) for (size_t i = 0; i < world->map.map_blocks.size(); i++)
@ -48,20 +48,20 @@ command_result df_regrass (Core * c, vector <string> & parameters)
} }
if (count) if (count)
c->con.print("Regrew %d tiles of grass.\n", count); out.print("Regrew %d tiles of grass.\n", count);
return CR_OK; return CR_OK;
} }
DFHACK_PLUGIN("regrass"); DFHACK_PLUGIN("regrass");
DFhackCExport command_result plugin_init (Core *c, std::vector<PluginCommand> &commands) DFhackCExport command_result plugin_init (color_ostream &out, std::vector<PluginCommand> &commands)
{ {
commands.clear(); commands.clear();
commands.push_back(PluginCommand("regrass", "Regrows all surface grass, restoring outdoor plant growth for pre-0.31.19 worlds.", df_regrass)); commands.push_back(PluginCommand("regrass", "Regrows all surface grass, restoring outdoor plant growth for pre-0.31.19 worlds.", df_regrass));
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }

@ -18,13 +18,13 @@ using df::global::world;
// Here go all the command declarations... // Here go all the command declarations...
// mostly to allow having the mandatory stuff on top of the file and commands on the bottom // mostly to allow having the mandatory stuff on top of the file and commands on the bottom
command_result tilesieve (Core * c, std::vector <std::string> & parameters); command_result tilesieve (color_ostream &out, std::vector <std::string> & parameters);
// A plugin must be able to return its name. This must correspond to the filename - skeleton.plug.so or skeleton.plug.dll // A plugin must be able to return its name. This must correspond to the filename - skeleton.plug.so or skeleton.plug.dll
DFHACK_PLUGIN("tilesieve"); DFHACK_PLUGIN("tilesieve");
// Mandatory init function. If you have some global state, create it here. // Mandatory init function. If you have some global state, create it here.
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
// Fill the command list with your commands. // Fill the command list with your commands.
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
@ -37,7 +37,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
} }
// This is called right before the plugin library is removed from memory. // This is called right before the plugin library is removed from memory.
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
@ -48,16 +48,16 @@ struct xyz
int z; int z;
}; };
command_result tilesieve(DFHack::Core * c, std::vector<std::string> & params) command_result tilesieve(color_ostream &out, std::vector<std::string> & params)
{ {
Console & con = c->con; CoreSuspender suspend;
CoreSuspender suspend(c);
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
c->con.print("Scanning.\n"); out.print("Scanning.\n");
std::set <df::tiletype> seen; std::set <df::tiletype> seen;
for (auto iter = world->map.map_blocks.begin(); iter != world->map.map_blocks.end(); iter++) for (auto iter = world->map.map_blocks.begin(); iter != world->map.map_blocks.end(); iter++)
{ {
@ -75,7 +75,7 @@ command_result tilesieve(DFHack::Core * c, std::vector<std::string> & params)
if(seen.count(tt)) if(seen.count(tt))
continue; continue;
seen.insert(tt); seen.insert(tt);
c->con.print("Found tile %x @ %d %d %d\n", tt, block->map_pos.x + x, block->map_pos.y + y, block->map_pos.z); out.print("Found tile %x @ %d %d %d\n", tt, block->map_pos.x + x, block->map_pos.y + y, block->map_pos.z);
} }
} }
return CR_OK; return CR_OK;

@ -24,14 +24,12 @@ struct t_vecTriplet
void * alloc_end; void * alloc_end;
}; };
command_result df_vectors (Core * c, command_result df_vectors (color_ostream &out, vector <string> & parameters);
vector <string> & parameters); command_result df_clearvec (color_ostream &out, vector <string> & parameters);
command_result df_clearvec (Core * c,
vector <string> & parameters);
DFHACK_PLUGIN("vectors"); DFHACK_PLUGIN("vectors");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand("vectors", commands.push_back(PluginCommand("vectors",
"Scan memory for vectors.\ "Scan memory for vectors.\
@ -45,7 +43,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
@ -94,11 +92,11 @@ static bool inAnyRange(vector<t_memrange> &ranges, void * ptr)
return false; return false;
} }
static bool getHeapRanges(Core * c, std::vector<t_memrange> &heap_ranges) static bool getHeapRanges(color_ostream &out, std::vector<t_memrange> &heap_ranges)
{ {
std::vector<t_memrange> ranges; std::vector<t_memrange> ranges;
c->p->getMemRanges(ranges); Core::getInstance().p->getMemRanges(ranges);
for (size_t i = 0; i < ranges.size(); i++) for (size_t i = 0; i < ranges.size(); i++)
{ {
@ -116,7 +114,7 @@ static bool getHeapRanges(Core * c, std::vector<t_memrange> &heap_ranges)
if (heap_ranges.empty()) if (heap_ranges.empty())
{ {
c->con << "No possible heap segments." << std::endl; out << "No possible heap segments." << std::endl;
return false; return false;
} }
@ -127,13 +125,13 @@ static bool getHeapRanges(Core * c, std::vector<t_memrange> &heap_ranges)
// COMMAND: vectors // COMMAND: vectors
//////////////////////////////////////// ////////////////////////////////////////
static void vectorsUsage(Console &con) static void vectorsUsage(color_ostream &con)
{ {
con << "Usage: vectors <start of scan address> <# bytes to scan>" con << "Usage: vectors <start of scan address> <# bytes to scan>"
<< std::endl; << std::endl;
} }
static void printVec(Console &con, const char* msg, t_vecTriplet *vec, static void printVec(color_ostream &con, const char* msg, t_vecTriplet *vec,
uint32_t start, uint32_t pos) uint32_t start, uint32_t pos)
{ {
uint32_t length = (int)vec->end - (int)vec->start; uint32_t length = (int)vec->end - (int)vec->start;
@ -143,10 +141,8 @@ static void printVec(Console &con, const char* msg, t_vecTriplet *vec,
msg, offset, pos, vec->start, length); msg, offset, pos, vec->start, length);
} }
command_result df_vectors (Core * c, vector <string> & parameters) command_result df_vectors (color_ostream &con, vector <string> & parameters)
{ {
Console & con = c->con;
if (parameters.size() != 2) if (parameters.size() != 2)
{ {
vectorsUsage(con); vectorsUsage(con);
@ -173,14 +169,13 @@ command_result df_vectors (Core * c, vector <string> & parameters)
while (start % 4 != 0) while (start % 4 != 0)
start++; start++;
c->Suspend(); CoreSuspender suspend;
std::vector<t_memrange> heap_ranges; std::vector<t_memrange> heap_ranges;
if (!getHeapRanges(c, heap_ranges)) if (!getHeapRanges(con, heap_ranges))
{ {
return CR_FAILURE; return CR_FAILURE;
c->Resume();
} }
bool startInRange = false; bool startInRange = false;
@ -208,7 +203,6 @@ command_result df_vectors (Core * c, vector <string> & parameters)
if (!startInRange) if (!startInRange)
{ {
con << "Address not in any memory range." << std::endl; con << "Address not in any memory range." << std::endl;
c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
@ -250,7 +244,6 @@ command_result df_vectors (Core * c, vector <string> & parameters)
} }
} // for (uint32_t pos = start; pos < end; pos += ptr_size) } // for (uint32_t pos = start; pos < end; pos += ptr_size)
c->Resume();
return CR_OK; return CR_OK;
} }
@ -258,17 +251,15 @@ command_result df_vectors (Core * c, vector <string> & parameters)
// COMMAND: clearvec // COMMAND: clearvec
//////////////////////////////////////// ////////////////////////////////////////
static void clearUsage(Console &con) static void clearUsage(color_ostream &con)
{ {
con << "Usage: clearvec <vector1 addr> [vector2 addr] ..." << std::endl; con << "Usage: clearvec <vector1 addr> [vector2 addr] ..." << std::endl;
con << "Address can be either for vector or pointer to vector." con << "Address can be either for vector or pointer to vector."
<< std::endl; << std::endl;
} }
command_result df_clearvec (Core * c, vector <string> & parameters) command_result df_clearvec (color_ostream &con, vector <string> & parameters)
{ {
Console & con = c->con;
if (parameters.size() == 0) if (parameters.size() == 0)
{ {
clearUsage(con); clearUsage(con);
@ -289,13 +280,12 @@ command_result df_clearvec (Core * c, vector <string> & parameters)
return CR_FAILURE; return CR_FAILURE;
} }
c->Suspend(); CoreSuspender suspend;
std::vector<t_memrange> heap_ranges; std::vector<t_memrange> heap_ranges;
if (!getHeapRanges(c, heap_ranges)) if (!getHeapRanges(con, heap_ranges))
{ {
c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
@ -356,6 +346,5 @@ command_result df_clearvec (Core * c, vector <string> & parameters)
con << addr_str << " set to zero length." << std::endl; con << addr_str << " set to zero length." << std::endl;
} // for (size_t i = 0; i < parameters.size(); i++) } // for (size_t i = 0; i < parameters.size(); i++)
c->Resume();
return CR_OK; return CR_OK;
} }

@ -19,12 +19,12 @@ using df::global::world;
DFHACK_PLUGIN("drybuckets"); DFHACK_PLUGIN("drybuckets");
command_result df_drybuckets (Core * c, vector <string> & parameters) command_result df_drybuckets (color_ostream &out, vector <string> & parameters)
{ {
if (!parameters.empty()) if (!parameters.empty())
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
CoreSuspender suspend(c); CoreSuspender suspend;
int dried_total = 0; int dried_total = 0;
for (size_t i = 0; i < world->items.all.size(); i++) for (size_t i = 0; i < world->items.all.size(); i++)
@ -37,17 +37,17 @@ command_result df_drybuckets (Core * c, vector <string> & parameters)
} }
} }
if (dried_total) if (dried_total)
c->con.print("Done. %d buckets of water marked for emptying.\n", dried_total); out.print("Done. %d buckets of water marked for emptying.\n", dried_total);
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand("drybuckets", "Removes water from buckets.", df_drybuckets)); commands.push_back(PluginCommand("drybuckets", "Removes water from buckets.", df_drybuckets));
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }

@ -32,12 +32,12 @@ using df::global::world;
// Here go all the command declarations... // Here go all the command declarations...
// mostly to allow having the mandatory stuff on top of the file and commands on the bottom // mostly to allow having the mandatory stuff on top of the file and commands on the bottom
command_result export_dwarves (Core * c, std::vector <std::string> & parameters); command_result export_dwarves (color_ostream &con, std::vector <std::string> & parameters);
DFHACK_PLUGIN("dwarfexport"); DFHACK_PLUGIN("dwarfexport");
// Mandatory init function. If you have some global state, create it here. // Mandatory init function. If you have some global state, create it here.
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init (color_ostream &con, std::vector <PluginCommand> &commands)
{ {
// Fill the command list with your commands. // Fill the command list with your commands.
commands.push_back(PluginCommand("dwarfexport", commands.push_back(PluginCommand("dwarfexport",
@ -48,7 +48,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
} }
// This is called right before the plugin library is removed from memory. // This is called right before the plugin library is removed from memory.
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown (color_ostream &con)
{ {
return CR_OK; return CR_OK;
} }
@ -86,7 +86,7 @@ static void element(const char* name, const uint32_t content, ostream& out, cons
out << extra_indent << " <" << name << ">" << content << "</" << name << ">" << endl; out << extra_indent << " <" << name << ">" << content << "</" << name << ">" << endl;
} }
static void printAttributes(Core* c, df::unit* cre, ostream& out) { static void printAttributes(color_ostream &con, df::unit* cre, ostream& out) {
out << " <Attributes>" << endl; out << " <Attributes>" << endl;
for (int i = 0; i < NUM_CREATURE_PHYSICAL_ATTRIBUTES; i++) { for (int i = 0; i < NUM_CREATURE_PHYSICAL_ATTRIBUTES; i++) {
element(physicals[i], cre->body.physical_attrs[i].unk1, out, " "); element(physicals[i], cre->body.physical_attrs[i].unk1, out, " ");
@ -101,7 +101,7 @@ static void printAttributes(Core* c, df::unit* cre, ostream& out) {
out << " </Attributes>" << endl; out << " </Attributes>" << endl;
} }
static void printTraits(Core* c, df::unit* cre, ostream& out) static void printTraits(color_ostream &con, df::unit* cre, ostream& out)
{ {
out << " <Traits>" << endl; out << " <Traits>" << endl;
@ -114,7 +114,7 @@ static void printTraits(Core* c, df::unit* cre, ostream& out)
"' value='" << s->traits[index] << "'>"; "' value='" << s->traits[index] << "'>";
//FIXME: needs reimplementing trait string generation //FIXME: needs reimplementing trait string generation
/* /*
string trait = c->vinfo->getTrait(i, s->traits[i]); string trait = con->vinfo->getTrait(i, s->traits[i]);
if (!trait.empty()) { if (!trait.empty()) {
out << trait.c_str(); out << trait.c_str();
} }
@ -139,7 +139,7 @@ static int32_t getCreatureAge(df::unit* cre)
return yearDifference; return yearDifference;
} }
static void printLabors(Core* c, df::unit* cre, ostream& out) static void printLabors(color_ostream &con, df::unit* cre, ostream& out)
{ {
// Using British spelling here, consistent with Runesmith // Using British spelling here, consistent with Runesmith
out << " <Labours>" << endl; out << " <Labours>" << endl;
@ -154,7 +154,7 @@ static void printLabors(Core* c, df::unit* cre, ostream& out)
out << " </Labours>" << endl; out << " </Labours>" << endl;
} }
static void printSkill(Core* c, df::unit_skill* skill, ostream& out) static void printSkill(color_ostream &con, df::unit_skill* skill, ostream& out)
{ {
out << " <Skill>" << endl; out << " <Skill>" << endl;
@ -164,7 +164,7 @@ static void printSkill(Core* c, df::unit_skill* skill, ostream& out)
out << " </Skill>" << endl; out << " </Skill>" << endl;
} }
static void printSkills(Core* c, df::unit* cre, ostream& out) static void printSkills(color_ostream &con, df::unit* cre, ostream& out)
{ {
std::vector<df::unit_skill* > vSkills = cre->status.current_soul->skills; std::vector<df::unit_skill* > vSkills = cre->status.current_soul->skills;
@ -172,7 +172,7 @@ static void printSkills(Core* c, df::unit* cre, ostream& out)
out << " <Skills>" << endl; out << " <Skills>" << endl;
for (int iCount = 0; iCount < vSkills.size(); iCount++) for (int iCount = 0; iCount < vSkills.size(); iCount++)
{ {
printSkill(c, vSkills.at(iCount), out); printSkill(con, vSkills.at(iCount), out);
} }
out << " </Skills>" << endl; out << " </Skills>" << endl;
@ -184,43 +184,43 @@ static void printSkills(Core* c, df::unit* cre, ostream& out)
// Sex // Sex
// Attributes // Attributes
// Traits // Traits
static void export_dwarf(Core* c, df::unit* cre, ostream& out) { static void export_dwarf(color_ostream &con, df::unit* cre, ostream& out) {
string info = cre->name.first_name; string info = cre->name.first_name;
info += " "; info += " ";
info += Translation::TranslateName(&cre->name, false); info += Translation::TranslateName(&cre->name, false);
info[0] = toupper(info[0]); info[0] = toupper(info[0]);
c->con.print("Exporting %s\n", info.c_str()); con.print("Exporting %s\n", info.c_str());
out << " <Creature>" << endl; out << " <Creature>" << endl;
element("Name", info.c_str(), out); element("Name", info.c_str(), out);
element("Nickname", cre->name.nickname.c_str(), out); element("Nickname", cre->name.nickname.c_str(), out);
element("Sex", cre->sex == 0 ? "Female" : "Male", out); element("Sex", cre->sex == 0 ? "Female" : "Male", out);
element("Age", getCreatureAge(cre), out); // Added age, active labors, and skills March 9, 2012 element("Age", getCreatureAge(cre), out); // Added age, active labors, and skills March 9, 2012
printAttributes(c, cre, out); printAttributes(con, cre, out);
printTraits(c, cre, out); printTraits(con, cre, out);
printLabors(c, cre, out); printLabors(con, cre, out);
printSkills(c, cre, out); printSkills(con, cre, out);
out << " </Creature>" << endl; out << " </Creature>" << endl;
} }
command_result export_dwarves (Core * c, std::vector <std::string> & parameters) command_result export_dwarves (color_ostream &con, std::vector <std::string> & parameters)
{ {
string filename; string filename;
if (parameters.size() == 1) { if (parameters.size() == 1) {
filename = parameters[0]; filename = parameters[0];
} else { } else {
c->con.print("export <filename>\n"); con.print("export <filename>\n");
return CR_OK; return CR_OK;
} }
ofstream outf(filename); ofstream outf(filename);
if (!outf) { if (!outf) {
c->con.printerr("Failed to open file %s\n", filename.c_str()); con.printerr("Failed to open file %s\n", filename.c_str());
return CR_FAILURE; return CR_FAILURE;
} }
c->Suspend(); CoreSuspender suspend;
uint32_t race = ui->race_id; uint32_t race = ui->race_id;
uint32_t civ = ui->civ_id; uint32_t civ = ui->civ_id;
@ -231,11 +231,10 @@ command_result export_dwarves (Core * c, std::vector <std::string> & parameters)
{ {
df::unit* cre = world->units.all[i]; df::unit* cre = world->units.all[i];
if (cre->race == race && cre->civ_id == civ) { if (cre->race == race && cre->civ_id == civ) {
export_dwarf(c, cre, outf); export_dwarf(con, cre, outf);
} }
} }
outf << "</Creatures>" << endl; outf << "</Creatures>" << endl;
c->Resume();
return CR_OK; return CR_OK;
} }

@ -18,14 +18,14 @@ using df::global::ui;
// dfhack interface // dfhack interface
DFHACK_PLUGIN("fastdwarf"); DFHACK_PLUGIN("fastdwarf");
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
static int enable_fastdwarf; static int enable_fastdwarf;
DFhackCExport command_result plugin_onupdate ( Core * c ) DFhackCExport command_result plugin_onupdate ( color_ostream &out )
{ {
if (!enable_fastdwarf) if (!enable_fastdwarf)
return CR_OK; return CR_OK;
@ -43,7 +43,7 @@ DFhackCExport command_result plugin_onupdate ( Core * c )
return CR_OK; return CR_OK;
} }
static command_result fastdwarf (Core * c, vector <string> & parameters) static command_result fastdwarf (color_ostream &out, vector <string> & parameters)
{ {
if (parameters.size() == 1 && (parameters[0] == "0" || parameters[0] == "1")) if (parameters.size() == 1 && (parameters[0] == "0" || parameters[0] == "1"))
{ {
@ -51,11 +51,11 @@ static command_result fastdwarf (Core * c, vector <string> & parameters)
enable_fastdwarf = 0; enable_fastdwarf = 0;
else else
enable_fastdwarf = 1; enable_fastdwarf = 1;
c->con.print("fastdwarf %sactivated.\n", (enable_fastdwarf ? "" : "de")); out.print("fastdwarf %sactivated.\n", (enable_fastdwarf ? "" : "de"));
} }
else else
{ {
c->con.print("Makes your minions move at ludicrous speeds.\n" out.print("Makes your minions move at ludicrous speeds.\n"
"Activate with 'fastdwarf 1', deactivate with 'fastdwarf 0'.\n" "Activate with 'fastdwarf 1', deactivate with 'fastdwarf 0'.\n"
"Current state: %d.\n", enable_fastdwarf); "Current state: %d.\n", enable_fastdwarf);
} }
@ -63,7 +63,7 @@ static command_result fastdwarf (Core * c, vector <string> & parameters)
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_init ( Core * c, 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",
"enable/disable fastdwarf (parameter=0/1)", "enable/disable fastdwarf (parameter=0/1)",

@ -21,13 +21,13 @@ using namespace df::enums;
typedef void (*checkTile)(DFCoord, MapExtras::MapCache &); typedef void (*checkTile)(DFCoord, MapExtras::MapCache &);
//Forward Declarations for Commands //Forward Declarations for Commands
command_result filltraffic(Core * c, std::vector<std::string> & params); command_result filltraffic(color_ostream &out, std::vector<std::string> & params);
command_result alltraffic(Core * c, std::vector<std::string> & params); command_result alltraffic(color_ostream &out, std::vector<std::string> & params);
//Forward Declarations for Utility Functions //Forward Declarations for Utility Functions
command_result setAllMatching(Core * c, checkTile checkProc, command_result setAllMatching(color_ostream &out, checkTile checkProc,
DFCoord minCoord = DFCoord(0, 0, 0), DFCoord minCoord = DFCoord(0, 0, 0),
DFCoord maxCoord = DFCoord(0xFFFF, 0xFFFF, 0xFFFF)); DFCoord maxCoord = DFCoord(0xFFFF, 0xFFFF, 0xFFFF));
void allHigh(DFCoord coord, MapExtras::MapCache & map); void allHigh(DFCoord coord, MapExtras::MapCache & map);
void allNormal(DFCoord coord, MapExtras::MapCache & map); void allNormal(DFCoord coord, MapExtras::MapCache & map);
@ -36,7 +36,7 @@ void allRestricted(DFCoord coord, MapExtras::MapCache & map);
DFHACK_PLUGIN("filltraffic"); DFHACK_PLUGIN("filltraffic");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"filltraffic","Flood-fill with selected traffic designation from cursor", "filltraffic","Flood-fill with selected traffic designation from cursor",
@ -69,12 +69,12 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
command_result filltraffic(Core * c, std::vector<std::string> & params) command_result filltraffic(color_ostream &out, std::vector<std::string> & params)
{ {
// HOTKEY COMMAND; CORE ALREADY SUSPENDED // HOTKEY COMMAND; CORE ALREADY SUSPENDED
@ -117,7 +117,7 @@ command_result filltraffic(Core * c, std::vector<std::string> & params)
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
@ -128,7 +128,7 @@ command_result filltraffic(Core * c, std::vector<std::string> & params)
Gui::getCursorCoords(cx,cy,cz); Gui::getCursorCoords(cx,cy,cz);
while(cx == -30000) while(cx == -30000)
{ {
c->con.printerr("Cursor is not active.\n"); out.printerr("Cursor is not active.\n");
return CR_FAILURE; return CR_FAILURE;
} }
@ -145,29 +145,29 @@ command_result filltraffic(Core * c, std::vector<std::string> & params)
source = (df::tile_traffic)des.bits.traffic; source = (df::tile_traffic)des.bits.traffic;
if(source == target) if(source == target)
{ {
c->con.printerr("This tile is already set to the target traffic type.\n"); out.printerr("This tile is already set to the target traffic type.\n");
return CR_FAILURE; return CR_FAILURE;
} }
if(isWallTerrain(tt)) if(isWallTerrain(tt))
{ {
c->con.printerr("This tile is a wall. Please select a passable tile.\n"); out.printerr("This tile is a wall. Please select a passable tile.\n");
return CR_FAILURE; return CR_FAILURE;
} }
if(checkpit && isOpenTerrain(tt)) if(checkpit && isOpenTerrain(tt))
{ {
c->con.printerr("This tile is a hole. Please select a passable tile.\n"); out.printerr("This tile is a hole. Please select a passable tile.\n");
return CR_FAILURE; return CR_FAILURE;
} }
if(checkbuilding && oc.bits.building) if(checkbuilding && oc.bits.building)
{ {
c->con.printerr("This tile contains a building. Please select an empty tile.\n"); out.printerr("This tile contains a building. Please select an empty tile.\n");
return CR_FAILURE; return CR_FAILURE;
} }
c->con.print("%d/%d/%d ... FILLING!\n", cx,cy,cz); out.print("%d/%d/%d ... FILLING!\n", cx,cy,cz);
//Naive four-way or six-way flood fill with possible tiles on a stack. //Naive four-way or six-way flood fill with possible tiles on a stack.
stack <DFCoord> flood; stack <DFCoord> flood;
@ -236,7 +236,7 @@ command_result filltraffic(Core * c, std::vector<std::string> & params)
enum e_checktype {no_check, check_equal, check_nequal}; enum e_checktype {no_check, check_equal, check_nequal};
command_result alltraffic(Core * c, std::vector<std::string> & params) command_result alltraffic(color_ostream &out, std::vector<std::string> & params)
{ {
void (*proc)(DFCoord, MapExtras::MapCache &) = allNormal; void (*proc)(DFCoord, MapExtras::MapCache &) = allNormal;
@ -262,22 +262,22 @@ command_result alltraffic(Core * c, std::vector<std::string> & params)
} }
} }
return setAllMatching(c, proc); return setAllMatching(out, proc);
} }
//Helper function for writing new functions that check every tile on the map. //Helper function for writing new functions that check every tile on the map.
//newTraffic is the traffic designation to set. //newTraffic is the traffic designation to set.
//check takes a coordinate and the map cache as arguments, and returns true if the criteria is met. //check takes a coordinate and the map cache as arguments, and returns true if the criteria is met.
//minCoord and maxCoord can be used to specify a bounding cube. //minCoord and maxCoord can be used to specify a bounding cube.
command_result setAllMatching(Core * c, checkTile checkProc, command_result setAllMatching(color_ostream &out, checkTile checkProc,
DFCoord minCoord, DFCoord maxCoord) DFCoord minCoord, DFCoord maxCoord)
{ {
//Initialization. //Initialization.
CoreSuspender suspend(c); CoreSuspender suspend;
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
@ -295,23 +295,23 @@ command_result setAllMatching(Core * c, checkTile checkProc,
//Check minimum co-ordinates against maximum map size //Check minimum co-ordinates against maximum map size
if (minCoord.x > maxCoord.x) if (minCoord.x > maxCoord.x)
{ {
c->con.printerr("Minimum x coordinate is greater than maximum x coordinate.\n"); out.printerr("Minimum x coordinate is greater than maximum x coordinate.\n");
return CR_FAILURE; return CR_FAILURE;
} }
if (minCoord.y > maxCoord.y) if (minCoord.y > maxCoord.y)
{ {
c->con.printerr("Minimum y coordinate is greater than maximum y coordinate.\n"); out.printerr("Minimum y coordinate is greater than maximum y coordinate.\n");
return CR_FAILURE; return CR_FAILURE;
} }
if (minCoord.z > maxCoord.y) if (minCoord.z > maxCoord.y)
{ {
c->con.printerr("Minimum z coordinate is greater than maximum z coordinate.\n"); out.printerr("Minimum z coordinate is greater than maximum z coordinate.\n");
return CR_FAILURE; return CR_FAILURE;
} }
MapExtras::MapCache MCache; MapExtras::MapCache MCache;
c->con.print("Setting traffic...\n"); out.print("Setting traffic...\n");
//Loop through every single tile //Loop through every single tile
for(uint32_t x = minCoord.x; x <= maxCoord.x; x++) for(uint32_t x = minCoord.x; x <= maxCoord.x; x++)
@ -327,7 +327,7 @@ command_result setAllMatching(Core * c, checkTile checkProc,
} }
MCache.WriteAll(); MCache.WriteAll();
c->con.print("Complete!\n"); out.print("Complete!\n");
return CR_OK; return CR_OK;
} }

@ -20,12 +20,13 @@ using namespace df::enums;
using df::global::world; using df::global::world;
command_result df_fixdiplomats (Core *c, vector<string> &parameters) command_result df_fixdiplomats (color_ostream &out, vector<string> &parameters)
{ {
if (!parameters.empty()) if (!parameters.empty())
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
CoreSuspender suspend(c); CoreSuspender suspend;
int checked = 0, fixed = 0; int checked = 0, fixed = 0;
for (int i = 0; i < world->entities.all.size(); i++) for (int i = 0; i < world->entities.all.size(); i++)
{ {
@ -120,16 +121,17 @@ command_result df_fixdiplomats (Core *c, vector<string> &parameters)
if (update || assign) if (update || assign)
fixed++; fixed++;
} }
c->con.print("Fixed %d of %d civilizations to enable tree cap diplomacy.\n", fixed, checked); out.print("Fixed %d of %d civilizations to enable tree cap diplomacy.\n", fixed, checked);
return CR_OK; return CR_OK;
} }
command_result df_fixmerchants (Core *c, vector<string> &parameters) command_result df_fixmerchants (color_ostream &out, vector<string> &parameters)
{ {
if (!parameters.empty()) if (!parameters.empty())
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
CoreSuspender suspend(c); CoreSuspender suspend;
int checked = 0, fixed = 0; int checked = 0, fixed = 0;
for (int i = 0; i < world->entities.all.size(); i++) for (int i = 0; i < world->entities.all.size(); i++)
{ {
@ -220,13 +222,13 @@ command_result df_fixmerchants (Core *c, vector<string> &parameters)
if (update || assign) if (update || assign)
fixed++; fixed++;
} }
c->con.print("Fixed %d of %d civilizations to enable merchant nobility.\n", fixed, checked); out.print("Fixed %d of %d civilizations to enable merchant nobility.\n", fixed, checked);
return CR_OK; return CR_OK;
} }
DFHACK_PLUGIN("fixpositions"); DFHACK_PLUGIN("fixpositions");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"fixdiplomats", "Add Diplomat position to Elven civilizations for tree cap diplomacy.", "fixdiplomats", "Add Diplomat position to Elven civilizations for tree cap diplomacy.",
@ -237,7 +239,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }

@ -34,16 +34,16 @@ bool setTileMaterial(df::tiletype &tile, const df::tiletype_material mat)
return false; return false;
} }
command_result df_fixveins (Core * c, vector <string> & parameters) command_result df_fixveins (color_ostream &out, vector <string> & parameters)
{ {
if (parameters.size()) if (parameters.size())
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
CoreSuspender suspend(c); CoreSuspender suspend;
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
@ -90,15 +90,15 @@ command_result df_fixveins (Core * c, vector <string> & parameters)
} }
} }
if (mineral_removed || feature_removed) if (mineral_removed || feature_removed)
c->con.print("Removed invalid references from %i mineral inclusion and %i map feature tiles.\n", mineral_removed, feature_removed); out.print("Removed invalid references from %i mineral inclusion and %i map feature tiles.\n", mineral_removed, feature_removed);
if (mineral_added || feature_added) if (mineral_added || feature_added)
c->con.print("Restored missing references to %i mineral inclusion and %i map feature tiles.\n", mineral_added, feature_added); out.print("Restored missing references to %i mineral inclusion and %i map feature tiles.\n", mineral_added, feature_added);
return CR_OK; return CR_OK;
} }
DFHACK_PLUGIN("fixveins"); DFHACK_PLUGIN("fixveins");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand("fixveins", commands.push_back(PluginCommand("fixveins",
"Remove invalid references to mineral inclusions and restore missing ones.", "Remove invalid references to mineral inclusions and restore missing ones.",
@ -106,7 +106,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }

@ -17,12 +17,12 @@ using namespace df::enums;
using df::global::world; using df::global::world;
command_result df_flows (Core * c, vector <string> & parameters) command_result df_flows (color_ostream &out, vector <string> & parameters)
{ {
CoreSuspender suspend(c); CoreSuspender suspend;
int flow1 = 0, flow2 = 0, flowboth = 0, water = 0, magma = 0; int flow1 = 0, flow2 = 0, flowboth = 0, water = 0, magma = 0;
c->con.print("Counting flows and liquids ...\n"); out.print("Counting flows and liquids ...\n");
for (size_t i = 0; i < world->map.map_blocks.size(); i++) for (size_t i = 0; i < world->map.map_blocks.size(); i++)
{ {
@ -48,17 +48,17 @@ command_result df_flows (Core * c, vector <string> & parameters)
} }
} }
c->con.print("Blocks with liquid_1=true: %d\n", flow1); out.print("Blocks with liquid_1=true: %d\n", flow1);
c->con.print("Blocks with liquid_2=true: %d\n", flow2); out.print("Blocks with liquid_2=true: %d\n", flow2);
c->con.print("Blocks with both: %d\n", flowboth); out.print("Blocks with both: %d\n", flowboth);
c->con.print("Water tiles: %d\n", water); out.print("Water tiles: %d\n", water);
c->con.print("Magma tiles: %d\n", magma); out.print("Magma tiles: %d\n", magma);
return CR_OK; return CR_OK;
} }
DFHACK_PLUGIN("flows"); DFHACK_PLUGIN("flows");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand("flows", commands.push_back(PluginCommand("flows",
"Counts map blocks with flowing liquids.", "Counts map blocks with flowing liquids.",
@ -66,7 +66,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }

@ -17,7 +17,7 @@ using namespace DFHack;
using namespace df::enums; using namespace df::enums;
command_result follow (Core * c, std::vector <std::string> & parameters); command_result follow (color_ostream &out, std::vector <std::string> & parameters);
df::unit *followedUnit; df::unit *followedUnit;
int32_t prevX, prevY, prevZ; int32_t prevX, prevY, prevZ;
@ -25,12 +25,13 @@ uint8_t prevMenuWidth;
DFHACK_PLUGIN("follow"); DFHACK_PLUGIN("follow");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"follow", "Follow the selected unit until camera control is released", "follow", "Follow the selected unit until camera control is released",
follow, Gui::view_unit_hotkey, follow, Gui::view_unit_hotkey,
" Select a unit and run this plugin to make the camera follow it. Moving the camera yourself deactivates the plugin.\n" " Select a unit and run this plugin to make the camera follow it.\n"
" Moving the camera yourself deactivates the plugin.\n"
)); ));
followedUnit = 0; followedUnit = 0;
prevX=prevY=prevZ = -1; prevX=prevY=prevZ = -1;
@ -39,12 +40,12 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_onstatechange(Core* c, state_change_event event) DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event)
{ {
switch (event) { switch (event) {
case SC_GAME_LOADED: case SC_GAME_LOADED:
@ -60,11 +61,11 @@ DFhackCExport command_result plugin_onstatechange(Core* c, state_change_event ev
} }
DFhackCExport command_result plugin_onupdate ( Core * c ) DFhackCExport command_result plugin_onupdate ( color_ostream &out )
{ {
if (!followedUnit) return CR_OK; //Don't do anything if we're not following a unit if (!followedUnit) return CR_OK; //Don't do anything if we're not following a unit
DFHack::World *world =c->getWorld(); DFHack::World *world = Core::getInstance().getWorld();
if (world->ReadPauseState() && prevX==-1) return CR_OK; //Wait until the game is unpaused after first running "follow" to begin following if (world->ReadPauseState() && prevX==-1) return CR_OK; //Wait until the game is unpaused after first running "follow" to begin following
df::coord &unitPos = followedUnit->pos; df::coord &unitPos = followedUnit->pos;
@ -100,7 +101,7 @@ DFhackCExport command_result plugin_onupdate ( Core * c )
followedUnit = 0; followedUnit = 0;
prevX=prevY=prevZ = -1; prevX=prevY=prevZ = -1;
prevMenuWidth = 0; prevMenuWidth = 0;
c->con.print("No longer following anything.\n"); out.print("No longer following anything.\n");
return CR_OK; return CR_OK;
} }
@ -131,7 +132,7 @@ DFhackCExport command_result plugin_onupdate ( Core * c )
return CR_OK; return CR_OK;
} }
command_result follow (Core * c, std::vector <std::string> & parameters) command_result follow (color_ostream &out, std::vector <std::string> & parameters)
{ {
// HOTKEY COMMAND: CORE ALREADY SUSPENDED // HOTKEY COMMAND: CORE ALREADY SUSPENDED
@ -140,17 +141,17 @@ command_result follow (Core * c, std::vector <std::string> & parameters)
if (followedUnit) if (followedUnit)
{ {
c->con.print("No longer following previously selected unit.\n"); out.print("No longer following previously selected unit.\n");
followedUnit = 0; followedUnit = 0;
} }
followedUnit = Gui::getSelectedUnit(c); followedUnit = Gui::getSelectedUnit(out);
if (followedUnit) if (followedUnit)
{ {
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;
ss << ". Simply manually move the view to break the following.\n"; ss << ". Simply manually move the view to break the following.\n";
c->con.print(ss.str().c_str()); out.print(ss.str().c_str());
} }
else followedUnit = 0; else followedUnit = 0;
return CR_OK; return CR_OK;

@ -23,7 +23,7 @@ using namespace df::enums;
using df::global::world; using df::global::world;
command_result df_getplants (Core * c, vector <string> & parameters) command_result df_getplants (color_ostream &out, vector <string> & parameters)
{ {
string plantMatStr = ""; string plantMatStr = "";
set<int> plantIDs; set<int> plantIDs;
@ -50,21 +50,21 @@ command_result df_getplants (Core * c, vector <string> & parameters)
} }
if (treesonly && shrubsonly) if (treesonly && shrubsonly)
{ {
c->con.printerr("Cannot specify both -t and -s at the same time!\n"); out.printerr("Cannot specify both -t and -s at the same time!\n");
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
if (all && exclude) if (all && exclude)
{ {
c->con.printerr("Cannot specify both -a and -x at the same time!\n"); out.printerr("Cannot specify both -a and -x at the same time!\n");
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
if (all && plantNames.size()) if (all && plantNames.size())
{ {
c->con.printerr("Cannot specify -a along with plant IDs!\n"); out.printerr("Cannot specify -a along with plant IDs!\n");
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
CoreSuspender suspend(c); CoreSuspender suspend;
for (size_t i = 0; i < world->raws.plants.all.size(); i++) for (size_t i = 0; i < world->raws.plants.all.size(); i++)
{ {
@ -79,22 +79,22 @@ command_result df_getplants (Core * c, vector <string> & parameters)
} }
if (plantNames.size() > 0) if (plantNames.size() > 0)
{ {
c->con.printerr("Invalid plant ID(s):"); out.printerr("Invalid plant ID(s):");
for (set<string>::const_iterator it = plantNames.begin(); it != plantNames.end(); it++) for (set<string>::const_iterator it = plantNames.begin(); it != plantNames.end(); it++)
c->con.printerr(" %s", it->c_str()); out.printerr(" %s", it->c_str());
c->con.printerr("\n"); out.printerr("\n");
return CR_FAILURE; return CR_FAILURE;
} }
if (plantIDs.size() == 0) if (plantIDs.size() == 0)
{ {
c->con.print("Valid plant IDs:\n"); out.print("Valid plant IDs:\n");
for (size_t i = 0; i < world->raws.plants.all.size(); i++) for (size_t i = 0; i < world->raws.plants.all.size(); i++)
{ {
df::plant_raw *plant = world->raws.plants.all[i]; df::plant_raw *plant = world->raws.plants.all[i];
if (plant->flags.is_set(plant_raw_flags::GRASS)) if (plant->flags.is_set(plant_raw_flags::GRASS))
continue; continue;
c->con.print("* (%s) %s - %s\n", plant->flags.is_set(plant_raw_flags::TREE) ? "tree" : "shrub", plant->id.c_str(), plant->name.c_str()); out.print("* (%s) %s - %s\n", plant->flags.is_set(plant_raw_flags::TREE) ? "tree" : "shrub", plant->id.c_str(), plant->name.c_str());
} }
return CR_OK; return CR_OK;
} }
@ -144,13 +144,13 @@ command_result df_getplants (Core * c, vector <string> & parameters)
cur->flags.bits.designated = true; cur->flags.bits.designated = true;
} }
if (count) if (count)
c->con.print("Updated %d plant designations.\n", count); out.print("Updated %d plant designations.\n", count);
return CR_OK; return CR_OK;
} }
DFHACK_PLUGIN("getplants"); DFHACK_PLUGIN("getplants");
DFhackCExport command_result plugin_init ( Core * c, vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"getplants", "Cut down all of the specified trees or gather specified shrubs", "getplants", "Cut down all of the specified trees or gather specified shrubs",
@ -169,7 +169,7 @@ DFhackCExport command_result plugin_init ( Core * c, vector <PluginCommand> &com
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }

@ -14,12 +14,12 @@ using namespace df::enums;
using df::global::d_init; using df::global::d_init;
command_result twaterlvl(Core * c, vector <string> & parameters); command_result twaterlvl(color_ostream &out, vector <string> & parameters);
command_result tidlers(Core * c, vector <string> & parameters); command_result tidlers(color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("initflags"); DFHACK_PLUGIN("initflags");
DFhackCExport command_result plugin_init (Core *c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands)
{ {
if (d_init) { if (d_init) {
commands.push_back(PluginCommand("twaterlvl", "Toggle display of water/magma depth.", commands.push_back(PluginCommand("twaterlvl", "Toggle display of water/magma depth.",
@ -31,23 +31,23 @@ DFhackCExport command_result plugin_init (Core *c, std::vector <PluginCommand> &
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
command_result twaterlvl(Core * c, vector <string> & parameters) command_result twaterlvl(color_ostream &out, vector <string> & parameters)
{ {
// HOTKEY COMMAND: CORE ALREADY SUSPENDED // HOTKEY COMMAND: CORE ALREADY SUSPENDED
d_init->flags1.toggle(d_init_flags1::SHOW_FLOW_AMOUNTS); d_init->flags1.toggle(d_init_flags1::SHOW_FLOW_AMOUNTS);
c->con << "Toggled the display of water/magma depth." << endl; out << "Toggled the display of water/magma depth." << endl;
return CR_OK; return CR_OK;
} }
command_result tidlers(Core * c, vector <string> & parameters) command_result tidlers(color_ostream &out, vector <string> & parameters)
{ {
// HOTKEY COMMAND: CORE ALREADY SUSPENDED // HOTKEY COMMAND: CORE ALREADY SUSPENDED
d_init->idlers = ENUM_NEXT_ITEM(d_init_idlers, d_init->idlers); d_init->idlers = ENUM_NEXT_ITEM(d_init_idlers, d_init->idlers);
c->con << "Toggled the display of idlers to " << ENUM_KEY_STR(d_init_idlers, d_init->idlers) << endl; out << "Toggled the display of idlers to " << ENUM_KEY_STR(d_init_idlers, d_init->idlers) << endl;
return CR_OK; return CR_OK;
} }

@ -39,15 +39,15 @@ using df::global::job_next_id;
/* Plugin registration */ /* Plugin registration */
static bool job_material_hotkey(Core *c, df::viewscreen *top); static bool job_material_hotkey(df::viewscreen *top);
static command_result job_material(Core *c, vector <string> & parameters); static command_result job_material(color_ostream &out, vector <string> & parameters);
static command_result job_duplicate(Core *c, vector <string> & parameters); static command_result job_duplicate(color_ostream &out, vector <string> & parameters);
static command_result job_cmd(Core *c, vector <string> & parameters); static command_result job_cmd(color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("jobutils"); DFHACK_PLUGIN("jobutils");
DFhackCExport command_result plugin_init (Core *c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands)
{ {
if (!world || !ui) if (!world || !ui)
return CR_FAILURE; return CR_FAILURE;
@ -99,30 +99,30 @@ DFhackCExport command_result plugin_init (Core *c, std::vector <PluginCommand> &
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
/* UI state guards */ /* UI state guards */
static bool job_material_hotkey(Core *c, df::viewscreen *top) static bool job_material_hotkey(df::viewscreen *top)
{ {
return Gui::workshop_job_hotkey(c, top) || return Gui::workshop_job_hotkey(top) ||
Gui::build_selector_hotkey(c, top); Gui::build_selector_hotkey(top);
} }
/* job-material implementation */ /* job-material implementation */
static command_result job_material_in_job(Core *c, MaterialInfo &new_mat) static command_result job_material_in_job(color_ostream &out, MaterialInfo &new_mat)
{ {
df::job *job = Gui::getSelectedWorkshopJob(c); df::job *job = Gui::getSelectedWorkshopJob(out);
if (!job) if (!job)
return CR_FAILURE; return CR_FAILURE;
if (!new_mat.isValid() || new_mat.type != 0) if (!new_mat.isValid() || new_mat.type != 0)
{ {
c->con.printerr("New job material isn't inorganic: %s\n", out.printerr("New job material isn't inorganic: %s\n",
new_mat.toString().c_str()); new_mat.toString().c_str());
return CR_FAILURE; return CR_FAILURE;
} }
@ -131,7 +131,7 @@ static command_result job_material_in_job(Core *c, MaterialInfo &new_mat)
if (!cur_mat.isValid() || cur_mat.type != 0) if (!cur_mat.isValid() || cur_mat.type != 0)
{ {
c->con.printerr("Current job material isn't inorganic: %s\n", out.printerr("Current job material isn't inorganic: %s\n",
cur_mat.toString().c_str()); cur_mat.toString().c_str());
return CR_FAILURE; return CR_FAILURE;
} }
@ -139,13 +139,13 @@ static command_result job_material_in_job(Core *c, MaterialInfo &new_mat)
df::craft_material_class old_class = cur_mat.getCraftClass(); df::craft_material_class old_class = cur_mat.getCraftClass();
if (old_class == craft_material_class::None) if (old_class == craft_material_class::None)
{ {
c->con.printerr("Unexpected current material type: %s\n", out.printerr("Unexpected current material type: %s\n",
cur_mat.toString().c_str()); cur_mat.toString().c_str());
return CR_FAILURE; return CR_FAILURE;
} }
if (new_mat.getCraftClass() != old_class) if (new_mat.getCraftClass() != old_class)
{ {
c->con.printerr("New material %s does not satisfy requirement: %s\n", out.printerr("New material %s does not satisfy requirement: %s\n",
new_mat.toString().c_str(), ENUM_KEY_STR(craft_material_class, old_class)); new_mat.toString().c_str(), ENUM_KEY_STR(craft_material_class, old_class));
return CR_FAILURE; return CR_FAILURE;
} }
@ -157,14 +157,14 @@ static command_result job_material_in_job(Core *c, MaterialInfo &new_mat)
if (item_mat != cur_mat) if (item_mat != cur_mat)
{ {
c->con.printerr("Job item %d has different material: %s\n", out.printerr("Job item %d has different material: %s\n",
i, item_mat.toString().c_str()); i, item_mat.toString().c_str());
return CR_FAILURE; return CR_FAILURE;
} }
if (!new_mat.matches(*item)) if (!new_mat.matches(*item))
{ {
c->con.printerr("Job item %d requirements not satisfied by %s.\n", out.printerr("Job item %d requirements not satisfied by %s.\n",
i, new_mat.toString().c_str()); i, new_mat.toString().c_str());
return CR_FAILURE; return CR_FAILURE;
} }
@ -181,7 +181,7 @@ static command_result job_material_in_job(Core *c, MaterialInfo &new_mat)
item->mat_index = new_mat.index; item->mat_index = new_mat.index;
} }
c->con << "Applied material '" << new_mat.toString() out << "Applied material '" << new_mat.toString()
<< "' to job " << ENUM_KEY_STR(job_type,job->job_type) << endl; << "' to job " << ENUM_KEY_STR(job_type,job->job_type) << endl;
return CR_OK; return CR_OK;
} }
@ -212,7 +212,7 @@ static bool build_choice_matches(df::ui_build_item_req *req, df::build_req_choic
return false; return false;
} }
static command_result job_material_in_build(Core *c, MaterialInfo &new_mat) static command_result job_material_in_build(color_ostream &out, MaterialInfo &new_mat)
{ {
df::ui_build_selector *sel = ui_build_selector; df::ui_build_selector *sel = ui_build_selector;
df::ui_build_item_req *req = sel->requirements[ui_build_selector->req_index]; df::ui_build_item_req *req = sel->requirements[ui_build_selector->req_index];
@ -234,11 +234,11 @@ static command_result job_material_in_build(Core *c, MaterialInfo &new_mat)
} }
} }
c->con.printerr("Could not find material in list: %s\n", new_mat.toString().c_str()); out.printerr("Could not find material in list: %s\n", new_mat.toString().c_str());
return CR_FAILURE; return CR_FAILURE;
} }
static command_result job_material(Core * c, vector <string> & parameters) static command_result job_material(color_ostream &out, vector <string> & parameters)
{ {
// HOTKEY COMMAND: CORE ALREADY SUSPENDED // HOTKEY COMMAND: CORE ALREADY SUSPENDED
@ -246,7 +246,7 @@ static command_result job_material(Core * c, vector <string> & parameters)
if (parameters.size() == 1) if (parameters.size() == 1)
{ {
if (!new_mat.find(parameters[0])) { if (!new_mat.find(parameters[0])) {
c->con.printerr("Could not find material: %s\n", parameters[0].c_str()); out.printerr("Could not find material: %s\n", parameters[0].c_str());
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
} }
@ -254,21 +254,21 @@ static command_result job_material(Core * c, vector <string> & parameters)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
if (ui->main.mode == ui_sidebar_mode::QueryBuilding) if (ui->main.mode == ui_sidebar_mode::QueryBuilding)
return job_material_in_job(c, new_mat); return job_material_in_job(out, new_mat);
if (ui->main.mode == ui_sidebar_mode::Build) if (ui->main.mode == ui_sidebar_mode::Build)
return job_material_in_build(c, new_mat); return job_material_in_build(out, new_mat);
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
/* job-duplicate implementation */ /* job-duplicate implementation */
static command_result job_duplicate(Core * c, vector <string> & parameters) static command_result job_duplicate(color_ostream &out, vector <string> & parameters)
{ {
if (!parameters.empty()) if (!parameters.empty())
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
df::job *job = Gui::getSelectedWorkshopJob(c); df::job *job = Gui::getSelectedWorkshopJob(out);
if (!job) if (!job)
return CR_FAILURE; return CR_FAILURE;
@ -277,14 +277,14 @@ static command_result job_duplicate(Core * c, vector <string> & parameters)
job->job_type != job_type::CollectSand && job->job_type != job_type::CollectSand &&
job->job_type != job_type::CollectClay)) job->job_type != job_type::CollectClay))
{ {
c->con.printerr("Cannot duplicate job %s\n", ENUM_KEY_STR(job_type,job->job_type)); out.printerr("Cannot duplicate job %s\n", ENUM_KEY_STR(job_type,job->job_type));
return CR_FAILURE; return CR_FAILURE;
} }
df::building *building = world->selected_building; df::building *building = world->selected_building;
if (building->jobs.size() >= 10) if (building->jobs.size() >= 10)
{ {
c->con.printerr("Job list is already full.\n"); out.printerr("Job list is already full.\n");
return CR_FAILURE; return CR_FAILURE;
} }
@ -299,40 +299,40 @@ static command_result job_duplicate(Core * c, vector <string> & parameters)
/* Main job command implementation */ /* Main job command implementation */
static df::job_item *getJobItem(Core *c, df::job *job, std::string idx) static df::job_item *getJobItem(color_ostream &out, df::job *job, std::string idx)
{ {
if (!job) if (!job)
return NULL; return NULL;
int v = atoi(idx.c_str()); int v = atoi(idx.c_str());
if (v < 1 || v > job->job_items.size()) { if (v < 1 || v > job->job_items.size()) {
c->con.printerr("Invalid item index.\n"); out.printerr("Invalid item index.\n");
return NULL; return NULL;
} }
return job->job_items[v-1]; return job->job_items[v-1];
} }
static command_result job_cmd(Core * c, vector <string> & parameters) static command_result job_cmd(color_ostream &out, vector <string> & parameters)
{ {
CoreSuspender suspend(c); CoreSuspender suspend;
std::string cmd = (parameters.empty() ? "query" : parameters[0]); std::string cmd = (parameters.empty() ? "query" : parameters[0]);
if (cmd == "query" || cmd == "list") if (cmd == "query" || cmd == "list")
{ {
df::job *job = Gui::getSelectedJob(c); df::job *job = Gui::getSelectedJob(out);
if (!job) if (!job)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
if (cmd == "query") { if (cmd == "query") {
printJobDetails(c, job); printJobDetails(out, job);
} else { } else {
if (!Gui::workshop_job_hotkey(c, c->getTopViewscreen())) if (!Gui::workshop_job_hotkey(Core::getTopViewscreen()))
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
df::building *selected = world->selected_building; df::building *selected = world->selected_building;
for (size_t i = 0; i < selected->jobs.size(); i++) for (size_t i = 0; i < selected->jobs.size(); i++)
printJobDetails(c, selected->jobs[i]); printJobDetails(out, selected->jobs[i]);
} }
} }
else if (cmd == "item-material") else if (cmd == "item-material")
@ -340,8 +340,8 @@ static command_result job_cmd(Core * c, vector <string> & parameters)
if (parameters.size() != 3) if (parameters.size() != 3)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
df::job *job = Gui::getSelectedJob(c); df::job *job = Gui::getSelectedJob(out);
df::job_item *item = getJobItem(c, job, parameters[1]); df::job_item *item = getJobItem(out, job, parameters[1]);
if (!item) if (!item)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
@ -349,13 +349,13 @@ static command_result job_cmd(Core * c, vector <string> & parameters)
MaterialInfo minfo; MaterialInfo minfo;
if (!minfo.find(parameters[2])) { if (!minfo.find(parameters[2])) {
c->con.printerr("Could not find the specified material.\n"); out.printerr("Could not find the specified material.\n");
return CR_FAILURE; return CR_FAILURE;
} }
if (minfo.isValid() && !iinfo.matches(*item, &minfo)) { if (minfo.isValid() && !iinfo.matches(*item, &minfo)) {
c->con.printerr("Material does not match the requirements.\n"); out.printerr("Material does not match the requirements.\n");
printJobDetails(c, job); printJobDetails(out, job);
return CR_FAILURE; return CR_FAILURE;
} }
@ -370,13 +370,13 @@ static command_result job_cmd(Core * c, vector <string> & parameters)
item->mat_type = minfo.type; item->mat_type = minfo.type;
item->mat_index = minfo.index; item->mat_index = minfo.index;
c->con << "Job item updated." << endl; out << "Job item updated." << endl;
if (item->item_type < 0 && minfo.isValid()) if (item->item_type < 0 && minfo.isValid())
c->con.printerr("WARNING: Due to a probable bug, creature & plant material subtype\n" out.printerr("WARNING: Due to a probable bug, creature & plant material subtype\n"
" is ignored unless the item type is also specified.\n"); " is ignored unless the item type is also specified.\n");
printJobDetails(c, job); printJobDetails(out, job);
return CR_OK; return CR_OK;
} }
else if (cmd == "item-type") else if (cmd == "item-type")
@ -384,8 +384,8 @@ static command_result job_cmd(Core * c, vector <string> & parameters)
if (parameters.size() != 3) if (parameters.size() != 3)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
df::job *job = Gui::getSelectedJob(c); df::job *job = Gui::getSelectedJob(out);
df::job_item *item = getJobItem(c, job, parameters[1]); df::job_item *item = getJobItem(out, job, parameters[1]);
if (!item) if (!item)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
@ -393,21 +393,21 @@ static command_result job_cmd(Core * c, vector <string> & parameters)
MaterialInfo minfo(item); MaterialInfo minfo(item);
if (!iinfo.find(parameters[2])) { if (!iinfo.find(parameters[2])) {
c->con.printerr("Could not find the specified item type.\n"); out.printerr("Could not find the specified item type.\n");
return CR_FAILURE; return CR_FAILURE;
} }
if (iinfo.isValid() && !iinfo.matches(*item, &minfo)) { if (iinfo.isValid() && !iinfo.matches(*item, &minfo)) {
c->con.printerr("Item type does not match the requirements.\n"); out.printerr("Item type does not match the requirements.\n");
printJobDetails(c, job); printJobDetails(out, job);
return CR_FAILURE; return CR_FAILURE;
} }
item->item_type = iinfo.type; item->item_type = iinfo.type;
item->item_subtype = iinfo.subtype; item->item_subtype = iinfo.subtype;
c->con << "Job item updated." << endl; out << "Job item updated." << endl;
printJobDetails(c, job); printJobDetails(out, job);
return CR_OK; return CR_OK;
} }
else else

@ -26,11 +26,11 @@ typedef vector <df::coord> coord_vec;
CommandHistory liquids_hist; CommandHistory liquids_hist;
command_result df_liquids (Core * c, vector <string> & parameters); command_result df_liquids (color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("liquids"); DFHACK_PLUGIN("liquids");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
liquids_hist.load("liquids.history"); liquids_hist.load("liquids.history");
commands.clear(); commands.clear();
@ -38,7 +38,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
liquids_hist.save("liquids.history"); liquids_hist.save("liquids.history");
return CR_OK; return CR_OK;
@ -220,15 +220,18 @@ private:
Core *c_; Core *c_;
}; };
command_result df_liquids (Core * c, vector <string> & parameters) command_result df_liquids (color_ostream &out_, vector <string> & parameters)
{ {
int32_t x,y,z; int32_t x,y,z;
assert(out_.is_console());
Console &out = static_cast<Console&>(out_);
for(size_t i = 0; i < parameters.size();i++) for(size_t i = 0; i < parameters.size();i++)
{ {
if(parameters[i] == "help" || parameters[i] == "?") if(parameters[i] == "help" || parameters[i] == "?")
{ {
c->con.print("This tool allows placing magma, water and other similar things.\n" out.print("This tool allows placing magma, water and other similar things.\n"
"It is interactive and further help is available when you run it.\n" "It is interactive and further help is available when you run it.\n"
); );
return CR_OK; return CR_OK;
@ -237,14 +240,14 @@ command_result df_liquids (Core * c, vector <string> & parameters)
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
Brush * brush = new RectangleBrush(1,1); Brush * brush = new RectangleBrush(1,1);
string brushname = "point"; string brushname = "point";
bool end = false; bool end = false;
c->con << "Welcome to the liquid spawner.\nType 'help' or '?' for a list of available commands, 'q' to quit.\nPress return after a command to confirm." << std::endl; out << "Welcome to the liquid spawner.\nType 'help' or '?' for a list of available commands, 'q' to quit.\nPress return after a command to confirm." << std::endl;
string mode="magma"; string mode="magma";
string flowmode="f+"; string flowmode="f+";
@ -256,11 +259,11 @@ command_result df_liquids (Core * c, vector <string> & parameters)
string command = ""; string command = "";
std::stringstream str; std::stringstream str;
str <<"[" << mode << ":" << brushname << ":" << amount << ":" << flowmode << ":" << setmode << "]#"; str <<"[" << mode << ":" << brushname << ":" << amount << ":" << flowmode << ":" << setmode << "]#";
if(c->con.lineedit(str.str(),command,liquids_hist) == -1) if(out.lineedit(str.str(),command,liquids_hist) == -1)
return CR_FAILURE; return CR_FAILURE;
if(command=="help" || command == "?") if(command=="help" || command == "?")
{ {
c->con << "Modes:" << endl out << "Modes:" << endl
<< "m - switch to magma" << endl << "m - switch to magma" << endl
<< "w - switch to water" << endl << "w - switch to water" << endl
<< "o - make obsidian wall instead" << endl << "o - make obsidian wall instead" << endl
@ -333,21 +336,21 @@ command_result df_liquids (Core * c, vector <string> & parameters)
std::stringstream str; std::stringstream str;
CommandHistory range_hist; CommandHistory range_hist;
str << " :set range width<" << width << "># "; str << " :set range width<" << width << "># ";
c->con.lineedit(str.str(),command,range_hist); out.lineedit(str.str(),command,range_hist);
range_hist.add(command); range_hist.add(command);
width = command == "" ? width : atoi (command.c_str()); width = command == "" ? width : atoi (command.c_str());
if(width < 1) width = 1; if(width < 1) width = 1;
str.str(""); str.str("");
str << " :set range height<" << height << "># "; str << " :set range height<" << height << "># ";
c->con.lineedit(str.str(),command,range_hist); out.lineedit(str.str(),command,range_hist);
range_hist.add(command); range_hist.add(command);
height = command == "" ? height : atoi (command.c_str()); height = command == "" ? height : atoi (command.c_str());
if(height < 1) height = 1; if(height < 1) height = 1;
str.str(""); str.str("");
str << " :set range z-levels<" << z_levels << "># "; str << " :set range z-levels<" << z_levels << "># ";
c->con.lineedit(str.str(),command,range_hist); out.lineedit(str.str(),command,range_hist);
range_hist.add(command); range_hist.add(command);
z_levels = command == "" ? z_levels : atoi (command.c_str()); z_levels = command == "" ? z_levels : atoi (command.c_str());
if(z_levels < 1) z_levels = 1; if(z_levels < 1) z_levels = 1;
@ -378,7 +381,7 @@ command_result df_liquids (Core * c, vector <string> & parameters)
{ {
delete brush; delete brush;
brushname = "flood"; brushname = "flood";
brush = new FloodBrush(c); brush = new FloodBrush(&Core::getInstance());
} }
else if(command == "q") else if(command == "q")
{ {
@ -427,24 +430,25 @@ command_result df_liquids (Core * c, vector <string> & parameters)
amount = 7; amount = 7;
else if(command.empty()) else if(command.empty())
{ {
CoreSuspender suspend(c); CoreSuspender suspend;
do do
{ {
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con << "Can't see any DF map loaded." << endl; out << "Can't see any DF map loaded." << endl;
break;; break;;
} }
if(!Gui::getCursorCoords(x,y,z)) if(!Gui::getCursorCoords(x,y,z))
{ {
c->con << "Can't get cursor coords! Make sure you have a cursor active in DF." << endl; out << "Can't get cursor coords! Make sure you have a cursor active in DF." << endl;
break; break;
} }
c->con << "cursor coords: " << x << "/" << y << "/" << z << endl; out << "cursor coords: " << x << "/" << y << "/" << z << endl;
MapCache mcache; MapCache mcache;
DFHack::DFCoord cursor(x,y,z); DFHack::DFCoord cursor(x,y,z);
coord_vec all_tiles = brush->points(mcache,cursor); coord_vec all_tiles = brush->points(mcache,cursor);
c->con << "working..." << endl; out << "working..." << endl;
if(mode == "obsidian") if(mode == "obsidian")
{ {
coord_vec::iterator iter = all_tiles.begin(); coord_vec::iterator iter = all_tiles.begin();
@ -584,21 +588,21 @@ command_result df_liquids (Core * c, vector <string> & parameters)
} }
else else
{ {
c->con << "flow bit 1 = " << bflags.bits.liquid_1 << endl; out << "flow bit 1 = " << bflags.bits.liquid_1 << endl;
c->con << "flow bit 2 = " << bflags.bits.liquid_2 << endl; out << "flow bit 2 = " << bflags.bits.liquid_2 << endl;
} }
biter ++; biter ++;
} }
} }
if(mcache.WriteAll()) if(mcache.WriteAll())
c->con << "OK" << endl; out << "OK" << endl;
else else
c->con << "Something failed horribly! RUN!" << endl; out << "Something failed horribly! RUN!" << endl;
} while (0); } while (0);
} }
else else
{ {
c->con << command << " : unknown command." << endl; out << command << " : unknown command." << endl;
} }
} }
return CR_OK; return CR_OK;

@ -23,11 +23,11 @@ using df::global::world;
typedef std::vector<df::plant *> PlantList; typedef std::vector<df::plant *> PlantList;
command_result mapexport (Core * c, std::vector <std::string> & parameters); command_result mapexport (color_ostream &out, std::vector <std::string> & parameters);
DFHACK_PLUGIN("mapexport"); DFHACK_PLUGIN("mapexport");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
GOOGLE_PROTOBUF_VERIFY_VERSION; GOOGLE_PROTOBUF_VERIFY_VERSION;
commands.clear(); commands.clear();
@ -35,12 +35,12 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
command_result mapexport (Core * c, std::vector <std::string> & parameters) command_result mapexport (color_ostream &out, std::vector <std::string> & parameters)
{ {
bool showHidden = false; bool showHidden = false;
@ -50,7 +50,7 @@ command_result mapexport (Core * c, std::vector <std::string> & parameters)
{ {
if(parameters[i] == "help" || parameters[i] == "?") if(parameters[i] == "help" || parameters[i] == "?")
{ {
c->con.print("Exports the currently visible map to a file.\n" out.print("Exports the currently visible map to a file.\n"
"Usage: mapexport [options] <filename>\n" "Usage: mapexport [options] <filename>\n"
"Example: mapexport all embark.dfmap\n" "Example: mapexport all embark.dfmap\n"
"Options:\n" "Options:\n"
@ -65,32 +65,30 @@ command_result mapexport (Core * c, std::vector <std::string> & parameters)
} }
} }
CoreSuspender suspend;
uint32_t x_max=0, y_max=0, z_max=0; uint32_t x_max=0, y_max=0, z_max=0;
c->Suspend();
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
if (parameters.size() < filenameParameter) if (parameters.size() < filenameParameter)
{ {
c->con.printerr("Please supply a filename.\n"); out.printerr("Please supply a filename.\n");
c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
std::string filename = parameters[filenameParameter-1]; std::string filename = parameters[filenameParameter-1];
if (filename.rfind(".dfmap") == std::string::npos) filename += ".dfmap"; if (filename.rfind(".dfmap") == std::string::npos) filename += ".dfmap";
c->con << "Writing to " << filename << "..." << std::endl; out << "Writing to " << filename << "..." << std::endl;
std::ofstream output_file(filename, std::ios::out | std::ios::trunc | std::ios::binary); std::ofstream output_file(filename, std::ios::out | std::ios::trunc | std::ios::binary);
if (!output_file.is_open()) if (!output_file.is_open())
{ {
c->con.printerr("Couldn't open the output file.\n"); out.printerr("Couldn't open the output file.\n");
c->Resume();
return CR_FAILURE; return CR_FAILURE;
} }
ZeroCopyOutputStream *raw_output = new OstreamOutputStream(&output_file); ZeroCopyOutputStream *raw_output = new OstreamOutputStream(&output_file);
@ -101,16 +99,16 @@ command_result mapexport (Core * c, std::vector <std::string> & parameters)
Maps::getSize(x_max, y_max, z_max); Maps::getSize(x_max, y_max, z_max);
MapExtras::MapCache map; MapExtras::MapCache map;
DFHack::Materials *mats = c->getMaterials(); DFHack::Materials *mats = Core::getInstance().getMaterials();
c->con << "Writing map info..." << std::endl; out << "Writing map info..." << std::endl;
dfproto::Map protomap; dfproto::Map protomap;
protomap.set_x_size(x_max); protomap.set_x_size(x_max);
protomap.set_y_size(y_max); protomap.set_y_size(y_max);
protomap.set_z_size(z_max); protomap.set_z_size(z_max);
c->con << "Writing material dictionary..." << std::endl; out << "Writing material dictionary..." << std::endl;
for (size_t i = 0; i < world->raws.inorganics.size(); i++) for (size_t i = 0; i < world->raws.inorganics.size(); i++)
{ {
@ -142,7 +140,7 @@ command_result mapexport (Core * c, std::vector <std::string> & parameters)
DFHack::t_feature blockFeatureGlobal; DFHack::t_feature blockFeatureGlobal;
DFHack::t_feature blockFeatureLocal; DFHack::t_feature blockFeatureLocal;
c->con.print("Writing map block information"); out.print("Writing map block information");
for(uint32_t z = 0; z < z_max; z++) for(uint32_t z = 0; z < z_max; z++)
{ {
@ -150,7 +148,7 @@ command_result mapexport (Core * c, std::vector <std::string> & parameters)
{ {
for(uint32_t b_x = 0; b_x < x_max; b_x++) for(uint32_t b_x = 0; b_x < x_max; b_x++)
{ {
if (b_x == 0 && b_y == 0 && z % 10 == 0) c->con.print("."); if (b_x == 0 && b_y == 0 && z % 10 == 0) out.print(".");
// Get the map block // Get the map block
df::coord2d blockCoord(b_x, b_y); df::coord2d blockCoord(b_x, b_y);
MapExtras::Block *b = map.BlockAt(DFHack::DFCoord(b_x, b_y, z)); MapExtras::Block *b = map.BlockAt(DFHack::DFCoord(b_x, b_y, z));
@ -282,7 +280,6 @@ command_result mapexport (Core * c, std::vector <std::string> & parameters)
delete raw_output; delete raw_output;
mats->Finish(); mats->Finish();
c->con.print("\nMap succesfully exported!\n"); out.print("\nMap succesfully exported!\n");
c->Resume();
return CR_OK; return CR_OK;
} }

@ -12,11 +12,11 @@ using namespace std;
using namespace DFHack; using namespace DFHack;
command_result mode (Core * c, vector <string> & parameters); command_result mode (color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("mode"); DFHACK_PLUGIN("mode");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.clear(); commands.clear();
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
@ -29,12 +29,12 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_onupdate ( Core * c ) DFhackCExport command_result plugin_onupdate ( color_ostream &out )
{ {
// add tracking here // add tracking here
return CR_OK; return CR_OK;
@ -94,8 +94,11 @@ void printCurrentModes(t_gamemodes gm, Console & con)
} }
} }
command_result mode (Core * c, vector <string> & parameters) command_result mode (color_ostream &out_, vector <string> & parameters)
{ {
assert(out_.is_console());
Console &out = static_cast<Console&>(out_);
string command = ""; string command = "";
bool set = false; bool set = false;
bool abuse = false; bool abuse = false;
@ -113,22 +116,28 @@ command_result mode (Core * c, vector <string> & parameters)
else else
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
c->Suspend();
World *world = c->getWorld(); World *world;
{
CoreSuspender suspend;
world = Core::getInstance().getWorld();
world->Start(); world->Start();
world->ReadGameMode(gm); world->ReadGameMode(gm);
c->Resume(); }
printCurrentModes(gm, c->con);
printCurrentModes(gm, out);
if(set) if(set)
{ {
if(!abuse) if(!abuse)
{ {
if( gm.g_mode == GAMEMODE_NONE || gm.g_type == GAMETYPE_VIEW_LEGENDS) if( gm.g_mode == GAMEMODE_NONE || gm.g_type == GAMETYPE_VIEW_LEGENDS)
{ {
c->con.printerr("It is not safe to set modes in menus.\n"); out.printerr("It is not safe to set modes in menus.\n");
return CR_FAILURE; return CR_FAILURE;
} }
c->con << "\nPossible choices:" << endl out << "\nPossible choices:" << endl
<< "0 = Fortress Mode" << endl << "0 = Fortress Mode" << endl
<< "1 = Adventurer Mode" << endl << "1 = Adventurer Mode" << endl
<< "2 = Arena Mode" << endl << "2 = Arena Mode" << endl
@ -140,7 +149,7 @@ command_result mode (Core * c, vector <string> & parameters)
string selected; string selected;
input_again: input_again:
CommandHistory hist; CommandHistory hist;
c->con.lineedit("Enter new mode: ",selected, hist); out.lineedit("Enter new mode: ",selected, hist);
if(selected == "c") if(selected == "c")
return CR_OK; return CR_OK;
const char * start = selected.c_str(); const char * start = selected.c_str();
@ -148,7 +157,7 @@ command_result mode (Core * c, vector <string> & parameters)
select = strtol(start, &end, 10); select = strtol(start, &end, 10);
if(!end || end==start || select > 4) if(!end || end==start || select > 4)
{ {
c->con.printerr("This is not a valid selection.\n"); out.printerr("This is not a valid selection.\n");
goto input_again; goto input_again;
} }
switch(select) switch(select)
@ -179,21 +188,24 @@ command_result mode (Core * c, vector <string> & parameters)
{ {
CommandHistory hist; CommandHistory hist;
string selected; string selected;
c->con.lineedit("Enter new game mode number (c for exit): ",selected, hist); out.lineedit("Enter new game mode number (c for exit): ",selected, hist);
if(selected == "c") if(selected == "c")
return CR_OK; return CR_OK;
const char * start = selected.c_str(); const char * start = selected.c_str();
gm.g_mode = (GameMode) strtol(start, 0, 10); gm.g_mode = (GameMode) strtol(start, 0, 10);
c->con.lineedit("Enter new game type number (c for exit): ",selected, hist); out.lineedit("Enter new game type number (c for exit): ",selected, hist);
if(selected == "c") if(selected == "c")
return CR_OK; return CR_OK;
start = selected.c_str(); start = selected.c_str();
gm.g_type = (GameType) strtol(start, 0, 10); gm.g_type = (GameType) strtol(start, 0, 10);
} }
c->Suspend();
{
CoreSuspender suspend;
world->WriteGameMode(gm); world->WriteGameMode(gm);
c->Resume(); }
c->con << endl;
out << endl;
} }
return CR_OK; return CR_OK;
} }

@ -20,13 +20,13 @@ using std::string;
using namespace DFHack; using namespace DFHack;
using df::global::world; using df::global::world;
command_result df_grow (Core * c, vector <string> & parameters); command_result df_grow (color_ostream &out, vector <string> & parameters);
command_result df_immolate (Core * c, vector <string> & parameters); command_result df_immolate (color_ostream &out, vector <string> & parameters);
command_result df_extirpate (Core * c, vector <string> & parameters); command_result df_extirpate (color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("plants"); DFHACK_PLUGIN("plants");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.clear(); commands.clear();
commands.push_back(PluginCommand("grow", "Grows saplings into trees (with active cursor, only the targetted one).", df_grow)); commands.push_back(PluginCommand("grow", "Grows saplings into trees (with active cursor, only the targetted one).", df_grow));
@ -35,7 +35,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
@ -81,13 +81,13 @@ static bool getoptions( vector <string> & parameters, bool & shrubs, bool & tree
* And he cursed the plants and trees for their bloodless wood, turning them into ash and smoldering ruin. * And he cursed the plants and trees for their bloodless wood, turning them into ash and smoldering ruin.
* Armok was pleased and great temples were built by the dwarves, for they shared his hatred for trees and plants. * Armok was pleased and great temples were built by the dwarves, for they shared his hatred for trees and plants.
*/ */
static command_result immolations (Core * c, do_what what, bool shrubs, bool trees, bool help) static command_result immolations (color_ostream &out, do_what what, bool shrubs, bool trees, bool help)
{ {
static const char * what1 = "destroys"; static const char * what1 = "destroys";
static const char * what2 = "burns"; static const char * what2 = "burns";
if(help) if(help)
{ {
c->con.print("Without any options, this command %s a plant under the cursor.\n" out.print("Without any options, this command %s a plant under the cursor.\n"
"Options:\n" "Options:\n"
"shrubs - affect all shrubs\n" "shrubs - affect all shrubs\n"
"trees - affect all trees\n" "trees - affect all trees\n"
@ -96,10 +96,10 @@ static command_result immolations (Core * c, do_what what, bool shrubs, bool tre
); );
return CR_OK; return CR_OK;
} }
CoreSuspender suspend(c); CoreSuspender suspend;
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
uint32_t x_max, y_max, z_max; uint32_t x_max, y_max, z_max;
@ -119,7 +119,7 @@ static command_result immolations (Core * c, do_what what, bool shrubs, bool tre
destroyed ++; destroyed ++;
} }
} }
c->con.print("Praise Armok!\n"); out.print("Praise Armok!\n");
} }
else else
{ {
@ -152,55 +152,55 @@ static command_result immolations (Core * c, do_what what, bool shrubs, bool tre
} }
else else
{ {
c->con.printerr("No mass destruction and no cursor...\n" ); out.printerr("No mass destruction and no cursor...\n" );
} }
} }
return CR_OK; return CR_OK;
} }
command_result df_immolate (Core * c, vector <string> & parameters) command_result df_immolate (color_ostream &out, vector <string> & parameters)
{ {
bool shrubs = false, trees = false, help = false; bool shrubs = false, trees = false, help = false;
if(getoptions(parameters,shrubs,trees,help)) if(getoptions(parameters,shrubs,trees,help))
{ {
return immolations(c,do_immolate,shrubs,trees, help); return immolations(out,do_immolate,shrubs,trees, help);
} }
else else
{ {
c->con.printerr("Invalid parameter!\n"); out.printerr("Invalid parameter!\n");
return CR_FAILURE; return CR_FAILURE;
} }
} }
command_result df_extirpate (Core * c, vector <string> & parameters) command_result df_extirpate (color_ostream &out, vector <string> & parameters)
{ {
bool shrubs = false, trees = false, help = false; bool shrubs = false, trees = false, help = false;
if(getoptions(parameters,shrubs,trees, help)) if(getoptions(parameters,shrubs,trees, help))
{ {
return immolations(c,do_extirpate,shrubs,trees, help); return immolations(out,do_extirpate,shrubs,trees, help);
} }
else else
{ {
c->con.printerr("Invalid parameter!\n"); out.printerr("Invalid parameter!\n");
return CR_FAILURE; return CR_FAILURE;
} }
} }
command_result df_grow (Core * c, vector <string> & parameters) command_result df_grow (color_ostream &out, vector <string> & parameters)
{ {
for(size_t i = 0; i < parameters.size();i++) for(size_t i = 0; i < parameters.size();i++)
{ {
if(parameters[i] == "help" || parameters[i] == "?") if(parameters[i] == "help" || parameters[i] == "?")
{ {
c->con.print("This command turns all living saplings into full-grown trees.\n"); out.print("This command turns all living saplings into full-grown trees.\n");
return CR_OK; return CR_OK;
} }
} }
CoreSuspender suspend(c); CoreSuspender suspend;
Console & con = c->con;
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
MapExtras::MapCache map; MapExtras::MapCache map;

@ -33,13 +33,13 @@ using namespace df::enums;
using df::global::world; using df::global::world;
using df::global::cursor; using df::global::cursor;
command_result df_probe (Core * c, vector <string> & parameters); command_result df_probe (color_ostream &out, vector <string> & parameters);
command_result df_cprobe (Core * c, vector <string> & parameters); command_result df_cprobe (color_ostream &out, vector <string> & parameters);
command_result df_bprobe (Core * c, vector <string> & parameters); command_result df_bprobe (color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("probe"); DFHACK_PLUGIN("probe");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.clear(); commands.clear();
commands.push_back(PluginCommand("probe", commands.push_back(PluginCommand("probe",
@ -54,20 +54,19 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
command_result df_cprobe (Core * c, vector <string> & parameters) command_result df_cprobe (color_ostream &out, vector <string> & parameters)
{ {
Console & con = c->con; CoreSuspender suspend;
CoreSuspender suspend(c);
int32_t cursorX, cursorY, cursorZ; int32_t cursorX, cursorY, cursorZ;
Gui::getCursorCoords(cursorX,cursorY,cursorZ); Gui::getCursorCoords(cursorX,cursorY,cursorZ);
if(cursorX == -30000) if(cursorX == -30000)
{ {
con.printerr("No cursor; place cursor over creature to probe.\n"); out.printerr("No cursor; place cursor over creature to probe.\n");
} }
else else
{ {
@ -76,7 +75,7 @@ command_result df_cprobe (Core * c, vector <string> & parameters)
df::unit * unit = world->units.all[i]; df::unit * unit = world->units.all[i];
if(unit->pos.x == cursorX && unit->pos.y == cursorY && unit->pos.z == cursorZ) if(unit->pos.x == cursorX && unit->pos.y == cursorY && unit->pos.z == cursorZ)
{ {
con.print("Creature %d, race %d (%x), civ %d (%x)\n", unit->id, unit->race, unit->race, unit->civ_id, unit->civ_id); out.print("Creature %d, race %d (%x), civ %d (%x)\n", unit->id, unit->race, unit->race, unit->civ_id, unit->civ_id);
break; break;
} }
} }
@ -84,29 +83,29 @@ command_result df_cprobe (Core * c, vector <string> & parameters)
return CR_OK; return CR_OK;
} }
command_result df_probe (Core * c, vector <string> & parameters) command_result df_probe (color_ostream &out, vector <string> & parameters)
{ {
//bool showBlock, showDesig, showOccup, showTile, showMisc; //bool showBlock, showDesig, showOccup, showTile, showMisc;
Console & con = c->con;
/* /*
if (!parseOptions(parameters, showBlock, showDesig, showOccup, if (!parseOptions(parameters, showBlock, showDesig, showOccup,
showTile, showMisc)) showTile, showMisc))
{ {
con.printerr("Unknown parameters!\n"); out.printerr("Unknown parameters!\n");
return CR_FAILURE; return CR_FAILURE;
} }
*/ */
CoreSuspender suspend(c); CoreSuspender suspend;
DFHack::Materials *Materials = Core::getInstance().getMaterials();
DFHack::Materials *Materials = c->getMaterials();
DFHack::VersionInfo* mem = c->vinfo;
std::vector<t_matglossInorganic> inorganic; std::vector<t_matglossInorganic> inorganic;
bool hasmats = Materials->CopyInorganicMaterials(inorganic); bool hasmats = Materials->CopyInorganicMaterials(inorganic);
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
MapExtras::MapCache mc; MapExtras::MapCache mc;
@ -118,7 +117,7 @@ command_result df_probe (Core * c, vector <string> & parameters)
Gui::getCursorCoords(cursorX,cursorY,cursorZ); Gui::getCursorCoords(cursorX,cursorY,cursorZ);
if(cursorX == -30000) if(cursorX == -30000)
{ {
con.printerr("No cursor; place cursor over tile to probe.\n"); out.printerr("No cursor; place cursor over tile to probe.\n");
return CR_FAILURE; return CR_FAILURE;
} }
DFCoord cursor (cursorX,cursorY,cursorZ); DFCoord cursor (cursorX,cursorY,cursorZ);
@ -131,17 +130,17 @@ command_result df_probe (Core * c, vector <string> & parameters)
MapExtras::Block * b = mc.BlockAt(cursor/16); MapExtras::Block * b = mc.BlockAt(cursor/16);
if(!b && !b->valid) if(!b && !b->valid)
{ {
con.printerr("No data.\n"); out.printerr("No data.\n");
return CR_OK; return CR_OK;
} }
mapblock40d & block = b->raw; mapblock40d & block = b->raw;
con.print("block addr: 0x%x\n\n", block.origin); out.print("block addr: 0x%x\n\n", block.origin);
/* /*
if (showBlock) if (showBlock)
{ {
con.print("block flags:\n"); out.print("block flags:\n");
print_bits<uint32_t>(block.blockflags.whole,con); print_bits<uint32_t>(block.blockflags.whole,out);
con.print("\n\n"); out.print("\n\n");
} }
*/ */
df::tiletype tiletype = mc.tiletypeAt(cursor); df::tiletype tiletype = mc.tiletypeAt(cursor);
@ -149,96 +148,96 @@ command_result df_probe (Core * c, vector <string> & parameters)
/* /*
if(showDesig) if(showDesig)
{ {
con.print("designation\n"); out.print("designation\n");
print_bits<uint32_t>(block.designation[tileX][tileY].whole, print_bits<uint32_t>(block.designation[tileX][tileY].whole,
con); out);
con.print("\n\n"); out.print("\n\n");
} }
if(showOccup) if(showOccup)
{ {
con.print("occupancy\n"); out.print("occupancy\n");
print_bits<uint32_t>(block.occupancy[tileX][tileY].whole, print_bits<uint32_t>(block.occupancy[tileX][tileY].whole,
con); out);
con.print("\n\n"); out.print("\n\n");
} }
*/ */
// tiletype // tiletype
con.print("tiletype: %d", tiletype); out.print("tiletype: %d", tiletype);
if(tileName(tiletype)) if(tileName(tiletype))
con.print(" = %s",tileName(tiletype)); out.print(" = %s",tileName(tiletype));
con.print("\n"); out.print("\n");
df::tiletype_shape shape = tileShape(tiletype); df::tiletype_shape shape = tileShape(tiletype);
df::tiletype_material material = tileMaterial(tiletype); df::tiletype_material material = tileMaterial(tiletype);
df::tiletype_special special = tileSpecial(tiletype); df::tiletype_special special = tileSpecial(tiletype);
df::tiletype_variant variant = tileVariant(tiletype); df::tiletype_variant variant = tileVariant(tiletype);
con.print("%-10s: %4d %s\n","Class" ,shape, out.print("%-10s: %4d %s\n","Class" ,shape,
ENUM_KEY_STR(tiletype_shape, shape)); ENUM_KEY_STR(tiletype_shape, shape));
con.print("%-10s: %4d %s\n","Material" , out.print("%-10s: %4d %s\n","Material" ,
material, ENUM_KEY_STR(tiletype_material, material)); material, ENUM_KEY_STR(tiletype_material, material));
con.print("%-10s: %4d %s\n","Special" , out.print("%-10s: %4d %s\n","Special" ,
special, ENUM_KEY_STR(tiletype_special, special)); special, ENUM_KEY_STR(tiletype_special, special));
con.print("%-10s: %4d %s\n" ,"Variant" , out.print("%-10s: %4d %s\n" ,"Variant" ,
variant, ENUM_KEY_STR(tiletype_variant, variant)); variant, ENUM_KEY_STR(tiletype_variant, variant));
con.print("%-10s: %s\n" ,"Direction", out.print("%-10s: %s\n" ,"Direction",
tileDirection(tiletype).getStr()); tileDirection(tiletype).getStr());
con.print("\n"); out.print("\n");
con.print("temperature1: %d U\n",mc.temperature1At(cursor)); out.print("temperature1: %d U\n",mc.temperature1At(cursor));
con.print("temperature2: %d U\n",mc.temperature2At(cursor)); out.print("temperature2: %d U\n",mc.temperature2At(cursor));
// biome, geolayer // biome, geolayer
con << "biome: " << des.bits.biome << std::endl; out << "biome: " << des.bits.biome << std::endl;
con << "geolayer: " << des.bits.geolayer_index out << "geolayer: " << des.bits.geolayer_index
<< std::endl; << std::endl;
int16_t base_rock = mc.baseMaterialAt(cursor); int16_t base_rock = mc.baseMaterialAt(cursor);
if(base_rock != -1) if(base_rock != -1)
{ {
con << "Layer material: " << dec << base_rock; out << "Layer material: " << dec << base_rock;
if(hasmats) if(hasmats)
con << " / " << inorganic[base_rock].id out << " / " << inorganic[base_rock].id
<< " / " << " / "
<< inorganic[base_rock].name << inorganic[base_rock].name
<< endl; << endl;
else else
con << endl; out << endl;
} }
int16_t vein_rock = mc.veinMaterialAt(cursor); int16_t vein_rock = mc.veinMaterialAt(cursor);
if(vein_rock != -1) if(vein_rock != -1)
{ {
con << "Vein material (final): " << dec << vein_rock; out << "Vein material (final): " << dec << vein_rock;
if(hasmats) if(hasmats)
con << " / " << inorganic[vein_rock].id out << " / " << inorganic[vein_rock].id
<< " / " << " / "
<< inorganic[vein_rock].name << inorganic[vein_rock].name
<< endl; << endl;
else else
con << endl; out << endl;
} }
// liquids // liquids
if(des.bits.flow_size) if(des.bits.flow_size)
{ {
if(des.bits.liquid_type == tile_liquid::Magma) if(des.bits.liquid_type == tile_liquid::Magma)
con <<"magma: "; out <<"magma: ";
else con <<"water: "; else out <<"water: ";
con << des.bits.flow_size << std::endl; out << des.bits.flow_size << std::endl;
} }
if(des.bits.flow_forbid) if(des.bits.flow_forbid)
con << "flow forbid" << std::endl; out << "flow forbid" << std::endl;
if(des.bits.pile) if(des.bits.pile)
con << "stockpile?" << std::endl; out << "stockpile?" << std::endl;
if(des.bits.rained) if(des.bits.rained)
con << "rained?" << std::endl; out << "rained?" << std::endl;
if(des.bits.smooth) if(des.bits.smooth)
con << "smooth?" << std::endl; out << "smooth?" << std::endl;
if(des.bits.water_salt) if(des.bits.water_salt)
con << "salty" << endl; out << "salty" << endl;
if(des.bits.water_stagnant) if(des.bits.water_stagnant)
con << "stagnant" << endl; out << "stagnant" << endl;
#define PRINT_FLAG( X ) con.print("%-16s= %c\n", #X , ( des.X ? 'Y' : ' ' ) ) #define PRINT_FLAG( X ) out.print("%-16s= %c\n", #X , ( des.X ? 'Y' : ' ' ) )
PRINT_FLAG( bits.hidden ); PRINT_FLAG( bits.hidden );
PRINT_FLAG( bits.light ); PRINT_FLAG( bits.light );
PRINT_FLAG( bits.outside ); PRINT_FLAG( bits.outside );
@ -254,37 +253,37 @@ command_result df_probe (Core * c, vector <string> & parameters)
PRINT_FLAG( bits.feature_local ); PRINT_FLAG( bits.feature_local );
if(local.type != -1) if(local.type != -1)
{ {
con.print("%-16s", ""); out.print("%-16s", "");
con.print(" %4d", block.local_feature); out.print(" %4d", block.local_feature);
con.print(" (%2d)", local.type); out.print(" (%2d)", local.type);
con.print(" addr 0x%X ", local.origin); out.print(" addr 0x%X ", local.origin);
con.print(" %s\n", sa_feature(local.type)); out.print(" %s\n", sa_feature(local.type));
} }
PRINT_FLAG( bits.feature_global ); PRINT_FLAG( bits.feature_global );
if(global.type != -1) if(global.type != -1)
{ {
con.print("%-16s", ""); out.print("%-16s", "");
con.print(" %4d", block.global_feature); out.print(" %4d", block.global_feature);
con.print(" (%2d)", global.type); out.print(" (%2d)", global.type);
con.print(" %s\n", sa_feature(global.type)); out.print(" %s\n", sa_feature(global.type));
} }
#undef PRINT_FLAG #undef PRINT_FLAG
con << "local feature idx: " << block.local_feature out << "local feature idx: " << block.local_feature
<< endl; << endl;
con << "global feature idx: " << block.global_feature out << "global feature idx: " << block.global_feature
<< endl; << endl;
con << "mystery: " << block.mystery << endl; out << "mystery: " << block.mystery << endl;
con << std::endl; out << std::endl;
return CR_OK; return CR_OK;
} }
command_result df_bprobe (Core * c, vector <string> & parameters) command_result df_bprobe (color_ostream &out, vector <string> & parameters)
{ {
CoreSuspender suspend(c); CoreSuspender suspend;
if(cursor->x == -30000) if(cursor->x == -30000)
{ {
c->con.printerr("No cursor; place cursor over tile to probe.\n"); out.printerr("No cursor; place cursor over tile to probe.\n");
return CR_FAILURE; return CR_FAILURE;
} }
@ -299,38 +298,38 @@ command_result df_bprobe (Core * c, vector <string> & parameters)
continue; continue;
string name; string name;
building.origin->getName(&name); building.origin->getName(&name);
c->con.print("Building %i - \"%s\" - type %s", building.origin->id, name.c_str(), ENUM_KEY_STR(building_type, building.type)); out.print("Building %i - \"%s\" - type %s", building.origin->id, name.c_str(), ENUM_KEY_STR(building_type, building.type));
switch (building.type) switch (building.type)
{ {
case building_type::Furnace: case building_type::Furnace:
c->con.print(", subtype %s", ENUM_KEY_STR(furnace_type, building.furnace_type)); out.print(", subtype %s", ENUM_KEY_STR(furnace_type, building.furnace_type));
if (building.furnace_type == furnace_type::Custom) if (building.furnace_type == furnace_type::Custom)
c->con.print(", custom type %i (%s)", building.custom_type, world->raws.buildings.all[building.custom_type]->code.c_str()); out.print(", custom type %i (%s)", building.custom_type, world->raws.buildings.all[building.custom_type]->code.c_str());
break; break;
case building_type::Workshop: case building_type::Workshop:
c->con.print(", subtype %s", ENUM_KEY_STR(workshop_type, building.workshop_type)); out.print(", subtype %s", ENUM_KEY_STR(workshop_type, building.workshop_type));
if (building.workshop_type == workshop_type::Custom) if (building.workshop_type == workshop_type::Custom)
c->con.print(", custom type %i (%s)", building.custom_type, world->raws.buildings.all[building.custom_type]->code.c_str()); out.print(", custom type %i (%s)", building.custom_type, world->raws.buildings.all[building.custom_type]->code.c_str());
break; break;
case building_type::Construction: case building_type::Construction:
c->con.print(", subtype %s", ENUM_KEY_STR(construction_type, building.construction_type)); out.print(", subtype %s", ENUM_KEY_STR(construction_type, building.construction_type));
break; break;
case building_type::Shop: case building_type::Shop:
c->con.print(", subtype %s", ENUM_KEY_STR(shop_type, building.shop_type)); out.print(", subtype %s", ENUM_KEY_STR(shop_type, building.shop_type));
break; break;
case building_type::SiegeEngine: case building_type::SiegeEngine:
c->con.print(", subtype %s", ENUM_KEY_STR(siegeengine_type, building.siegeengine_type)); out.print(", subtype %s", ENUM_KEY_STR(siegeengine_type, building.siegeengine_type));
break; break;
case building_type::Trap: case building_type::Trap:
c->con.print(", subtype %s", ENUM_KEY_STR(trap_type, building.trap_type)); out.print(", subtype %s", ENUM_KEY_STR(trap_type, building.trap_type));
break; break;
default: default:
if (building.subtype != -1) if (building.subtype != -1)
c->con.print(", subtype %i", building.subtype); out.print(", subtype %i", building.subtype);
break; break;
} }
c->con.print("\n"); out.print("\n");
} }
return CR_OK; return CR_OK;

@ -108,7 +108,7 @@ struct compare_pair_second
} }
}; };
static void printMatdata(DFHack::Console & con, const matdata &data) static void printMatdata(color_ostream &con, const matdata &data)
{ {
con << std::setw(9) << data.count; con << std::setw(9) << data.count;
@ -129,7 +129,7 @@ static int getValue(const df::plant_raw &info)
} }
template <typename T, template <typename> class P> template <typename T, template <typename> class P>
void printMats(DFHack::Console & con, MatMap &mat, std::vector<T*> &materials, bool show_value) void printMats(color_ostream &con, MatMap &mat, std::vector<T*> &materials, bool show_value)
{ {
unsigned int total = 0; unsigned int total = 0;
MatSorter sorting_vector; MatSorter sorting_vector;
@ -160,7 +160,7 @@ void printMats(DFHack::Console & con, MatMap &mat, std::vector<T*> &materials, b
con << ">>> TOTAL = " << total << std::endl << std::endl; con << ">>> TOTAL = " << total << std::endl << std::endl;
} }
void printVeins(DFHack::Console & con, MatMap &mat_map, void printVeins(color_ostream &con, MatMap &mat_map,
DFHack::Materials* mats, bool show_value) DFHack::Materials* mats, bool show_value)
{ {
MatMap ores; MatMap ores;
@ -189,11 +189,11 @@ void printVeins(DFHack::Console & con, MatMap &mat_map,
printMats<df::inorganic_raw, std::greater>(con, rest, world->raws.inorganics, show_value); printMats<df::inorganic_raw, std::greater>(con, rest, world->raws.inorganics, show_value);
} }
command_result prospector (Core * c, vector <string> & parameters); command_result prospector (color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("prospector"); DFHACK_PLUGIN("prospector");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.clear(); commands.clear();
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
@ -215,7 +215,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
@ -226,12 +226,12 @@ static coord2d biome_delta[] = {
coord2d(-1,-1), coord2d(0,-1), coord2d(1,-1) coord2d(-1,-1), coord2d(0,-1), coord2d(1,-1)
}; };
static command_result embark_prospector(DFHack::Core *c, df::viewscreen_choose_start_sitest *screen, static command_result embark_prospector(color_ostream &out, df::viewscreen_choose_start_sitest *screen,
bool showHidden, bool showValue) bool showHidden, bool showValue)
{ {
if (!world || !world->world_data) if (!world || !world->world_data)
{ {
c->con.printerr("World data is not available.\n"); out.printerr("World data is not available.\n");
return CR_FAILURE; return CR_FAILURE;
} }
@ -242,7 +242,7 @@ static command_result embark_prospector(DFHack::Core *c, df::viewscreen_choose_s
if (!cur_details) if (!cur_details)
{ {
c->con.printerr("Current region details are not available.\n"); out.printerr("Current region details are not available.\n");
return CR_FAILURE; return CR_FAILURE;
} }
@ -251,7 +251,7 @@ static command_result embark_prospector(DFHack::Core *c, df::viewscreen_choose_s
if (screen->biome_highlighted) if (screen->biome_highlighted)
{ {
c->con.print("Processing one embark tile of biome F%d.\n\n", screen->biome_idx+1); out.print("Processing one embark tile of biome F%d.\n\n", screen->biome_idx+1);
biomes[screen->biome_rgn[screen->biome_idx]]++; biomes[screen->biome_rgn[screen->biome_idx]]++;
} }
else else
@ -279,7 +279,7 @@ static command_result embark_prospector(DFHack::Core *c, df::viewscreen_choose_s
if (!geo_biome) if (!geo_biome)
{ {
c->con.printerr("Region geo-biome not found: (%d,%d)\n", bx, by); out.printerr("Region geo-biome not found: (%d,%d)\n", bx, by);
return CR_FAILURE; return CR_FAILURE;
} }
@ -340,21 +340,21 @@ static command_result embark_prospector(DFHack::Core *c, df::viewscreen_choose_s
} }
// Print the report // Print the report
c->con << "Layer materials:" << std::endl; out << "Layer materials:" << std::endl;
printMats<df::inorganic_raw, shallower>(c->con, layerMats, world->raws.inorganics, showValue); printMats<df::inorganic_raw, shallower>(out, layerMats, world->raws.inorganics, showValue);
if (showHidden) { if (showHidden) {
DFHack::Materials *mats = c->getMaterials(); DFHack::Materials *mats = Core::getInstance().getMaterials();
printVeins(c->con, veinMats, mats, showValue); printVeins(out, veinMats, mats, showValue);
mats->Finish(); mats->Finish();
} }
c->con << "Warning: the above data is only a very rough estimate." << std::endl; out << "Warning: the above data is only a very rough estimate." << std::endl;
return CR_OK; return CR_OK;
} }
command_result prospector (DFHack::Core * c, vector <string> & parameters) command_result prospector (color_ostream &con, vector <string> & parameters)
{ {
bool showHidden = false; bool showHidden = false;
bool showPlants = true; bool showPlants = true;
@ -362,7 +362,7 @@ command_result prospector (DFHack::Core * c, vector <string> & parameters)
bool showTemple = true; bool showTemple = true;
bool showValue = false; bool showValue = false;
bool showTube = false; bool showTube = false;
Console & con = c->con;
for(size_t i = 0; i < parameters.size();i++) for(size_t i = 0; i < parameters.size();i++)
{ {
if (parameters[i] == "all") if (parameters[i] == "all")
@ -380,15 +380,16 @@ command_result prospector (DFHack::Core * c, vector <string> & parameters)
else else
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
CoreSuspender suspend(c);
CoreSuspender suspend;
// Embark screen active: estimate using world geology data // Embark screen active: estimate using world geology data
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_choose_start_sitest, c->getTopViewscreen())) if (VIRTUAL_CAST_VAR(screen, df::viewscreen_choose_start_sitest, Core::getTopViewscreen()))
return embark_prospector(c, screen, showHidden, showValue); return embark_prospector(con, screen, showHidden, showValue);
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); con.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
@ -396,7 +397,7 @@ command_result prospector (DFHack::Core * c, vector <string> & parameters)
Maps::getSize(x_max, y_max, z_max); Maps::getSize(x_max, y_max, z_max);
MapExtras::MapCache map; MapExtras::MapCache map;
DFHack::Materials *mats = c->getMaterials(); DFHack::Materials *mats = Core::getInstance().getMaterials();
DFHack::t_feature blockFeatureGlobal; DFHack::t_feature blockFeatureGlobal;
DFHack::t_feature blockFeatureLocal; DFHack::t_feature blockFeatureLocal;

@ -28,11 +28,11 @@ using namespace df::enums;
using df::global::ui; using df::global::ui;
using df::global::world; using df::global::world;
static command_result rename(Core * c, vector <string> & parameters); static command_result rename(color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("rename"); DFHACK_PLUGIN("rename");
DFhackCExport command_result plugin_init (Core *c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.clear(); commands.clear();
if (world && ui) { if (world && ui) {
@ -49,7 +49,7 @@ DFhackCExport command_result plugin_init (Core *c, std::vector <PluginCommand> &
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
@ -79,9 +79,9 @@ static df::squad *getSquadByIndex(unsigned idx)
return df::squad::find(entity->squads[idx]); return df::squad::find(entity->squads[idx]);
} }
static command_result rename(Core * c, vector <string> &parameters) static command_result rename(color_ostream &out, vector <string> &parameters)
{ {
CoreSuspender suspend(c); CoreSuspender suspend;
string cmd; string cmd;
if (!parameters.empty()) if (!parameters.empty())
@ -96,7 +96,7 @@ static command_result rename(Core * c, vector <string> &parameters)
df::squad *squad = getSquadByIndex(id-1); df::squad *squad = getSquadByIndex(id-1);
if (!squad) { if (!squad) {
c->con.printerr("Couldn't find squad with index %d.\n", id); out.printerr("Couldn't find squad with index %d.\n", id);
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
@ -109,7 +109,7 @@ static command_result rename(Core * c, vector <string> &parameters)
int id = atoi(parameters[1].c_str()); int id = atoi(parameters[1].c_str());
if (id < 1 || id > 16) { if (id < 1 || id > 16) {
c->con.printerr("Invalid hotkey index\n"); out.printerr("Invalid hotkey index\n");
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
@ -120,7 +120,7 @@ static command_result rename(Core * c, vector <string> &parameters)
if (parameters.size() != 2) if (parameters.size() != 2)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
df::unit *unit = Gui::getSelectedUnit(c); df::unit *unit = Gui::getSelectedUnit(out);
if (!unit) if (!unit)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
@ -153,7 +153,7 @@ static command_result rename(Core * c, vector <string> &parameters)
if (parameters.size() != 2) if (parameters.size() != 2)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
df::unit *unit = Gui::getSelectedUnit(c); df::unit *unit = Gui::getSelectedUnit(out);
if (!unit) if (!unit)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
@ -162,7 +162,7 @@ static command_result rename(Core * c, vector <string> &parameters)
else else
{ {
if (!parameters.empty() && cmd != "?") if (!parameters.empty() && cmd != "?")
c->con.printerr("Invalid command: %s\n", cmd.c_str()); out.printerr("Invalid command: %s\n", cmd.c_str());
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }

@ -58,15 +58,15 @@ enum revealstate
revealstate revealed = NOT_REVEALED; revealstate revealed = NOT_REVEALED;
command_result reveal(DFHack::Core * c, std::vector<std::string> & params); command_result reveal(color_ostream &out, std::vector<std::string> & params);
command_result unreveal(DFHack::Core * c, std::vector<std::string> & params); command_result unreveal(color_ostream &out, std::vector<std::string> & params);
command_result revtoggle(DFHack::Core * c, std::vector<std::string> & params); command_result revtoggle(color_ostream &out, std::vector<std::string> & params);
command_result revflood(DFHack::Core * c, std::vector<std::string> & params); command_result revflood(color_ostream &out, std::vector<std::string> & params);
command_result nopause(DFHack::Core * c, std::vector<std::string> & params); command_result nopause(color_ostream &out, std::vector<std::string> & params);
DFHACK_PLUGIN("reveal"); DFHACK_PLUGIN("reveal");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.clear(); commands.clear();
commands.push_back(PluginCommand("reveal","Reveal the map. 'reveal hell' will also reveal hell. 'reveal demon' won't pause.",reveal)); commands.push_back(PluginCommand("reveal","Reveal the map. 'reveal hell' will also reveal hell. 'reveal demon' won't pause.",reveal));
@ -77,9 +77,9 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_onupdate ( Core * c ) DFhackCExport command_result plugin_onupdate ( color_ostream &out )
{ {
DFHack::World *World =c->getWorld(); DFHack::World *World = Core::getInstance().getWorld();
t_gamemodes gm; t_gamemodes gm;
World->ReadGameMode(gm); World->ReadGameMode(gm);
if(gm.g_mode == GAMEMODE_DWARF) if(gm.g_mode == GAMEMODE_DWARF)
@ -97,12 +97,12 @@ DFhackCExport command_result plugin_onupdate ( Core * c )
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
command_result nopause (Core * c, std::vector <std::string> & parameters) command_result nopause (color_ostream &out, std::vector <std::string> & parameters)
{ {
if (parameters.size() == 1 && (parameters[0] == "0" || parameters[0] == "1")) if (parameters.size() == 1 && (parameters[0] == "0" || parameters[0] == "1"))
{ {
@ -110,17 +110,17 @@ command_result nopause (Core * c, std::vector <std::string> & parameters)
nopause_state = 0; nopause_state = 0;
else else
nopause_state = 1; nopause_state = 1;
c->con.print("nopause %sactivated.\n", (nopause_state ? "" : "de")); out.print("nopause %sactivated.\n", (nopause_state ? "" : "de"));
} }
else else
{ {
c->con.print("Disable pausing (doesn't affect pause forced by reveal).\nActivate with 'nopause 1', deactivate with 'nopause 0'.\nCurrent state: %d.\n", nopause_state); out.print("Disable pausing (doesn't affect pause forced by reveal).\nActivate with 'nopause 1', deactivate with 'nopause 0'.\nCurrent state: %d.\n", nopause_state);
} }
return CR_OK; return CR_OK;
} }
void revealAdventure(DFHack::Core * c) void revealAdventure(color_ostream &out)
{ {
for (size_t i = 0; i < world->map.map_blocks.size(); i++) for (size_t i = 0; i < world->map.map_blocks.size(); i++)
{ {
@ -138,10 +138,10 @@ void revealAdventure(DFHack::Core * c)
designations[x][y].bits.pile = 1; designations[x][y].bits.pile = 1;
} }
} }
c->con.print("Local map revealed.\n"); out.print("Local map revealed.\n");
} }
command_result reveal(DFHack::Core * c, std::vector<std::string> & params) command_result reveal(color_ostream &out, std::vector<std::string> & params)
{ {
bool no_hell = true; bool no_hell = true;
bool pause = true; bool pause = true;
@ -151,7 +151,7 @@ command_result reveal(DFHack::Core * c, std::vector<std::string> & params)
no_hell = false; no_hell = false;
else if(params[i] == "help" || params[i] == "?") else if(params[i] == "help" || params[i] == "?")
{ {
c->con.print("Reveals the map, by default ignoring hell.\n" out.print("Reveals the map, by default ignoring hell.\n"
"Options:\n" "Options:\n"
"hell - also reveal hell, while forcing the game to pause.\n" "hell - also reveal hell, while forcing the game to pause.\n"
"demon - reveal hell, do not pause.\n" "demon - reveal hell, do not pause.\n"
@ -168,25 +168,26 @@ command_result reveal(DFHack::Core * c, std::vector<std::string> & params)
no_hell = false; no_hell = false;
pause = false; pause = false;
} }
Console & con = c->con; auto & con = out;
if(revealed != NOT_REVEALED) if(revealed != NOT_REVEALED)
{ {
con.printerr("Map is already revealed or this is a different map.\n"); con.printerr("Map is already revealed or this is a different map.\n");
return CR_FAILURE; return CR_FAILURE;
} }
CoreSuspender suspend(c); CoreSuspender suspend;
DFHack::World *World =c->getWorld();
DFHack::World *World = Core::getInstance().getWorld();
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
t_gamemodes gm; t_gamemodes gm;
World->ReadGameMode(gm); World->ReadGameMode(gm);
if(gm.g_mode == GAMEMODE_ADVENTURE) if(gm.g_mode == GAMEMODE_ADVENTURE)
{ {
revealAdventure(c); revealAdventure(out);
return CR_OK; return CR_OK;
} }
if(gm.g_mode != GAMEMODE_DWARF) if(gm.g_mode != GAMEMODE_DWARF)
@ -237,14 +238,14 @@ command_result reveal(DFHack::Core * c, std::vector<std::string> & params)
return CR_OK; return CR_OK;
} }
command_result unreveal(DFHack::Core * c, std::vector<std::string> & params) command_result unreveal(color_ostream &out, std::vector<std::string> & params)
{ {
Console & con = c->con; auto & con = out;
for(size_t i = 0; i < params.size();i++) for(size_t i = 0; i < params.size();i++)
{ {
if(params[i] == "help" || params[i] == "?") if(params[i] == "help" || params[i] == "?")
{ {
c->con.print("Reverts the previous reveal operation, hiding the map again.\n"); out.print("Reverts the previous reveal operation, hiding the map again.\n");
return CR_OK; return CR_OK;
} }
} }
@ -253,12 +254,12 @@ command_result unreveal(DFHack::Core * c, std::vector<std::string> & params)
con.printerr("There's nothing to revert!\n"); con.printerr("There's nothing to revert!\n");
return CR_FAILURE; return CR_FAILURE;
} }
CoreSuspender suspend(c); CoreSuspender suspend;
DFHack::World *World =c->getWorld(); DFHack::World *World = Core::getInstance().getWorld();
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
t_gamemodes gm; t_gamemodes gm;
@ -294,56 +295,56 @@ command_result unreveal(DFHack::Core * c, std::vector<std::string> & params)
return CR_OK; return CR_OK;
} }
command_result revtoggle (DFHack::Core * c, std::vector<std::string> & params) command_result revtoggle (color_ostream &out, std::vector<std::string> & params)
{ {
for(size_t i = 0; i < params.size();i++) for(size_t i = 0; i < params.size();i++)
{ {
if(params[i] == "help" || params[i] == "?") if(params[i] == "help" || params[i] == "?")
{ {
c->con.print("Toggles between reveal and unreveal.\nCurrently it: "); out.print("Toggles between reveal and unreveal.\nCurrently it: ");
break; break;
} }
} }
if(revealed) if(revealed)
{ {
return unreveal(c,params); return unreveal(out,params);
} }
else else
{ {
return reveal(c,params); return reveal(out,params);
} }
} }
command_result revflood(DFHack::Core * c, std::vector<std::string> & params) command_result revflood(color_ostream &out, std::vector<std::string> & params)
{ {
for(size_t i = 0; i < params.size();i++) for(size_t i = 0; i < params.size();i++)
{ {
if(params[i] == "help" || params[i] == "?") if(params[i] == "help" || params[i] == "?")
{ {
c->con.print("This command hides the whole map. Then, starting from the cursor,\n" out.print("This command hides the whole map. Then, starting from the cursor,\n"
"reveals all accessible tiles. Allows repairing parma-revealed maps.\n" "reveals all accessible tiles. Allows repairing parma-revealed maps.\n"
); );
return CR_OK; return CR_OK;
} }
} }
CoreSuspender suspend(c); CoreSuspender suspend;
uint32_t x_max,y_max,z_max; uint32_t x_max,y_max,z_max;
World * World = c->getWorld(); World * World = Core::getInstance().getWorld();
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
if(revealed != NOT_REVEALED) if(revealed != NOT_REVEALED)
{ {
c->con.printerr("This is only safe to use with non-revealed map.\n"); out.printerr("This is only safe to use with non-revealed map.\n");
return CR_FAILURE; return CR_FAILURE;
} }
t_gamemodes gm; t_gamemodes gm;
World->ReadGameMode(gm); World->ReadGameMode(gm);
if(gm.g_type != GAMETYPE_DWARF_MAIN && gm.g_mode != GAMEMODE_DWARF ) if(gm.g_type != GAMETYPE_DWARF_MAIN && gm.g_mode != GAMEMODE_DWARF )
{ {
c->con.printerr("Only in proper dwarf mode.\n"); out.printerr("Only in proper dwarf mode.\n");
return CR_FAILURE; return CR_FAILURE;
} }
int32_t cx, cy, cz; int32_t cx, cy, cz;
@ -354,7 +355,7 @@ command_result revflood(DFHack::Core * c, std::vector<std::string> & params)
Gui::getCursorCoords(cx,cy,cz); Gui::getCursorCoords(cx,cy,cz);
if(cx == -30000) if(cx == -30000)
{ {
c->con.printerr("Cursor is not active. Point the cursor at some empty space you want to be unhidden.\n"); out.printerr("Cursor is not active. Point the cursor at some empty space you want to be unhidden.\n");
return CR_FAILURE; return CR_FAILURE;
} }
DFCoord xy ((uint32_t)cx,(uint32_t)cy,cz); DFCoord xy ((uint32_t)cx,(uint32_t)cy,cz);
@ -362,7 +363,7 @@ command_result revflood(DFHack::Core * c, std::vector<std::string> & params)
df::tiletype tt = MCache->tiletypeAt(xy); df::tiletype tt = MCache->tiletypeAt(xy);
if(isWallTerrain(tt)) if(isWallTerrain(tt))
{ {
c->con.printerr("Point the cursor at some empty space you want to be unhidden.\n"); out.printerr("Point the cursor at some empty space you want to be unhidden.\n");
delete MCache; delete MCache;
return CR_FAILURE; return CR_FAILURE;
} }

@ -42,19 +42,19 @@ bool ignoreSeeds(df::item_flags& f) // seeds with the following flags should not
f.bits.in_job; f.bits.in_job;
}; };
void printHelp(Core& core) // prints help void printHelp(color_ostream &out) // prints help
{ {
core.con.print( out.print(
"Watches the numbers of seeds available and enables/disables seed and plant cooking.\n" "Watches the numbers of seeds available and enables/disables seed and plant cooking.\n"
"Each plant type can be assigned a limit. If their number falls below,\n" "Each plant type can be assigned a limit. If their number falls below,\n"
"the plants and seeds of that type will be excluded from cookery.\n" "the plants and seeds of that type will be excluded from cookery.\n"
"If the number rises above the limit + %i, then cooking will be allowed.\n", buffer "If the number rises above the limit + %i, then cooking will be allowed.\n", buffer
); );
core.con.printerr( out.printerr(
"The plugin needs a fortress to be loaded and will deactivate automatically otherwise.\n" "The plugin needs a fortress to be loaded and will deactivate automatically otherwise.\n"
"You have to reactivate with 'seedwatch start' after you load the game.\n" "You have to reactivate with 'seedwatch start' after you load the game.\n"
); );
core.con.print( out.print(
"Options:\n" "Options:\n"
"seedwatch all - Adds all plants from the abbreviation list to the watch list.\n" "seedwatch all - Adds all plants from the abbreviation list to the watch list.\n"
"seedwatch start - Start watching.\n" "seedwatch start - Start watching.\n"
@ -64,13 +64,13 @@ void printHelp(Core& core) // prints help
); );
if(!abbreviations.empty()) if(!abbreviations.empty())
{ {
core.con.print("You can use these abbreviations for the plant tokens:\n"); out.print("You can use these abbreviations for the plant tokens:\n");
for(map<string, string>::const_iterator i = abbreviations.begin(); i != abbreviations.end(); ++i) for(map<string, string>::const_iterator i = abbreviations.begin(); i != abbreviations.end(); ++i)
{ {
core.con.print("%s -> %s\n", i->first.c_str(), i->second.c_str()); out.print("%s -> %s\n", i->first.c_str(), i->second.c_str());
} }
} }
core.con.print( out.print(
"Examples:\n" "Examples:\n"
"seedwatch MUSHROOM_HELMET_PLUMP 30\n" "seedwatch MUSHROOM_HELMET_PLUMP 30\n"
" add MUSHROOM_HELMET_PLUMP to the watch list, limit = 30\n" " add MUSHROOM_HELMET_PLUMP to the watch list, limit = 30\n"
@ -96,14 +96,9 @@ string searchAbbreviations(string in)
} }
}; };
command_result df_seedwatch(Core* pCore, vector<string>& parameters) command_result df_seedwatch(color_ostream &out, vector<string>& parameters)
{ {
Core& core = *pCore; CoreSuspender suspend;
if(!core.isValid())
{
return CR_FAILURE;
}
CoreSuspender suspend(pCore);
map<string, t_materialIndex> materialsReverser; map<string, t_materialIndex> materialsReverser;
for(size_t i = 0; i < world->raws.plants.all.size(); ++i) for(size_t i = 0; i < world->raws.plants.all.size(); ++i)
@ -111,7 +106,7 @@ command_result df_seedwatch(Core* pCore, vector<string>& parameters)
materialsReverser[world->raws.plants.all[i]->id] = i; materialsReverser[world->raws.plants.all[i]->id] = i;
} }
World *w = core.getWorld(); World *w = Core::getInstance().getWorld();
t_gamemodes gm; t_gamemodes gm;
w->ReadGameMode(gm);// FIXME: check return value w->ReadGameMode(gm);// FIXME: check return value
@ -119,7 +114,7 @@ command_result df_seedwatch(Core* pCore, vector<string>& parameters)
if(gm.g_mode != GAMEMODE_DWARF || gm.g_type != GAMETYPE_DWARF_MAIN) if(gm.g_mode != GAMEMODE_DWARF || gm.g_type != GAMETYPE_DWARF_MAIN)
{ {
// just print the help // just print the help
printHelp(core); printHelp(out);
return CR_OK; return CR_OK;
} }
@ -128,50 +123,50 @@ command_result df_seedwatch(Core* pCore, vector<string>& parameters)
switch(parameters.size()) switch(parameters.size())
{ {
case 0: case 0:
printHelp(core); printHelp(out);
break; break;
case 1: case 1:
par = parameters[0]; par = parameters[0];
if(par == "help") printHelp(core); if(par == "help") printHelp(out);
else if(par == "?") printHelp(core); else if(par == "?") printHelp(out);
else if(par == "start") else if(par == "start")
{ {
running = true; running = true;
core.con.print("seedwatch supervision started.\n"); out.print("seedwatch supervision started.\n");
} }
else if(par == "stop") else if(par == "stop")
{ {
running = false; running = false;
core.con.print("seedwatch supervision stopped.\n"); out.print("seedwatch supervision stopped.\n");
} }
else if(par == "clear") else if(par == "clear")
{ {
Kitchen::clearLimits(); Kitchen::clearLimits();
core.con.print("seedwatch watchlist cleared\n"); out.print("seedwatch watchlist cleared\n");
} }
else if(par == "info") else if(par == "info")
{ {
core.con.print("seedwatch Info:\n"); out.print("seedwatch Info:\n");
if(running) if(running)
{ {
core.con.print("seedwatch is supervising. Use 'seedwatch stop' to stop supervision.\n"); out.print("seedwatch is supervising. Use 'seedwatch stop' to stop supervision.\n");
} }
else else
{ {
core.con.print("seedwatch is not supervising. Use 'seedwatch start' to start supervision.\n"); out.print("seedwatch is not supervising. Use 'seedwatch start' to start supervision.\n");
} }
map<t_materialIndex, unsigned int> watchMap; map<t_materialIndex, unsigned int> watchMap;
Kitchen::fillWatchMap(watchMap); Kitchen::fillWatchMap(watchMap);
if(watchMap.empty()) if(watchMap.empty())
{ {
core.con.print("The watch list is empty.\n"); out.print("The watch list is empty.\n");
} }
else else
{ {
core.con.print("The watch list is:\n"); out.print("The watch list is:\n");
for(map<t_materialIndex, unsigned int>::const_iterator i = watchMap.begin(); i != watchMap.end(); ++i) for(map<t_materialIndex, unsigned int>::const_iterator i = watchMap.begin(); i != watchMap.end(); ++i)
{ {
core.con.print("%s : %u\n", world->raws.plants.all[i->first]->id.c_str(), i->second); out.print("%s : %u\n", world->raws.plants.all[i->first]->id.c_str(), i->second);
} }
} }
} }
@ -179,22 +174,22 @@ command_result df_seedwatch(Core* pCore, vector<string>& parameters)
{ {
map<t_materialIndex, unsigned int> watchMap; map<t_materialIndex, unsigned int> watchMap;
Kitchen::fillWatchMap(watchMap); Kitchen::fillWatchMap(watchMap);
Kitchen::debug_print(core); Kitchen::debug_print(out);
} }
/* /*
else if(par == "dumpmaps") else if(par == "dumpmaps")
{ {
core.con.print("Plants:\n"); out.print("Plants:\n");
for(auto i = plantMaterialTypes.begin(); i != plantMaterialTypes.end(); i++) for(auto i = plantMaterialTypes.begin(); i != plantMaterialTypes.end(); i++)
{ {
auto t = materialsModule.df_organic->at(i->first); auto t = materialsModule.df_organic->at(i->first);
core.con.print("%s : %u %u\n", organics[i->first].id.c_str(), i->second, t->material_basic_mat); out.print("%s : %u %u\n", organics[i->first].id.c_str(), i->second, t->material_basic_mat);
} }
core.con.print("Seeds:\n"); out.print("Seeds:\n");
for(auto i = seedMaterialTypes.begin(); i != seedMaterialTypes.end(); i++) for(auto i = seedMaterialTypes.begin(); i != seedMaterialTypes.end(); i++)
{ {
auto t = materialsModule.df_organic->at(i->first); auto t = materialsModule.df_organic->at(i->first);
core.con.print("%s : %u %u\n", organics[i->first].id.c_str(), i->second, t->material_seed); out.print("%s : %u %u\n", organics[i->first].id.c_str(), i->second, t->material_seed);
} }
} }
*/ */
@ -204,11 +199,11 @@ command_result df_seedwatch(Core* pCore, vector<string>& parameters)
if(materialsReverser.count(token) > 0) if(materialsReverser.count(token) > 0)
{ {
Kitchen::removeLimit(materialsReverser[token]); Kitchen::removeLimit(materialsReverser[token]);
core.con.print("%s is not being watched\n", token.c_str()); out.print("%s is not being watched\n", token.c_str());
} }
else else
{ {
core.con.print("%s has not been found as a material.\n", token.c_str()); out.print("%s has not been found as a material.\n", token.c_str());
} }
} }
break; break;
@ -228,16 +223,16 @@ command_result df_seedwatch(Core* pCore, vector<string>& parameters)
if(materialsReverser.count(token) > 0) if(materialsReverser.count(token) > 0)
{ {
Kitchen::setLimit(materialsReverser[token], limit); Kitchen::setLimit(materialsReverser[token], limit);
core.con.print("%s is being watched.\n", token.c_str()); out.print("%s is being watched.\n", token.c_str());
} }
else else
{ {
core.con.print("%s has not been found as a material.\n", token.c_str()); out.print("%s has not been found as a material.\n", token.c_str());
} }
} }
break; break;
default: default:
printHelp(core); printHelp(out);
break; break;
} }
@ -246,7 +241,7 @@ command_result df_seedwatch(Core* pCore, vector<string>& parameters)
DFHACK_PLUGIN("seedwatch"); DFHACK_PLUGIN("seedwatch");
DFhackCExport command_result plugin_init(Core* pCore, vector<PluginCommand>& commands) DFhackCExport command_result plugin_init(color_ostream &out, vector<PluginCommand>& commands)
{ {
commands.clear(); commands.clear();
commands.push_back(PluginCommand("seedwatch", "Switches cookery based on quantity of seeds, to keep reserves", df_seedwatch)); commands.push_back(PluginCommand("seedwatch", "Switches cookery based on quantity of seeds, to keep reserves", df_seedwatch));
@ -275,13 +270,13 @@ DFhackCExport command_result plugin_init(Core* pCore, vector<PluginCommand>& com
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_onstatechange(Core* pCore, state_change_event event) DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event)
{ {
switch (event) { switch (event) {
case SC_GAME_LOADED: case SC_GAME_LOADED:
case SC_GAME_UNLOADED: case SC_GAME_UNLOADED:
if (running) if (running)
pCore->con.printerr("seedwatch deactivated due to game load/unload\n"); out.printerr("seedwatch deactivated due to game load/unload\n");
running = false; running = false;
break; break;
default: default:
@ -291,7 +286,7 @@ DFhackCExport command_result plugin_onstatechange(Core* pCore, state_change_even
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_onupdate(Core* pCore) DFhackCExport command_result plugin_onupdate(color_ostream &out)
{ {
if (running) if (running)
{ {
@ -301,8 +296,7 @@ DFhackCExport command_result plugin_onupdate(Core* pCore)
return CR_OK; return CR_OK;
counter = 0; counter = 0;
Core& core = *pCore; World *w = Core::getInstance().getWorld();
World *w = core.getWorld();
t_gamemodes gm; t_gamemodes gm;
w->ReadGameMode(gm);// FIXME: check return value w->ReadGameMode(gm);// FIXME: check return value
// if game mode isn't fortress mode // if game mode isn't fortress mode
@ -310,7 +304,7 @@ DFhackCExport command_result plugin_onupdate(Core* pCore)
{ {
// stop running. // stop running.
running = false; running = false;
core.con.printerr("seedwatch deactivated due to game mode switch\n"); out.printerr("seedwatch deactivated due to game mode switch\n");
return CR_OK; return CR_OK;
} }
// this is dwarf mode, continue // this is dwarf mode, continue

@ -10,13 +10,13 @@ using namespace DFHack;
// Here go all the command declarations... // Here go all the command declarations...
// mostly to allow having the mandatory stuff on top of the file and commands on the bottom // mostly to allow having the mandatory stuff on top of the file and commands on the bottom
command_result server (Core * c, std::vector <std::string> & parameters); command_result server (color_ostream &out, std::vector <std::string> & parameters);
// A plugins must be able to return its name. This must correspond to the filename - skeleton.plug.so or skeleton.plug.dll // A plugins must be able to return its name. This must correspond to the filename - skeleton.plug.so or skeleton.plug.dll
DFHACK_PLUGIN("server"); DFHACK_PLUGIN("server");
// Mandatory init function. If you have some global state, create it here. // Mandatory init function. If you have some global state, create it here.
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
// Fill the command list with your commands. // Fill the command list with your commands.
commands.clear(); commands.clear();
@ -27,7 +27,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
} }
// This is called right before the plugin library is removed from memory. // This is called right before the plugin library is removed from memory.
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
// You *MUST* kill all threads you created before this returns. // You *MUST* kill all threads you created before this returns.
// If everythin fails, just return CR_FAILURE. Your plugin will be // If everythin fails, just return CR_FAILURE. Your plugin will be
@ -36,7 +36,7 @@ DFhackCExport command_result plugin_shutdown ( Core * c )
} }
// This is WRONG and STUPID. Never use this as an example! // This is WRONG and STUPID. Never use this as an example!
command_result server (Core * c, std::vector <std::string> & parameters) command_result server (color_ostream &out, std::vector <std::string> & parameters)
{ {
// It's nice to provide a 'help' option for your command. // It's nice to provide a 'help' option for your command.
// It's also nice to print the same help if you get invalid options from the user instead of just acting strange // It's also nice to print the same help if you get invalid options from the user instead of just acting strange
@ -46,7 +46,7 @@ command_result server (Core * c, std::vector <std::string> & parameters)
{ {
// Core has a handle to the console. The console is thread-safe. // Core has a handle to the console. The console is thread-safe.
// Only one thing can read from it at a time though... // Only one thing can read from it at a time though...
c->con.print("This command is a simple Hello World example for zeromq!\n"); out.print("This command is a simple Hello World example for zeromq!\n");
return CR_OK; return CR_OK;
} }
} }
@ -61,7 +61,7 @@ command_result server (Core * c, std::vector <std::string> & parameters)
// Wait for next request from client // Wait for next request from client
socket.recv (&request); socket.recv (&request);
c->con.print("Received Hello\n"); out.print("Received Hello\n");
// Do some 'work' // Do some 'work'
#ifdef LINUX_BUILD #ifdef LINUX_BUILD

@ -26,18 +26,18 @@ using namespace df::enums;
using df::global::world; using df::global::world;
command_result df_showmood (Core * c, vector <string> & parameters) command_result df_showmood (color_ostream &out, vector <string> & parameters)
{ {
if (!parameters.empty()) if (!parameters.empty())
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
if (!Translation::IsValid()) if (!Translation::IsValid())
{ {
c->con.printerr("Translation data unavailable!\n"); out.printerr("Translation data unavailable!\n");
return CR_FAILURE; return CR_FAILURE;
} }
CoreSuspender suspend(c); CoreSuspender suspend;
bool found = false; bool found = false;
for (df::job_list_link *cur = world->job_list.next; cur != NULL; cur = cur->next) for (df::job_list_link *cur = world->job_list.next; cur != NULL; cur = cur->next)
@ -58,27 +58,27 @@ command_result df_showmood (Core * c, vector <string> & parameters)
} }
if (!unit) if (!unit)
{ {
c->con.printerr("Found strange mood not attached to any dwarf!\n"); out.printerr("Found strange mood not attached to any dwarf!\n");
continue; continue;
} }
if (unit->mood == mood_type::None) if (unit->mood == mood_type::None)
{ {
c->con.printerr("Dwarf with strange mood does not have a mood type!\n"); out.printerr("Dwarf with strange mood does not have a mood type!\n");
continue; continue;
} }
c->con.print("%s is currently ", Translation::TranslateName(&unit->name, false).c_str()); out.print("%s is currently ", Translation::TranslateName(&unit->name, false).c_str());
switch (unit->mood) switch (unit->mood)
{ {
case mood_type::Macabre: case mood_type::Macabre:
c->con.print("in a macabre mood"); out.print("in a macabre mood");
if (job->job_type != job_type::StrangeMoodBrooding) if (job->job_type != job_type::StrangeMoodBrooding)
c->con.print(" (but isn't actually in a macabre mood?)"); out.print(" (but isn't actually in a macabre mood?)");
break; break;
case mood_type::Fell: case mood_type::Fell:
c->con.print("in a fell mood"); out.print("in a fell mood");
if (job->job_type != job_type::StrangeMoodFell) if (job->job_type != job_type::StrangeMoodFell)
c->con.print(" (but isn't actually in a fell mood?)"); out.print(" (but isn't actually in a fell mood?)");
break; break;
case mood_type::Fey: case mood_type::Fey:
@ -87,77 +87,77 @@ command_result df_showmood (Core * c, vector <string> & parameters)
switch (unit->mood) switch (unit->mood)
{ {
case mood_type::Fey: case mood_type::Fey:
c->con.print("in a fey mood"); out.print("in a fey mood");
break; break;
case mood_type::Secretive: case mood_type::Secretive:
c->con.print("in a secretive mood"); out.print("in a secretive mood");
break; break;
case mood_type::Possessed: case mood_type::Possessed:
c->con.print("possessed"); out.print("possessed");
break; break;
} }
c->con.print(" with intent to "); out.print(" with intent to ");
switch (job->job_type) switch (job->job_type)
{ {
case job_type::StrangeMoodCrafter: case job_type::StrangeMoodCrafter:
c->con.print("become a Craftsdwarf (or Engraver)"); out.print("become a Craftsdwarf (or Engraver)");
break; break;
case job_type::StrangeMoodJeweller: case job_type::StrangeMoodJeweller:
c->con.print("become a Jeweler"); out.print("become a Jeweler");
break; break;
case job_type::StrangeMoodForge: case job_type::StrangeMoodForge:
c->con.print("become a Metalworker"); out.print("become a Metalworker");
break; break;
case job_type::StrangeMoodMagmaForge: case job_type::StrangeMoodMagmaForge:
c->con.print("become a Metalworker using a Magma Forge"); out.print("become a Metalworker using a Magma Forge");
break; break;
case job_type::StrangeMoodCarpenter: case job_type::StrangeMoodCarpenter:
c->con.print("become a Carpenter"); out.print("become a Carpenter");
break; break;
case job_type::StrangeMoodMason: case job_type::StrangeMoodMason:
c->con.print("become a Mason (or Miner)"); out.print("become a Mason (or Miner)");
break; break;
case job_type::StrangeMoodBowyer: case job_type::StrangeMoodBowyer:
c->con.print("become a Bowyer"); out.print("become a Bowyer");
break; break;
case job_type::StrangeMoodTanner: case job_type::StrangeMoodTanner:
c->con.print("become a Leatherworker (or Tanner)"); out.print("become a Leatherworker (or Tanner)");
break; break;
case job_type::StrangeMoodWeaver: case job_type::StrangeMoodWeaver:
c->con.print("become a Clothier (or Weaver)"); out.print("become a Clothier (or Weaver)");
break; break;
case job_type::StrangeMoodGlassmaker: case job_type::StrangeMoodGlassmaker:
c->con.print("become a Glassmaker"); out.print("become a Glassmaker");
break; break;
case job_type::StrangeMoodMechanics: case job_type::StrangeMoodMechanics:
c->con.print("become a Mechanic"); out.print("become a Mechanic");
break; break;
case job_type::StrangeMoodBrooding: case job_type::StrangeMoodBrooding:
c->con.print("enter a macabre mood?"); out.print("enter a macabre mood?");
break; break;
case job_type::StrangeMoodFell: case job_type::StrangeMoodFell:
c->con.print("enter a fell mood?"); out.print("enter a fell mood?");
break; break;
} }
break; break;
default: default:
c->con.print("insane?"); out.print("insane?");
break; break;
} }
if (building) if (building)
{ {
string name; string name;
building->getName(&name); building->getName(&name);
c->con.print(" and has claimed a %s\n", name.c_str()); out.print(" and has claimed a %s\n", name.c_str());
} }
else else
c->con.print(" and has not yet claimed a workshop\n"); out.print(" and has not yet claimed a workshop\n");
for (size_t i = 0; i < job->job_items.size(); i++) for (size_t i = 0; i < job->job_items.size(); i++)
{ {
df::job_item *item = job->job_items[i]; df::job_item *item = job->job_items[i];
c->con.print("Item %i: ", i + 1); out.print("Item %i: ", i + 1);
MaterialInfo matinfo(item->mat_type, item->mat_index); MaterialInfo matinfo(item->mat_type, item->mat_index);
@ -166,37 +166,37 @@ command_result df_showmood (Core * c, vector <string> & parameters)
switch (item->item_type) switch (item->item_type)
{ {
case item_type::BOULDER: case item_type::BOULDER:
c->con.print("%s boulder", mat_name.c_str()); out.print("%s boulder", mat_name.c_str());
break; break;
case item_type::BLOCKS: case item_type::BLOCKS:
c->con.print("%s blocks", mat_name.c_str()); out.print("%s blocks", mat_name.c_str());
break; break;
case item_type::WOOD: case item_type::WOOD:
c->con.print("%s logs", mat_name.c_str()); out.print("%s logs", mat_name.c_str());
break; break;
case item_type::BAR: case item_type::BAR:
if (matinfo.isInorganicWildcard()) if (matinfo.isInorganicWildcard())
mat_name = "metal"; mat_name = "metal";
if (matinfo.inorganic && matinfo.inorganic->flags.is_set(inorganic_flags::WAFERS)) if (matinfo.inorganic && matinfo.inorganic->flags.is_set(inorganic_flags::WAFERS))
c->con.print("%s wafers", mat_name.c_str()); out.print("%s wafers", mat_name.c_str());
else else
c->con.print("%s bars", mat_name.c_str()); out.print("%s bars", mat_name.c_str());
break; break;
case item_type::SMALLGEM: case item_type::SMALLGEM:
c->con.print("%s cut gems", mat_name.c_str()); out.print("%s cut gems", mat_name.c_str());
break; break;
case item_type::ROUGH: case item_type::ROUGH:
if (matinfo.isAnyInorganic()) if (matinfo.isAnyInorganic())
{ {
if (matinfo.isInorganicWildcard()) if (matinfo.isInorganicWildcard())
mat_name = "any"; mat_name = "any";
c->con.print("%s rough gems", mat_name.c_str()); out.print("%s rough gems", mat_name.c_str());
} }
else else
c->con.print("raw %s", mat_name.c_str()); out.print("raw %s", mat_name.c_str());
break; break;
case item_type::SKIN_TANNED: case item_type::SKIN_TANNED:
c->con.print("%s leather", mat_name.c_str()); out.print("%s leather", mat_name.c_str());
break; break;
case item_type::CLOTH: case item_type::CLOTH:
if (matinfo.isNone()) if (matinfo.isNone())
@ -208,36 +208,36 @@ command_result df_showmood (Core * c, vector <string> & parameters)
else if (item->flags2.bits.yarn) else if (item->flags2.bits.yarn)
mat_name = "any yarn"; mat_name = "any yarn";
} }
c->con.print("%s cloth", mat_name.c_str()); out.print("%s cloth", mat_name.c_str());
break; break;
case item_type::REMAINS: case item_type::REMAINS:
c->con.print("%s remains", mat_name.c_str()); out.print("%s remains", mat_name.c_str());
break; break;
case item_type::CORPSE: case item_type::CORPSE:
c->con.print("%s %scorpse", mat_name.c_str(), (item->flags1.bits.murdered ? "murdered " : "")); out.print("%s %scorpse", mat_name.c_str(), (item->flags1.bits.murdered ? "murdered " : ""));
break; break;
case item_type::NONE: case item_type::NONE:
if (item->flags2.bits.body_part) if (item->flags2.bits.body_part)
{ {
if (item->flags2.bits.bone) if (item->flags2.bits.bone)
c->con.print("%s bones", mat_name.c_str()); out.print("%s bones", mat_name.c_str());
else if (item->flags2.bits.shell) else if (item->flags2.bits.shell)
c->con.print("%s shells", mat_name.c_str()); out.print("%s shells", mat_name.c_str());
else if (item->flags2.bits.horn) else if (item->flags2.bits.horn)
c->con.print("%s horns", mat_name.c_str()); out.print("%s horns", mat_name.c_str());
else if (item->flags2.bits.pearl) else if (item->flags2.bits.pearl)
c->con.print("%s pearls", mat_name.c_str()); out.print("%s pearls", mat_name.c_str());
else if (item->flags2.bits.ivory_tooth) else if (item->flags2.bits.ivory_tooth)
c->con.print("%s ivory/teeth", mat_name.c_str()); out.print("%s ivory/teeth", mat_name.c_str());
else else
c->con.print("%s unknown body parts (%s:%s:%s)", out.print("%s unknown body parts (%s:%s:%s)",
mat_name.c_str(), mat_name.c_str(),
bitfieldToString(item->flags1).c_str(), bitfieldToString(item->flags1).c_str(),
bitfieldToString(item->flags2).c_str(), bitfieldToString(item->flags2).c_str(),
bitfieldToString(item->flags3).c_str()); bitfieldToString(item->flags3).c_str());
} }
else else
c->con.print("indeterminate %s item (%s:%s:%s)", out.print("indeterminate %s item (%s:%s:%s)",
mat_name.c_str(), mat_name.c_str(),
bitfieldToString(item->flags1).c_str(), bitfieldToString(item->flags1).c_str(),
bitfieldToString(item->flags2).c_str(), bitfieldToString(item->flags2).c_str(),
@ -247,7 +247,7 @@ command_result df_showmood (Core * c, vector <string> & parameters)
{ {
ItemTypeInfo itinfo(item->item_type, item->item_subtype); ItemTypeInfo itinfo(item->item_type, item->item_subtype);
c->con.print("item %s material %s flags (%s:%s:%s)", out.print("item %s material %s flags (%s:%s:%s)",
itinfo.toString().c_str(), mat_name.c_str(), itinfo.toString().c_str(), mat_name.c_str(),
bitfieldToString(item->flags1).c_str(), bitfieldToString(item->flags1).c_str(),
bitfieldToString(item->flags2).c_str(), bitfieldToString(item->flags2).c_str(),
@ -256,25 +256,25 @@ command_result df_showmood (Core * c, vector <string> & parameters)
} }
} }
c->con.print(", quantity %i\n", item->quantity); out.print(", quantity %i\n", item->quantity);
} }
} }
if (!found) if (!found)
c->con.print("No strange moods currently active.\n"); out.print("No strange moods currently active.\n");
return CR_OK; return CR_OK;
} }
DFHACK_PLUGIN("showmood"); DFHACK_PLUGIN("showmood");
DFhackCExport command_result plugin_init (Core *c, std::vector<PluginCommand> &commands) DFhackCExport command_result plugin_init (color_ostream &out, std::vector<PluginCommand> &commands)
{ {
commands.clear(); commands.clear();
commands.push_back(PluginCommand("showmood", "Shows items needed for current strange mood.", df_showmood)); commands.push_back(PluginCommand("showmood", "Shows items needed for current strange mood.", df_showmood));
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }

@ -19,14 +19,14 @@ using namespace df::enums;
// Here go all the command declarations... // Here go all the command declarations...
// mostly to allow having the mandatory stuff on top of the file and commands on the bottom // mostly to allow having the mandatory stuff on top of the file and commands on the bottom
command_result skeleton (Core * c, std::vector <std::string> & parameters); command_result skeleton (color_ostream &out, std::vector <std::string> & parameters);
// A plugin must be able to return its name and version. // A plugin must be able to return its name and version.
// The name string provided must correspond to the filename - skeleton.plug.so or skeleton.plug.dll in this case // The name string provided must correspond to the filename - skeleton.plug.so or skeleton.plug.dll in this case
DFHACK_PLUGIN("skeleton"); DFHACK_PLUGIN("skeleton");
// Mandatory init function. If you have some global state, create it here. // Mandatory init function. If you have some global state, create it here.
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
// Fill the command list with your commands. // Fill the command list with your commands.
commands.clear(); commands.clear();
@ -43,7 +43,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
} }
// This is called right before the plugin library is removed from memory. // This is called right before the plugin library is removed from memory.
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
// You *MUST* kill all threads you created before this returns. // You *MUST* kill all threads you created before this returns.
// If everything fails, just return CR_FAILURE. Your plugin will be // If everything fails, just return CR_FAILURE. Your plugin will be
@ -55,7 +55,7 @@ DFhackCExport command_result plugin_shutdown ( Core * c )
// Invoked with DF suspended, and always before the matching plugin_onupdate. // Invoked with DF suspended, and always before the matching plugin_onupdate.
// More event codes may be added in the future. // More event codes may be added in the future.
/* /*
DFhackCExport command_result plugin_onstatechange(Core* c, state_change_event event) DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event)
{ {
switch (event) { switch (event) {
case SC_GAME_LOADED: case SC_GAME_LOADED:
@ -74,7 +74,7 @@ DFhackCExport command_result plugin_onstatechange(Core* c, state_change_event ev
// Whatever you put here will be done in each game step. Don't abuse it. // Whatever you put here will be done in each game step. Don't abuse it.
// It's optional, so you can just comment it out like this if you don't need it. // It's optional, so you can just comment it out like this if you don't need it.
/* /*
DFhackCExport command_result plugin_onupdate ( Core * c ) DFhackCExport command_result plugin_onupdate ( color_ostream &out )
{ {
// whetever. You don't need to suspend DF execution here. // whetever. You don't need to suspend DF execution here.
return CR_OK; return CR_OK;
@ -82,7 +82,7 @@ DFhackCExport command_result plugin_onupdate ( Core * c )
*/ */
// A command! It sits around and looks pretty. And it's nice and friendly. // A command! It sits around and looks pretty. And it's nice and friendly.
command_result skeleton (Core * c, std::vector <std::string> & parameters) command_result skeleton (color_ostream &out, std::vector <std::string> & parameters)
{ {
// It's nice to print a help message you get invalid options // It's nice to print a help message you get invalid options
// from the user instead of just acting strange. // from the user instead of just acting strange.
@ -96,9 +96,9 @@ command_result skeleton (Core * c, std::vector <std::string> & parameters)
// Suspend this thread until DF has time for us. If you // Suspend this thread until DF has time for us. If you
// use CoreSuspender, it'll automatically resume DF when // use CoreSuspender, it'll automatically resume DF when
// execution leaves the current scope. // execution leaves the current scope.
CoreSuspender suspend(c); CoreSuspender suspend;
// Actually do something here. Yay. // Actually do something here. Yay.
c->con.print("Hello! I do nothing, remember?\n"); out.print("Hello! I do nothing, remember?\n");
// Give control back to DF. // Give control back to DF.
return CR_OK; return CR_OK;
} }

@ -22,12 +22,12 @@ using df::global::selection_rect;
using df::building_stockpilest; using df::building_stockpilest;
static command_result copystock(Core *c, vector <string> & parameters); static command_result copystock(color_ostream &out, vector <string> & parameters);
static bool copystock_guard(Core *c, df::viewscreen *top); static bool copystock_guard(df::viewscreen *top);
DFHACK_PLUGIN("stockpiles"); DFHACK_PLUGIN("stockpiles");
DFhackCExport command_result plugin_init (Core *c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.clear(); commands.clear();
if (world && ui) { if (world && ui) {
@ -47,16 +47,16 @@ DFhackCExport command_result plugin_init (Core *c, std::vector <PluginCommand> &
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
static bool copystock_guard(Core *c, df::viewscreen *top) static bool copystock_guard(df::viewscreen *top)
{ {
using namespace ui_sidebar_mode; using namespace ui_sidebar_mode;
if (!Gui::dwarfmode_hotkey(c,top)) if (!Gui::dwarfmode_hotkey(top))
return false; return false;
switch (ui->main.mode) { switch (ui->main.mode) {
@ -70,7 +70,7 @@ static bool copystock_guard(Core *c, df::viewscreen *top)
} }
} }
static command_result copystock(Core * c, vector <string> & parameters) static command_result copystock(color_ostream &out, vector <string> & parameters)
{ {
// HOTKEY COMMAND: CORE ALREADY SUSPENDED // HOTKEY COMMAND: CORE ALREADY SUSPENDED
@ -80,14 +80,14 @@ static command_result copystock(Core * c, vector <string> & parameters)
ui->main.mode = ui_sidebar_mode::QueryBuilding; ui->main.mode = ui_sidebar_mode::QueryBuilding;
selection_rect->start_x = -30000; selection_rect->start_x = -30000;
c->con << "Switched back to query building." << endl; out << "Switched back to query building." << endl;
return CR_OK; return CR_OK;
} }
building_stockpilest *sp = virtual_cast<building_stockpilest>(world->selected_building); building_stockpilest *sp = virtual_cast<building_stockpilest>(world->selected_building);
if (!sp) if (!sp)
{ {
c->con.printerr("Selected building isn't a stockpile.\n"); out.printerr("Selected building isn't a stockpile.\n");
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
@ -95,6 +95,6 @@ static command_result copystock(Core * c, vector <string> & parameters)
ui->main.mode = ui_sidebar_mode::Stockpiles; ui->main.mode = ui_sidebar_mode::Stockpiles;
world->selected_stockpile_type = stockpile_category::Custom; world->selected_stockpile_type = stockpile_category::Custom;
c->con << "Stockpile options copied." << endl; out << "Stockpile options copied." << endl;
return CR_OK; return CR_OK;
} }

@ -633,11 +633,11 @@ public:
CommandHistory tiletypes_hist; CommandHistory tiletypes_hist;
command_result df_tiletypes (Core * c, vector <string> & parameters); command_result df_tiletypes (color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("tiletypes"); DFHACK_PLUGIN("tiletypes");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
tiletypes_hist.load("tiletypes.history"); tiletypes_hist.load("tiletypes.history");
commands.clear(); commands.clear();
@ -645,13 +645,13 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
tiletypes_hist.save("tiletypes.history"); tiletypes_hist.save("tiletypes.history");
return CR_OK; return CR_OK;
} }
command_result df_tiletypes (Core * c, vector <string> & parameters) command_result df_tiletypes (color_ostream &out, vector <string> & parameters)
{ {
uint32_t x_max = 0, y_max = 0, z_max = 0; uint32_t x_max = 0, y_max = 0, z_max = 0;
int32_t x = 0, y = 0, z = 0; int32_t x = 0, y = 0, z = 0;
@ -660,7 +660,7 @@ command_result df_tiletypes (Core * c, vector <string> & parameters)
{ {
if(parameters[i] == "help" || parameters[i] == "?") if(parameters[i] == "help" || parameters[i] == "?")
{ {
c->con.print("This tool allows painting tiles types with a brush, using an optional filter.\n" out.print("This tool allows painting tiles types with a brush, using an optional filter.\n"
"The tool is interactive, similarly to the liquids tool.\n" "The tool is interactive, similarly to the liquids tool.\n"
"Further help is available inside.\n" "Further help is available inside.\n"
); );
@ -668,16 +668,19 @@ command_result df_tiletypes (Core * c, vector <string> & parameters)
} }
} }
assert(out.is_console());
Console &con = static_cast<Console&>(out);
TileType filter, paint; TileType filter, paint;
Brush *brush = new RectangleBrush(1,1); Brush *brush = new RectangleBrush(1,1);
bool end = false; bool end = false;
std::string brushname = "point"; std::string brushname = "point";
int width = 1, height = 1, z_levels = 1; int width = 1, height = 1, z_levels = 1;
c->con << "Welcome to the tiletype tool.\nType 'help' or '?' for a list of available commands, 'q' to quit.\nPress return after a command to confirm." << std::endl; con << "Welcome to the tiletype tool.\nType 'help' or '?' for a list of available commands, 'q' to quit.\nPress return after a command to confirm." << std::endl;
c->con.printerr("THIS TOOL CAN BE DANGEROUS. YOU'VE BEEN WARNED.\n"); con.printerr("THIS TOOL CAN BE DANGEROUS. YOU'VE BEEN WARNED.\n");
while (!end) while (!end)
{ {
c->con << "Filter: " << filter << std::endl con << "Filter: " << filter << std::endl
<< "Paint: " << paint << std::endl << "Paint: " << paint << std::endl
<< "Brush: " << brushname << std::endl; << "Brush: " << brushname << std::endl;
@ -686,7 +689,7 @@ command_result df_tiletypes (Core * c, vector <string> & parameters)
std::string option = ""; std::string option = "";
std::string value = ""; std::string value = "";
c->con.lineedit("tiletypes> ",input,tiletypes_hist); con.lineedit("tiletypes> ",input,tiletypes_hist);
tiletypes_hist.add(input); tiletypes_hist.add(input);
std::istringstream ss(input); std::istringstream ss(input);
ss >> command >> option >> value; ss >> command >> option >> value;
@ -695,7 +698,7 @@ command_result df_tiletypes (Core * c, vector <string> & parameters)
if (command == "help" || command == "?") if (command == "help" || command == "?")
{ {
help(c->con,option); help(con,option);
} }
else if (command == "quit" || command == "q") else if (command == "quit" || command == "q")
{ {
@ -720,19 +723,19 @@ command_result df_tiletypes (Core * c, vector <string> & parameters)
std::stringstream ss; std::stringstream ss;
CommandHistory hist; CommandHistory hist;
ss << "Set range width <" << width << "> "; ss << "Set range width <" << width << "> ";
c->con.lineedit(ss.str(),command,hist); con.lineedit(ss.str(),command,hist);
width = command == "" ? width : toint(command); width = command == "" ? width : toint(command);
if (width < 1) width = 1; if (width < 1) width = 1;
ss.str(""); ss.str("");
ss << "Set range height <" << height << "> "; ss << "Set range height <" << height << "> ";
c->con.lineedit(ss.str(),command,hist); con.lineedit(ss.str(),command,hist);
height = command == "" ? height : toint(command); height = command == "" ? height : toint(command);
if (height < 1) height = 1; if (height < 1) height = 1;
ss.str(""); ss.str("");
ss << "Set range z-levels <" << z_levels << "> "; ss << "Set range z-levels <" << z_levels << "> ";
c->con.lineedit(ss.str(),command,hist); con.lineedit(ss.str(),command,hist);
z_levels = command == "" ? z_levels : toint(command); z_levels = command == "" ? z_levels : toint(command);
if (z_levels < 1) z_levels = 1; if (z_levels < 1) z_levels = 1;
@ -763,29 +766,30 @@ command_result df_tiletypes (Core * c, vector <string> & parameters)
{ {
if (paint.empty()) if (paint.empty())
{ {
c->con.printerr("Set the paint first.\n"); con.printerr("Set the paint first.\n");
continue; continue;
} }
CoreSuspender suspend(c); CoreSuspender suspend;
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); con.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
Maps::getSize(x_max, y_max, z_max); Maps::getSize(x_max, y_max, z_max);
if (!Gui::getCursorCoords(x,y,z)) if (!Gui::getCursorCoords(x,y,z))
{ {
c->con.printerr("Can't get cursor coords! Make sure you have a cursor active in DF.\n"); con.printerr("Can't get cursor coords! Make sure you have a cursor active in DF.\n");
return CR_FAILURE; return CR_FAILURE;
} }
c->con.print("Cursor coords: (%d, %d, %d)\n",x,y,z); con.print("Cursor coords: (%d, %d, %d)\n",x,y,z);
DFHack::DFCoord cursor(x,y,z); DFHack::DFCoord cursor(x,y,z);
MapExtras::MapCache map; MapExtras::MapCache map;
coord_vec all_tiles = brush->points(map, cursor); coord_vec all_tiles = brush->points(map, cursor);
c->con.print("working...\n"); con.print("working...\n");
for (coord_vec::iterator iter = all_tiles.begin(); iter != all_tiles.end(); ++iter) for (coord_vec::iterator iter = all_tiles.begin(); iter != all_tiles.end(); ++iter)
{ {
@ -895,11 +899,11 @@ command_result df_tiletypes (Core * c, vector <string> & parameters)
if (map.WriteAll()) if (map.WriteAll())
{ {
c->con.print("OK\n"); con.print("OK\n");
} }
else else
{ {
c->con.printerr("Something failed horribly! RUN!\n"); con.printerr("Something failed horribly! RUN!\n");
} }
} }
} }

@ -17,23 +17,23 @@ using namespace DFHack;
using namespace df::enums; using namespace df::enums;
using df::global::world; using df::global::world;
command_result tubefill(DFHack::Core * c, std::vector<std::string> & params); command_result tubefill(color_ostream &out, std::vector<std::string> & params);
DFHACK_PLUGIN("tubefill"); DFHACK_PLUGIN("tubefill");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.clear(); commands.clear();
commands.push_back(PluginCommand("tubefill","Fill in all the adamantine tubes again.",tubefill)); commands.push_back(PluginCommand("tubefill","Fill in all the adamantine tubes again.",tubefill));
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
command_result tubefill(DFHack::Core * c, std::vector<std::string> & params) command_result tubefill(color_ostream &out, std::vector<std::string> & params)
{ {
uint64_t count = 0; uint64_t count = 0;
@ -41,16 +41,18 @@ command_result tubefill(DFHack::Core * c, std::vector<std::string> & params)
{ {
if(params[i] == "help" || params[i] == "?") if(params[i] == "help" || params[i] == "?")
{ {
c->con.print("Replenishes mined out adamantine and hollow adamantine tubes.\n" out.print("Replenishes mined out adamantine and hollow adamantine tubes.\n"
"May cause !!FUN!!\n" "May cause !!FUN!!\n"
); );
return CR_OK; return CR_OK;
} }
} }
CoreSuspender suspend(c);
CoreSuspender suspend;
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
@ -102,6 +104,6 @@ command_result tubefill(DFHack::Core * c, std::vector<std::string> & params)
} }
} }
} }
c->con.print("Found and changed %d tiles.\n", count); out.print("Found and changed %d tiles.\n", count);
return CR_OK; return CR_OK;
} }

@ -35,31 +35,33 @@ using df::global::world;
using namespace DFHack::Gui; using namespace DFHack::Gui;
static command_result tweak(Core * c, vector <string> & parameters); static command_result tweak(color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("tweak"); DFHACK_PLUGIN("tweak");
DFhackCExport command_result plugin_init (Core *c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.clear(); commands.clear();
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"tweak", "Various tweaks for minor bugs.", tweak, false, "tweak", "Various tweaks for minor bugs.", tweak, false,
" tweak clear-missing\n" " tweak clear-missing\n"
" Remove the missing status from the selected unit.\n" " Remove the missing status from the selected unit.\n"
" lair\n" " tweak lair\n"
" Mark the map as monster lair\n" " Mark the map as monster lair, preventing item scatter on reclaim.\n"
)); ));
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown (color_ostream &out)
{ {
return CR_OK; return CR_OK;
} }
command_result lair(DFHack::Core * c, std::vector<std::string> & params);
static command_result tweak(Core * c, vector <string> &parameters) static command_result lair(color_ostream &out, std::vector<std::string> & params);
static command_result tweak(color_ostream &out, vector <string> &parameters)
{ {
CoreSuspender suspend(c); CoreSuspender suspend;
if (parameters.empty()) if (parameters.empty())
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
@ -68,7 +70,7 @@ static command_result tweak(Core * c, vector <string> &parameters)
if (cmd == "clear-missing") if (cmd == "clear-missing")
{ {
df::unit *unit = getSelectedUnit(c); df::unit *unit = getSelectedUnit(out);
if (!unit) if (!unit)
return CR_FAILURE; return CR_FAILURE;
@ -85,7 +87,7 @@ static command_result tweak(Core * c, vector <string> &parameters)
} }
else if(cmd == "lair") else if(cmd == "lair")
{ {
return lair(c,parameters); return lair(out,parameters);
} }
else return CR_WRONG_USAGE; else return CR_WRONG_USAGE;
@ -93,22 +95,12 @@ static command_result tweak(Core * c, vector <string> &parameters)
} }
#include "modules/Maps.h" #include "modules/Maps.h"
command_result lair(DFHack::Core * c, std::vector<std::string> & params)
{
for(size_t i = 0; i < params.size();i++)
{
if(params[i] == "help" || params[i] == "?")
{
c->con.print("Makes the map a smonster lair, hopefully preventing item scatter.\n");
return CR_OK;
}
}
Console & con = c->con;
//CoreSuspender suspend(c); command_result lair(color_ostream &out, std::vector<std::string> & params)
{
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
uint32_t x_max,y_max,z_max; uint32_t x_max,y_max,z_max;
@ -124,6 +116,6 @@ command_result lair(DFHack::Core * c, std::vector<std::string> & params)
occupancies[x][y].bits.monster_lair = true; occupancies[x][y].bits.monster_lair = true;
} }
} }
con.print("Map monsterized.\n"); out.print("Map monsterized.\n");
return CR_OK; return CR_OK;
} }

@ -16,16 +16,16 @@ using std::stack;
using namespace DFHack; using namespace DFHack;
using namespace df::enums; using namespace df::enums;
command_result vdig (Core * c, vector <string> & parameters); command_result vdig (color_ostream &out, vector <string> & parameters);
command_result vdigx (Core * c, vector <string> & parameters); command_result vdigx (color_ostream &out, vector <string> & parameters);
command_result autodig (Core * c, vector <string> & parameters); command_result autodig (color_ostream &out, vector <string> & parameters);
command_result expdig (Core * c, vector <string> & parameters); command_result expdig (color_ostream &out, vector <string> & parameters);
command_result digcircle (Core *c, vector <string> & parameters); command_result digcircle (color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("vdig"); DFHACK_PLUGIN("vdig");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.clear(); commands.clear();
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
@ -45,7 +45,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
@ -79,12 +79,12 @@ bool dig (MapExtras::MapCache & MCache,
return false; return false;
if(x == 0 || x == x_max * 16 - 1) if(x == 0 || x == x_max * 16 - 1)
{ {
//c->con.print("not digging map border\n"); //out.print("not digging map border\n");
return false; return false;
} }
if(y == 0 || y == y_max * 16 - 1) if(y == 0 || y == y_max * 16 - 1)
{ {
//c->con.print("not digging map border\n"); //out.print("not digging map border\n");
return false; return false;
} }
df::tiletype tt = MCache.tiletypeAt(at); df::tiletype tt = MCache.tiletypeAt(at);
@ -177,7 +177,7 @@ bool lineY (MapExtras::MapCache & MCache,
return true; return true;
}; };
command_result digcircle (Core * c, vector <string> & parameters) command_result digcircle (color_ostream &out, vector <string> & parameters)
{ {
static bool filled = false; static bool filled = false;
static circle_what what = circle_set; static circle_what what = circle_set;
@ -244,7 +244,7 @@ command_result digcircle (Core * c, vector <string> & parameters)
diameter = -diameter; diameter = -diameter;
if(force_help || diameter == 0) if(force_help || diameter == 0)
{ {
c->con.print( out.print(
"A command for easy designation of filled and hollow circles.\n" "A command for easy designation of filled and hollow circles.\n"
"\n" "\n"
"Options:\n" "Options:\n"
@ -272,10 +272,10 @@ command_result digcircle (Core * c, vector <string> & parameters)
return CR_OK; return CR_OK;
} }
int32_t cx, cy, cz; int32_t cx, cy, cz;
CoreSuspender suspend(c); CoreSuspender suspend;
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
@ -285,7 +285,7 @@ command_result digcircle (Core * c, vector <string> & parameters)
MapExtras::MapCache MCache; MapExtras::MapCache MCache;
if(!Gui::getCursorCoords(cx,cy,cz) || cx == -30000) if(!Gui::getCursorCoords(cx,cy,cz) || cx == -30000)
{ {
c->con.printerr("Can't get the cursor coords...\n"); out.printerr("Can't get the cursor coords...\n");
return CR_FAILURE; return CR_FAILURE;
} }
int r = diameter / 2; int r = diameter / 2;
@ -773,7 +773,7 @@ bool stamp_pattern (uint32_t bx, uint32_t by, int z_level,
return true; return true;
}; };
command_result expdig (Core * c, vector <string> & parameters) command_result expdig (color_ostream &out, vector <string> & parameters)
{ {
bool force_help = false; bool force_help = false;
static explo_how how = EXPLO_NOTHING; static explo_how how = EXPLO_NOTHING;
@ -823,7 +823,7 @@ command_result expdig (Core * c, vector <string> & parameters)
} }
if(force_help || how == EXPLO_NOTHING) if(force_help || how == EXPLO_NOTHING)
{ {
c->con.print( out.print(
"This command can be used for exploratory mining.\n" "This command can be used for exploratory mining.\n"
"http://dwarffortresswiki.org/Exploratory_mining\n" "http://dwarffortresswiki.org/Exploratory_mining\n"
"\n" "\n"
@ -846,18 +846,18 @@ command_result expdig (Core * c, vector <string> & parameters)
); );
return CR_OK; return CR_OK;
} }
CoreSuspender suspend(c); CoreSuspender suspend;
uint32_t x_max, y_max, z_max; uint32_t x_max, y_max, z_max;
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
Maps::getSize(x_max,y_max,z_max); Maps::getSize(x_max,y_max,z_max);
int32_t xzzz,yzzz,z_level; int32_t xzzz,yzzz,z_level;
if(!Gui::getViewCoords(xzzz,yzzz,z_level)) if(!Gui::getViewCoords(xzzz,yzzz,z_level))
{ {
c->con.printerr("Can't get view coords...\n"); out.printerr("Can't get view coords...\n");
return CR_FAILURE; return CR_FAILURE;
} }
if(how == EXPLO_DIAG5) if(how == EXPLO_DIAG5)
@ -949,15 +949,15 @@ command_result expdig (Core * c, vector <string> & parameters)
return CR_OK; return CR_OK;
} }
command_result vdigx (Core * c, vector <string> & parameters) command_result vdigx (color_ostream &out, vector <string> & parameters)
{ {
// HOTKEY COMMAND: CORE ALREADY SUSPENDED // HOTKEY COMMAND: CORE ALREADY SUSPENDED
vector <string> lol; vector <string> lol;
lol.push_back("x"); lol.push_back("x");
return vdig(c,lol); return vdig(out,lol);
} }
command_result vdig (Core * c, vector <string> & parameters) command_result vdig (color_ostream &out, vector <string> & parameters)
{ {
// HOTKEY COMMAND: CORE ALREADY SUSPENDED // HOTKEY COMMAND: CORE ALREADY SUSPENDED
uint32_t x_max,y_max,z_max; uint32_t x_max,y_max,z_max;
@ -970,11 +970,11 @@ command_result vdig (Core * c, vector <string> & parameters)
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
Console & con = c->con; auto &con = out;
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
c->con.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
@ -1114,7 +1114,7 @@ command_result vdig (Core * c, vector <string> & parameters)
return CR_OK; return CR_OK;
} }
command_result autodig (Core * c, vector <string> & parameters) command_result autodig (color_ostream &out, vector <string> & parameters)
{ {
return CR_NOT_IMPLEMENTED; return CR_NOT_IMPLEMENTED;
} }

@ -15,7 +15,7 @@ using namespace std;
#include "modules/Gui.h" #include "modules/Gui.h"
using namespace DFHack; using namespace DFHack;
command_result df_versionosd (Core * c, vector <string> & parameters); command_result df_versionosd (color_ostream &out, vector <string> & parameters);
static DFSDL_Surface* (*_IMG_LoadPNG_RW)(void* src) = 0; static DFSDL_Surface* (*_IMG_LoadPNG_RW)(void* src) = 0;
static vPtr (*_SDL_RWFromFile)(const char* file, const char *mode) = 0; static vPtr (*_SDL_RWFromFile)(const char* file, const char *mode) = 0;
static int (*_SDL_SetAlpha)(vPtr surface, uint32_t flag, uint8_t alpha) = 0; static int (*_SDL_SetAlpha)(vPtr surface, uint32_t flag, uint8_t alpha) = 0;
@ -45,7 +45,7 @@ DFTileSurface* createTile(int x, int y)
return tile; return tile;
} }
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.clear(); commands.clear();
commands.push_back(PluginCommand("versionosd", commands.push_back(PluginCommand("versionosd",
@ -66,7 +66,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
if ( !surface ) if ( !surface )
{ {
c->con.print("Couldnt load image from file %s", file); out.print("Couldnt load image from file %s", file);
return CR_FAILURE; return CR_FAILURE;
} }
@ -99,7 +99,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
Graphic* g = c->getGraphic(); Graphic* g = c->getGraphic();
g->Unregister(gettile); g->Unregister(gettile);
@ -114,12 +114,11 @@ DFhackCExport command_result plugin_shutdown ( Core * c )
return CR_OK; return CR_OK;
} }
command_result df_versionosd (Core * c, vector <string> & parameters) command_result df_versionosd (color_ostream &out, vector <string> & parameters)
{ {
On = !On; On = !On;
c->Suspend(); CoreSuspender suspend;
c->con.print("Version OSD is %s\n", On ? "On" : "Off"); out.print("Version OSD is %s\n", On ? "On" : "Off");
c->Resume();
return CR_OK; return CR_OK;
} }

@ -13,11 +13,11 @@ using namespace DFHack;
bool locked = false; bool locked = false;
unsigned char locked_data[25]; unsigned char locked_data[25];
command_result weather (Core * c, vector <string> & parameters); command_result weather (color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("weather"); DFHACK_PLUGIN("weather");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.clear(); commands.clear();
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
@ -32,14 +32,13 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }
command_result weather (Core * c, vector <string> & parameters) command_result weather (color_ostream &con, vector <string> & parameters)
{ {
Console & con = c->con;
int val_override = -1; int val_override = -1;
bool lock = false; bool lock = false;
bool unlock = false; bool unlock = false;
@ -81,8 +80,9 @@ command_result weather (Core * c, vector <string> & parameters)
} }
bool something = lock || unlock || rain || snow || clear || val_override != -1; bool something = lock || unlock || rain || snow || clear || val_override != -1;
CoreSuspender suspend(c); CoreSuspender suspend;
DFHack::World * w = c->getWorld();
DFHack::World * w = Core::getInstance().getWorld();
if(!w->wmap) if(!w->wmap)
{ {
con << "Weather support seems broken :(" << std::endl; con << "Weather support seems broken :(" << std::endl;

@ -50,14 +50,14 @@ using df::global::job_next_id;
/* Plugin registration */ /* Plugin registration */
static command_result workflow_cmd(Core *c, vector <string> & parameters); static command_result workflow_cmd(color_ostream &out, vector <string> & parameters);
static void init_state(Core *c); static void init_state(color_ostream &out);
static void cleanup_state(Core *c); static void cleanup_state(color_ostream &out);
DFHACK_PLUGIN("workflow"); DFHACK_PLUGIN("workflow");
DFhackCExport command_result plugin_init (Core *c, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.clear(); commands.clear();
if (!world || !ui) if (!world || !ui)
@ -118,27 +118,27 @@ DFhackCExport command_result plugin_init (Core *c, std::vector <PluginCommand> &
); );
} }
init_state(c); init_state(out);
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result plugin_shutdown (color_ostream &out)
{ {
cleanup_state(c); cleanup_state(out);
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_onstatechange(Core* c, state_change_event event) DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event)
{ {
switch (event) { switch (event) {
case SC_GAME_LOADED: case SC_GAME_LOADED:
cleanup_state(c); cleanup_state(out);
init_state(c); init_state(out);
break; break;
case SC_GAME_UNLOADED: case SC_GAME_UNLOADED:
cleanup_state(c); cleanup_state(out);
break; break;
default: default:
break; break;
@ -392,12 +392,12 @@ static void setOptionEnabled(ConfigFlags flag, bool on)
* STATE INITIALIZATION * * STATE INITIALIZATION *
******************************/ ******************************/
static void stop_protect(Core *c) static void stop_protect(color_ostream &out)
{ {
pending_recover.clear(); pending_recover.clear();
if (!known_jobs.empty()) if (!known_jobs.empty())
c->con.print("Unprotecting %d jobs.\n", known_jobs.size()); out.print("Unprotecting %d jobs.\n", known_jobs.size());
for (TKnownJobs::iterator it = known_jobs.begin(); it != known_jobs.end(); ++it) for (TKnownJobs::iterator it = known_jobs.begin(); it != known_jobs.end(); ++it)
delete it->second; delete it->second;
@ -405,31 +405,33 @@ static void stop_protect(Core *c)
known_jobs.clear(); known_jobs.clear();
} }
static void cleanup_state(Core *c) static void cleanup_state(color_ostream &out)
{ {
config = PersistentDataItem(); config = PersistentDataItem();
stop_protect(c); stop_protect(out);
for (size_t i = 0; i < constraints.size(); i++) for (size_t i = 0; i < constraints.size(); i++)
delete constraints[i]; delete constraints[i];
constraints.clear(); constraints.clear();
} }
static void check_lost_jobs(Core *c, int ticks); static void check_lost_jobs(color_ostream &out, int ticks);
static ItemConstraint *get_constraint(Core *c, const std::string &str, PersistentDataItem *cfg = NULL); static ItemConstraint *get_constraint(color_ostream &out, const std::string &str, PersistentDataItem *cfg = NULL);
static void start_protect(Core *c) static void start_protect(color_ostream &out)
{ {
check_lost_jobs(c, 0); check_lost_jobs(out, 0);
if (!known_jobs.empty()) if (!known_jobs.empty())
c->con.print("Protecting %d jobs.\n", known_jobs.size()); out.print("Protecting %d jobs.\n", known_jobs.size());
} }
static void init_state(Core *c) static void init_state(color_ostream &out)
{ {
config = c->getWorld()->GetPersistentData("workflow/config"); auto pworld = Core::getInstance().getWorld();
config = pworld->GetPersistentData("workflow/config");
if (config.isValid() && config.ival(0) == -1) if (config.isValid() && config.ival(0) == -1)
config.ival(0) = 0; config.ival(0) = 0;
@ -437,14 +439,14 @@ static void init_state(Core *c)
// Parse constraints // Parse constraints
std::vector<PersistentDataItem> items; std::vector<PersistentDataItem> items;
c->getWorld()->GetPersistentData(&items, "workflow/constraints"); pworld->GetPersistentData(&items, "workflow/constraints");
for (int i = items.size()-1; i >= 0; i--) { for (int i = items.size()-1; i >= 0; i--) {
if (get_constraint(c, items[i].val(), &items[i])) if (get_constraint(out, items[i].val(), &items[i]))
continue; continue;
c->con.printerr("Lost constraint %s\n", items[i].val().c_str()); out.printerr("Lost constraint %s\n", items[i].val().c_str());
c->getWorld()->DeletePersistentData(items[i]); pworld->DeletePersistentData(items[i]);
} }
last_tick_frame_count = world->frame_counter; last_tick_frame_count = world->frame_counter;
@ -453,35 +455,37 @@ static void init_state(Core *c)
if (!enabled) if (!enabled)
return; return;
start_protect(c); start_protect(out);
} }
static void enable_plugin(Core *c) static void enable_plugin(color_ostream &out)
{ {
auto pworld = Core::getInstance().getWorld();
if (!config.isValid()) if (!config.isValid())
{ {
config = c->getWorld()->AddPersistentData("workflow/config"); config = pworld->AddPersistentData("workflow/config");
config.ival(0) = 0; config.ival(0) = 0;
} }
setOptionEnabled(CF_ENABLED, true); setOptionEnabled(CF_ENABLED, true);
enabled = true; enabled = true;
c->con << "Enabling the plugin." << endl; out << "Enabling the plugin." << endl;
start_protect(c); start_protect(out);
} }
/****************************** /******************************
* JOB AUTO-RECOVERY * * JOB AUTO-RECOVERY *
******************************/ ******************************/
static void forget_job(Core *c, ProtectedJob *pj) static void forget_job(color_ostream &out, ProtectedJob *pj)
{ {
known_jobs.erase(pj->id); known_jobs.erase(pj->id);
delete pj; delete pj;
} }
static bool recover_job(Core *c, ProtectedJob *pj) static bool recover_job(color_ostream &out, ProtectedJob *pj)
{ {
if (pj->isLive()) if (pj->isLive())
return true; return true;
@ -490,18 +494,18 @@ static bool recover_job(Core *c, ProtectedJob *pj)
pj->holder = df::building::find(pj->building_id); pj->holder = df::building::find(pj->building_id);
if (!pj->holder) if (!pj->holder)
{ {
c->con.printerr("Forgetting job %d (%s): holder building lost.", out.printerr("Forgetting job %d (%s): holder building lost.",
pj->id, ENUM_KEY_STR(job_type, pj->job_copy->job_type)); pj->id, ENUM_KEY_STR(job_type, pj->job_copy->job_type));
forget_job(c, pj); forget_job(out, pj);
return true; return true;
} }
// Check its state and postpone or cancel if invalid // Check its state and postpone or cancel if invalid
if (pj->holder->jobs.size() >= 10) if (pj->holder->jobs.size() >= 10)
{ {
c->con.printerr("Forgetting job %d (%s): holder building has too many jobs.", out.printerr("Forgetting job %d (%s): holder building has too many jobs.",
pj->id, ENUM_KEY_STR(job_type, pj->job_copy->job_type)); pj->id, ENUM_KEY_STR(job_type, pj->job_copy->job_type));
forget_job(c, pj); forget_job(out, pj);
return true; return true;
} }
@ -522,7 +526,7 @@ static bool recover_job(Core *c, ProtectedJob *pj)
{ {
deleteJobStruct(recovered); deleteJobStruct(recovered);
c->con.printerr("Inconsistency: job %d (%s) already in list.", out.printerr("Inconsistency: job %d (%s) already in list.",
pj->id, ENUM_KEY_STR(job_type, pj->job_copy->job_type)); pj->id, ENUM_KEY_STR(job_type, pj->job_copy->job_type));
return true; return true;
} }
@ -534,7 +538,7 @@ static bool recover_job(Core *c, ProtectedJob *pj)
return true; return true;
} }
static void check_lost_jobs(Core *c, int ticks) static void check_lost_jobs(color_ostream &out, int ticks)
{ {
ProtectedJob::cur_tick_idx++; ProtectedJob::cur_tick_idx++;
if (ticks < 0) ticks = 0; if (ticks < 0) ticks = 0;
@ -548,7 +552,7 @@ static void check_lost_jobs(Core *c, int ticks)
if (pj) if (pj)
{ {
if (!job->flags.bits.repeat) if (!job->flags.bits.repeat)
forget_job(c, pj); forget_job(out, pj);
else else
pj->tick_job(job, ticks); pj->tick_job(job, ticks);
} }
@ -571,7 +575,7 @@ static void check_lost_jobs(Core *c, int ticks)
} }
} }
static void update_job_data(Core *c) static void update_job_data(color_ostream &out)
{ {
df::job_list_link *p = world->job_list.next; df::job_list_link *p = world->job_list.next;
for (; p; p = p->next) for (; p; p = p->next)
@ -583,16 +587,16 @@ static void update_job_data(Core *c)
} }
} }
static void recover_jobs(Core *c) static void recover_jobs(color_ostream &out)
{ {
for (int i = pending_recover.size()-1; i >= 0; i--) for (int i = pending_recover.size()-1; i >= 0; i--)
if (recover_job(c, pending_recover[i])) if (recover_job(out, pending_recover[i]))
vector_erase_at(pending_recover, i); vector_erase_at(pending_recover, i);
} }
static void process_constraints(Core *c); static void process_constraints(color_ostream &out);
DFhackCExport command_result plugin_onupdate(Core* c) DFhackCExport command_result plugin_onupdate(color_ostream &out)
{ {
if (!enabled) if (!enabled)
return CR_OK; return CR_OK;
@ -602,7 +606,7 @@ DFhackCExport command_result plugin_onupdate(Core* c)
if ((++cnt % 5) != 0) if ((++cnt % 5) != 0)
return CR_OK; return CR_OK;
check_lost_jobs(c, world->frame_counter - last_tick_frame_count); check_lost_jobs(out, world->frame_counter - last_tick_frame_count);
last_tick_frame_count = world->frame_counter; last_tick_frame_count = world->frame_counter;
// Proceed every in-game half-day, or when jobs to recover changed // Proceed every in-game half-day, or when jobs to recover changed
@ -611,7 +615,7 @@ DFhackCExport command_result plugin_onupdate(Core* c)
if (pending_recover.size() != last_rlen || check_time) if (pending_recover.size() != last_rlen || check_time)
{ {
recover_jobs(c); recover_jobs(out);
last_rlen = pending_recover.size(); last_rlen = pending_recover.size();
// If the half-day passed, proceed to update // If the half-day passed, proceed to update
@ -619,8 +623,8 @@ DFhackCExport command_result plugin_onupdate(Core* c)
{ {
last_frame_count = world->frame_counter; last_frame_count = world->frame_counter;
update_job_data(c); update_job_data(out);
process_constraints(c); process_constraints(out);
} }
} }
@ -631,7 +635,7 @@ DFhackCExport command_result plugin_onupdate(Core* c)
* ITEM COUNT CONSTRAINT * * ITEM COUNT CONSTRAINT *
******************************/ ******************************/
static ItemConstraint *get_constraint(Core *c, const std::string &str, PersistentDataItem *cfg) static ItemConstraint *get_constraint(color_ostream &out, const std::string &str, PersistentDataItem *cfg)
{ {
std::vector<std::string> tokens; std::vector<std::string> tokens;
split_string(&tokens, str, "/"); split_string(&tokens, str, "/");
@ -643,7 +647,7 @@ static ItemConstraint *get_constraint(Core *c, const std::string &str, Persisten
ItemTypeInfo item; ItemTypeInfo item;
if (!item.find(tokens[0]) || !item.isValid()) { if (!item.find(tokens[0]) || !item.isValid()) {
c->con.printerr("Cannot find item type: %s\n", tokens[0].c_str()); out.printerr("Cannot find item type: %s\n", tokens[0].c_str());
return NULL; return NULL;
} }
@ -653,7 +657,7 @@ static ItemConstraint *get_constraint(Core *c, const std::string &str, Persisten
df::dfhack_material_category mat_mask; df::dfhack_material_category mat_mask;
std::string maskstr = vector_get(tokens,1); std::string maskstr = vector_get(tokens,1);
if (!maskstr.empty() && !parseJobMaterialCategory(&mat_mask, maskstr)) { if (!maskstr.empty() && !parseJobMaterialCategory(&mat_mask, maskstr)) {
c->con.printerr("Cannot decode material mask: %s\n", maskstr.c_str()); out.printerr("Cannot decode material mask: %s\n", maskstr.c_str());
return NULL; return NULL;
} }
@ -663,7 +667,7 @@ static ItemConstraint *get_constraint(Core *c, const std::string &str, Persisten
MaterialInfo material; MaterialInfo material;
std::string matstr = vector_get(tokens,2); std::string matstr = vector_get(tokens,2);
if (!matstr.empty() && (!material.find(matstr) || !material.isValid())) { if (!matstr.empty() && (!material.find(matstr) || !material.isValid())) {
c->con.printerr("Cannot find material: %s\n", matstr.c_str()); out.printerr("Cannot find material: %s\n", matstr.c_str());
return NULL; return NULL;
} }
@ -671,7 +675,7 @@ static ItemConstraint *get_constraint(Core *c, const std::string &str, Persisten
weight += (material.index >= 0 ? 5000 : 1000); weight += (material.index >= 0 ? 5000 : 1000);
if (mat_mask.whole && material.isValid() && !material.matches(mat_mask)) { if (mat_mask.whole && material.isValid() && !material.matches(mat_mask)) {
c->con.printerr("Material %s doesn't match mask %s\n", matstr.c_str(), maskstr.c_str()); out.printerr("Material %s doesn't match mask %s\n", matstr.c_str(), maskstr.c_str());
return NULL; return NULL;
} }
@ -693,7 +697,7 @@ static ItemConstraint *get_constraint(Core *c, const std::string &str, Persisten
nct->config = *cfg; nct->config = *cfg;
else else
{ {
nct->config = c->getWorld()->AddPersistentData("workflow/constraints"); nct->config = Core::getInstance().getWorld()->AddPersistentData("workflow/constraints");
nct->init(str); nct->init(str);
} }
@ -701,13 +705,13 @@ static ItemConstraint *get_constraint(Core *c, const std::string &str, Persisten
return nct; return nct;
} }
static void delete_constraint(Core *c, ItemConstraint *cv) static void delete_constraint(color_ostream &out, ItemConstraint *cv)
{ {
int idx = linear_index(constraints, cv); int idx = linear_index(constraints, cv);
if (idx >= 0) if (idx >= 0)
vector_erase_at(constraints, idx); vector_erase_at(constraints, idx);
c->getWorld()->DeletePersistentData(cv->config); Core::getInstance().getWorld()->DeletePersistentData(cv->config);
delete cv; delete cv;
} }
@ -858,7 +862,7 @@ static void guess_job_material(df::job *job, MaterialInfo &mat, df::dfhack_mater
} }
} }
static void compute_job_outputs(Core *c, ProtectedJob *pj) static void compute_job_outputs(color_ostream &out, ProtectedJob *pj)
{ {
using namespace df::enums::job_type; using namespace df::enums::job_type;
@ -946,7 +950,7 @@ static void compute_job_outputs(Core *c, ProtectedJob *pj)
link_job_constraint(pj, itype, isubtype, mat_mask, mat.type, mat.index); link_job_constraint(pj, itype, isubtype, mat_mask, mat.type, mat.index);
} }
static void map_job_constraints(Core *c) static void map_job_constraints(color_ostream &out)
{ {
melt_active = false; melt_active = false;
@ -968,7 +972,7 @@ static void map_job_constraints(Core *c)
if (!melt_active && pj->actual_job->job_type == job_type::MeltMetalObject) if (!melt_active && pj->actual_job->job_type == job_type::MeltMetalObject)
melt_active = pj->isResumed(); melt_active = pj->isResumed();
compute_job_outputs(c, pj); compute_job_outputs(out, pj);
} }
} }
@ -1046,7 +1050,7 @@ static bool itemInRealJob(df::item *item)
!= job_type_class::Hauling; != job_type_class::Hauling;
} }
static void map_job_items(Core *c) static void map_job_items(color_ostream &out)
{ {
for (size_t i = 0; i < constraints.size(); i++) for (size_t i = 0; i < constraints.size(); i++)
{ {
@ -1159,7 +1163,7 @@ static void map_job_items(Core *c)
static std::string shortJobDescription(df::job *job); static std::string shortJobDescription(df::job *job);
static void setJobResumed(Core *c, ProtectedJob *pj, bool goal) static void setJobResumed(color_ostream &out, ProtectedJob *pj, bool goal)
{ {
bool current = pj->isResumed(); bool current = pj->isResumed();
@ -1167,14 +1171,14 @@ static void setJobResumed(Core *c, ProtectedJob *pj, bool goal)
if (goal != current) if (goal != current)
{ {
c->con.print("%s %s%s\n", out.print("%s %s%s\n",
(goal ? "Resuming" : "Suspending"), (goal ? "Resuming" : "Suspending"),
shortJobDescription(pj->actual_job).c_str(), shortJobDescription(pj->actual_job).c_str(),
(!goal || pj->isActuallyResumed() ? "" : " (delayed)")); (!goal || pj->isActuallyResumed() ? "" : " (delayed)"));
} }
} }
static void update_jobs_by_constraints(Core *c) static void update_jobs_by_constraints(color_ostream &out)
{ {
for (TKnownJobs::const_iterator it = known_jobs.begin(); it != known_jobs.end(); ++it) for (TKnownJobs::const_iterator it = known_jobs.begin(); it != known_jobs.end(); ++it)
{ {
@ -1185,7 +1189,7 @@ static void update_jobs_by_constraints(Core *c)
if (pj->actual_job->job_type == job_type::MeltMetalObject && if (pj->actual_job->job_type == job_type::MeltMetalObject &&
isOptionEnabled(CF_AUTOMELT)) isOptionEnabled(CF_AUTOMELT))
{ {
setJobResumed(c, pj, meltable_count > 0); setJobResumed(out, pj, meltable_count > 0);
continue; continue;
} }
@ -1210,7 +1214,7 @@ static void update_jobs_by_constraints(Core *c)
else if (suspend_weight >= 0 && suspend_weight >= resume_weight) else if (suspend_weight >= 0 && suspend_weight >= resume_weight)
goal = false; goal = false;
setJobResumed(c, pj, goal); setJobResumed(out, pj, goal);
} }
for (size_t i = 0; i < constraints.size(); i++) for (size_t i = 0; i < constraints.size(); i++)
@ -1250,15 +1254,15 @@ static void update_jobs_by_constraints(Core *c)
} }
} }
static void process_constraints(Core *c) static void process_constraints(color_ostream &out)
{ {
if (constraints.empty() && if (constraints.empty() &&
!isOptionEnabled(CF_DRYBUCKETS | CF_AUTOMELT)) !isOptionEnabled(CF_DRYBUCKETS | CF_AUTOMELT))
return; return;
map_job_constraints(c); map_job_constraints(out);
map_job_items(c); map_job_items(out);
update_jobs_by_constraints(c); update_jobs_by_constraints(out);
} }
/****************************** /******************************
@ -1286,7 +1290,7 @@ static std::string shortJobDescription(df::job *job)
return rv; return rv;
} }
static void print_constraint(Core *c, ItemConstraint *cv, bool no_job = false, std::string prefix = "") static void print_constraint(color_ostream &out, ItemConstraint *cv, bool no_job = false, std::string prefix = "")
{ {
Console::color_value color; Console::color_value color;
if (cv->request_resume) if (cv->request_resume)
@ -1296,24 +1300,24 @@ static void print_constraint(Core *c, ItemConstraint *cv, bool no_job = false, s
else else
color = Console::COLOR_DARKGREY; color = Console::COLOR_DARKGREY;
c->con.color(color); out.color(color);
c->con << prefix << "Constraint " << flush; out << prefix << "Constraint " << flush;
c->con.color(Console::COLOR_GREY); out.color(Console::COLOR_GREY);
c->con << cv->config.val() << " " << flush; out << cv->config.val() << " " << flush;
c->con.color(color); out.color(color);
c->con << (cv->goalByCount() ? "count " : "amount ") out << (cv->goalByCount() ? "count " : "amount ")
<< cv->goalCount() << " (gap " << cv->goalGap() << ")" << endl; << cv->goalCount() << " (gap " << cv->goalGap() << ")" << endl;
c->con.reset_color(); out.reset_color();
if (cv->item_count || cv->item_inuse) if (cv->item_count || cv->item_inuse)
c->con << prefix << " items: amount " << cv->item_amount << "; " out << prefix << " items: amount " << cv->item_amount << "; "
<< cv->item_count << " stacks available, " << cv->item_count << " stacks available, "
<< cv->item_inuse << " in use." << endl; << cv->item_inuse << " in use." << endl;
if (no_job) return; if (no_job) return;
if (cv->jobs.empty()) if (cv->jobs.empty())
c->con.printerr(" (no jobs)\n"); out.printerr(" (no jobs)\n");
std::vector<ProtectedJob*> unique_jobs; std::vector<ProtectedJob*> unique_jobs;
std::vector<int> unique_counts; std::vector<int> unique_counts;
@ -1347,79 +1351,79 @@ static void print_constraint(Core *c, ItemConstraint *cv, bool no_job = false, s
{ {
if (pj->want_resumed) if (pj->want_resumed)
{ {
c->con.color(Console::COLOR_YELLOW); out.color(Console::COLOR_YELLOW);
c->con << start << " (delayed)" << endl; out << start << " (delayed)" << endl;
} }
else else
{ {
c->con.color(Console::COLOR_BLUE); out.color(Console::COLOR_BLUE);
c->con << start << " (suspended)" << endl; out << start << " (suspended)" << endl;
} }
} }
else else
{ {
c->con.color(Console::COLOR_GREEN); out.color(Console::COLOR_GREEN);
c->con << start << endl; out << start << endl;
} }
c->con.reset_color(); out.reset_color();
if (unique_counts[i] > 1) if (unique_counts[i] > 1)
c->con << prefix << " (" << unique_counts[i] << " copies)" << endl; out << prefix << " (" << unique_counts[i] << " copies)" << endl;
} }
} }
static void print_job(Core *c, ProtectedJob *pj) static void print_job(color_ostream &out, ProtectedJob *pj)
{ {
if (!pj) if (!pj)
return; return;
df::job *job = pj->isLive() ? pj->actual_job : pj->job_copy; df::job *job = pj->isLive() ? pj->actual_job : pj->job_copy;
printJobDetails(c, job); printJobDetails(out, job);
if (job->job_type == job_type::MeltMetalObject && if (job->job_type == job_type::MeltMetalObject &&
isOptionEnabled(CF_AUTOMELT)) isOptionEnabled(CF_AUTOMELT))
{ {
if (meltable_count <= 0) if (meltable_count <= 0)
c->con.color(Console::COLOR_CYAN); out.color(Console::COLOR_CYAN);
else if (pj->want_resumed && !pj->isActuallyResumed()) else if (pj->want_resumed && !pj->isActuallyResumed())
c->con.color(Console::COLOR_YELLOW); out.color(Console::COLOR_YELLOW);
else else
c->con.color(Console::COLOR_GREEN); out.color(Console::COLOR_GREEN);
c->con << " Meltable: " << meltable_count << " objects." << endl; out << " Meltable: " << meltable_count << " objects." << endl;
c->con.reset_color(); out.reset_color();
} }
for (size_t i = 0; i < pj->constraints.size(); i++) for (size_t i = 0; i < pj->constraints.size(); i++)
print_constraint(c, pj->constraints[i], true, " "); print_constraint(out, pj->constraints[i], true, " ");
} }
static command_result workflow_cmd(Core *c, vector <string> & parameters) static command_result workflow_cmd(color_ostream &out, vector <string> & parameters)
{ {
CoreSuspender suspend(c); CoreSuspender suspend;
if (!c->isWorldLoaded()) { if (!Core::getInstance().isWorldLoaded()) {
c->con.printerr("World is not loaded: please load a game first.\n"); out.printerr("World is not loaded: please load a game first.\n");
return CR_FAILURE; return CR_FAILURE;
} }
if (enabled) { if (enabled) {
check_lost_jobs(c, 0); check_lost_jobs(out, 0);
recover_jobs(c); recover_jobs(out);
update_job_data(c); update_job_data(out);
map_job_constraints(c); map_job_constraints(out);
map_job_items(c); map_job_items(out);
} }
df::building *workshop = NULL; df::building *workshop = NULL;
df::job *job = NULL; df::job *job = NULL;
if (Gui::dwarfmode_hotkey(c, c->getTopViewscreen()) && if (Gui::dwarfmode_hotkey(Core::getTopViewscreen()) &&
ui->main.mode == ui_sidebar_mode::QueryBuilding) ui->main.mode == ui_sidebar_mode::QueryBuilding)
{ {
workshop = world->selected_building; workshop = world->selected_building;
job = Gui::getSelectedWorkshopJob(c, true); job = Gui::getSelectedWorkshopJob(out, true);
} }
std::string cmd = parameters.empty() ? "list" : parameters[0]; std::string cmd = parameters.empty() ? "list" : parameters[0];
@ -1429,7 +1433,7 @@ static command_result workflow_cmd(Core *c, vector <string> & parameters)
bool enable = (cmd == "enable"); bool enable = (cmd == "enable");
if (enable && !enabled) if (enable && !enabled)
{ {
enable_plugin(c); enable_plugin(out);
} }
else if (!enable && parameters.size() == 1) else if (!enable && parameters.size() == 1)
{ {
@ -1437,10 +1441,10 @@ static command_result workflow_cmd(Core *c, vector <string> & parameters)
{ {
enabled = false; enabled = false;
setOptionEnabled(CF_ENABLED, false); setOptionEnabled(CF_ENABLED, false);
stop_protect(c); stop_protect(out);
} }
c->con << "The plugin is disabled." << endl; out << "The plugin is disabled." << endl;
return CR_OK; return CR_OK;
} }
@ -1455,38 +1459,38 @@ static command_result workflow_cmd(Core *c, vector <string> & parameters)
} }
if (enabled) if (enabled)
c->con << "The plugin is enabled." << endl; out << "The plugin is enabled." << endl;
else else
c->con << "The plugin is disabled." << endl; out << "The plugin is disabled." << endl;
if (isOptionEnabled(CF_DRYBUCKETS)) if (isOptionEnabled(CF_DRYBUCKETS))
c->con << "Option drybuckets is enabled." << endl; out << "Option drybuckets is enabled." << endl;
if (isOptionEnabled(CF_AUTOMELT)) if (isOptionEnabled(CF_AUTOMELT))
c->con << "Option auto-melt is enabled." << endl; out << "Option auto-melt is enabled." << endl;
return CR_OK; return CR_OK;
} }
else if (cmd == "count" || cmd == "amount") else if (cmd == "count" || cmd == "amount")
{ {
if (!enabled) if (!enabled)
enable_plugin(c); enable_plugin(out);
} }
if (!enabled) if (!enabled)
c->con << "Note: the plugin is not enabled." << endl; out << "Note: the plugin is not enabled." << endl;
if (cmd == "jobs") if (cmd == "jobs")
{ {
if (workshop) if (workshop)
{ {
for (size_t i = 0; i < workshop->jobs.size(); i++) for (size_t i = 0; i < workshop->jobs.size(); i++)
print_job(c, get_known(workshop->jobs[i]->id)); print_job(out, get_known(workshop->jobs[i]->id));
} }
else else
{ {
for (TKnownJobs::iterator it = known_jobs.begin(); it != known_jobs.end(); ++it) for (TKnownJobs::iterator it = known_jobs.begin(); it != known_jobs.end(); ++it)
if (it->second->isLive()) if (it->second->isLive())
print_job(c, it->second); print_job(out, it->second);
} }
bool pending = false; bool pending = false;
@ -1497,11 +1501,11 @@ static command_result workflow_cmd(Core *c, vector <string> & parameters)
{ {
if (!pending) if (!pending)
{ {
c->con.print("\nPending recovery:\n"); out.print("\nPending recovery:\n");
pending = true; pending = true;
} }
printJobDetails(c, pending_recover[i]->job_copy); printJobDetails(out, pending_recover[i]->job_copy);
} }
} }
@ -1510,7 +1514,7 @@ static command_result workflow_cmd(Core *c, vector <string> & parameters)
else if (cmd == "list") else if (cmd == "list")
{ {
for (size_t i = 0; i < constraints.size(); i++) for (size_t i = 0; i < constraints.size(); i++)
print_constraint(c, constraints[i]); print_constraint(out, constraints[i]);
return CR_OK; return CR_OK;
} }
@ -1521,11 +1525,11 @@ static command_result workflow_cmd(Core *c, vector <string> & parameters)
int limit = atoi(parameters[2].c_str()); int limit = atoi(parameters[2].c_str());
if (limit <= 0) { if (limit <= 0) {
c->con.printerr("Invalid limit value.\n"); out.printerr("Invalid limit value.\n");
return CR_FAILURE; return CR_FAILURE;
} }
ItemConstraint *icv = get_constraint(c, parameters[1]); ItemConstraint *icv = get_constraint(out, parameters[1]);
if (!icv) if (!icv)
return CR_FAILURE; return CR_FAILURE;
@ -1536,8 +1540,8 @@ static command_result workflow_cmd(Core *c, vector <string> & parameters)
else else
icv->setGoalGap(-1); icv->setGoalGap(-1);
process_constraints(c); process_constraints(out);
print_constraint(c, icv); print_constraint(out, icv);
return CR_OK; return CR_OK;
} }
else if (cmd == "unlimit") else if (cmd == "unlimit")
@ -1550,11 +1554,11 @@ static command_result workflow_cmd(Core *c, vector <string> & parameters)
if (constraints[i]->config.val() != parameters[1]) if (constraints[i]->config.val() != parameters[1])
continue; continue;
delete_constraint(c, constraints[i]); delete_constraint(out, constraints[i]);
return CR_OK; return CR_OK;
} }
c->con.printerr("Constraint not found: %s\n", parameters[1].c_str()); out.printerr("Constraint not found: %s\n", parameters[1].c_str());
return CR_FAILURE; return CR_FAILURE;
} }
else else