Merge branch 'master' of git://github.com/angavrilov/dfhack

develop
jj 2012-06-11 16:00:00 +02:00
commit 95606ee3dc
24 changed files with 272 additions and 115 deletions

@ -726,7 +726,7 @@ Units module
* ``dfhack.units.isDead(unit)`` * ``dfhack.units.isDead(unit)``
The unit is completely dead and passive. The unit is completely dead and passive, or a ghost.
* ``dfhack.units.isAlive(unit)`` * ``dfhack.units.isAlive(unit)``
@ -734,7 +734,16 @@ Units module
* ``dfhack.units.isSane(unit)`` * ``dfhack.units.isSane(unit)``
The unit is capable of rational action, i.e. not dead, insane or zombie. The unit is capable of rational action, i.e. not dead, insane, zombie, or active werewolf.
* ``dfhack.units.isDwarf(unit)``
The unit is of the correct race of the fortress.
* ``dfhack.units.isCitizen(unit)``
The unit is an alive sane citizen of the fortress; wraps the
same checks the game uses to decide game-over by extinction.
* ``dfhack.units.getAge(unit[,true_age])`` * ``dfhack.units.getAge(unit[,true_age])``

@ -960,13 +960,20 @@ a lua list containing them.</p>
<p>Returns the nemesis record of the unit if it has one, or <em>nil</em>.</p> <p>Returns the nemesis record of the unit if it has one, or <em>nil</em>.</p>
</li> </li>
<li><p class="first"><tt class="docutils literal">dfhack.units.isDead(unit)</tt></p> <li><p class="first"><tt class="docutils literal">dfhack.units.isDead(unit)</tt></p>
<p>The unit is completely dead and passive.</p> <p>The unit is completely dead and passive, or a ghost.</p>
</li> </li>
<li><p class="first"><tt class="docutils literal">dfhack.units.isAlive(unit)</tt></p> <li><p class="first"><tt class="docutils literal">dfhack.units.isAlive(unit)</tt></p>
<p>The unit isn't dead or undead.</p> <p>The unit isn't dead or undead.</p>
</li> </li>
<li><p class="first"><tt class="docutils literal">dfhack.units.isSane(unit)</tt></p> <li><p class="first"><tt class="docutils literal">dfhack.units.isSane(unit)</tt></p>
<p>The unit is capable of rational action, i.e. not dead, insane or zombie.</p> <p>The unit is capable of rational action, i.e. not dead, insane, zombie, or active werewolf.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.units.isDwarf(unit)</tt></p>
<p>The unit is of the correct race of the fortress.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.units.isCitizen(unit)</tt></p>
<p>The unit is an alive sane citizen of the fortress; wraps the
same checks the game uses to decide game-over by extinction.</p>
</li> </li>
<li><p class="first"><tt class="docutils literal"><span class="pre">dfhack.units.getAge(unit[,true_age])</span></tt></p> <li><p class="first"><tt class="docutils literal"><span class="pre">dfhack.units.getAge(unit[,true_age])</span></tt></p>
<p>Returns the age of the unit in years as a floating-point value. <p>Returns the age of the unit in years as a floating-point value.

@ -200,7 +200,9 @@ google/protobuf/compiler/zip_writer.cc
LIST(APPEND LIBPROTOBUF_FULL_SRCS ${LIBPROTOBUF_LITE_SRCS}) LIST(APPEND LIBPROTOBUF_FULL_SRCS ${LIBPROTOBUF_LITE_SRCS})
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -Wno-sign-compare") IF(CMAKE_COMPILER_IS_GNUCC)
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -Wno-sign-compare")
ENDIF()
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
SET(PROTOBUF_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}) SET(PROTOBUF_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR})

@ -13,6 +13,9 @@ keybinding add Ctrl-Shift-K autodump-destroy-here
# any item: # any item:
keybinding add Ctrl-K autodump-destroy-item keybinding add Ctrl-K autodump-destroy-item
# quicksave, only in main dwarfmode screen and menu page
keybinding add Ctrl-Alt-S@dwarfmode/Default quicksave
############################## ##############################
# Generic adv mode bindings # # Generic adv mode bindings #
############################## ##############################

@ -208,6 +208,8 @@ IF(UNIX)
SET_SOURCE_FILES_PROPERTIES(DataStatics.cpp DataStaticsCtor.cpp DataStaticsFields.cpp SET_SOURCE_FILES_PROPERTIES(DataStatics.cpp DataStaticsCtor.cpp DataStaticsFields.cpp
PROPERTIES COMPILE_FLAGS "-g0 -O1") PROPERTIES COMPILE_FLAGS "-g0 -O1")
ELSE(WIN32) ELSE(WIN32)
SET_SOURCE_FILES_PROPERTIES(DataStatics.cpp DataStaticsCtor.cpp DataStaticsFields.cpp
PROPERTIES COMPILE_FLAGS "/O1 /bigobj")
ENDIF() ENDIF()

@ -715,6 +715,8 @@ static const LuaWrapper::FunctionReg dfhack_units_module[] = {
WRAPM(Units, isDead), WRAPM(Units, isDead),
WRAPM(Units, isAlive), WRAPM(Units, isAlive),
WRAPM(Units, isSane), WRAPM(Units, isSane),
WRAPM(Units, isDwarf),
WRAPM(Units, isCitizen),
WRAPM(Units, getAge), WRAPM(Units, getAge),
WRAPM(Units, getProfessionName), WRAPM(Units, getProfessionName),
WRAPM(Units, getCasteProfessionName), WRAPM(Units, getCasteProfessionName),

@ -107,7 +107,7 @@ void VersionInfoFactory::ParseVersion (TiXmlElement* entry, VersionInfo* mem)
} }
else else
{ {
throw Error::SymbolsXmlBadAttribute("os-type"); return; // ignore it if it's invalid
} }
// process additional entries // process additional entries

@ -160,6 +160,17 @@ INSTANTIATE_WRAPPERS(6, (OSTREAM_ARG,A1,A2,A3,A4,A5,A6), (out,vA1,vA2,vA3,vA4,vA
#define FW_TARGS class A1, class A2, class A3, class A4, class A5, class A6, class A7 #define FW_TARGS class A1, class A2, class A3, class A4, class A5, class A6, class A7
INSTANTIATE_RETURN_TYPE((A1,A2,A3,A4,A5,A6,A7)) INSTANTIATE_RETURN_TYPE((A1,A2,A3,A4,A5,A6,A7))
INSTANTIATE_WRAPPERS(7, (A1,A2,A3,A4,A5,A6,A7), (vA1,vA2,vA3,vA4,vA5,vA6,vA7),
LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3);
LOAD_ARG(A4); LOAD_ARG(A5); LOAD_ARG(A6);
LOAD_ARG(A7);)
INSTANTIATE_WRAPPERS(7, (OSTREAM_ARG,A1,A2,A3,A4,A5,A6,A7), (out,vA1,vA2,vA3,vA4,vA5,vA6,vA7),
LOAD_OSTREAM(out); LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3);
LOAD_ARG(A4); LOAD_ARG(A5); LOAD_ARG(A6); LOAD_ARG(A7);)
#undef FW_TARGS
#define FW_TARGS class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8
INSTANTIATE_RETURN_TYPE((A1,A2,A3,A4,A5,A6,A7,A8))
#undef FW_TARGS #undef FW_TARGS
#undef FW_TARGSC #undef FW_TARGSC

@ -37,16 +37,6 @@ distribution.
namespace DFHack namespace DFHack
{ {
/**
* \ingroup grp_world
*/
enum WeatherType
{
CLEAR,
RAINING,
SNOWING
};
typedef unsigned char weather_map [5][5];
/** /**
* \ingroup grp_world * \ingroup grp_world
*/ */
@ -113,7 +103,6 @@ namespace DFHack
class DFHACK_EXPORT World : public Module class DFHACK_EXPORT World : public Module
{ {
public: public:
weather_map * wmap;
World(); World();
~World(); ~World();
bool Start(); bool Start();

@ -58,12 +58,14 @@ using namespace DFHack;
#include "df/viewscreen_layer_overall_healthst.h" #include "df/viewscreen_layer_overall_healthst.h"
#include "df/viewscreen_layer_assigntradest.h" #include "df/viewscreen_layer_assigntradest.h"
#include "df/viewscreen_layer_militaryst.h" #include "df/viewscreen_layer_militaryst.h"
#include "df/viewscreen_layer_stockpilest.h"
#include "df/viewscreen_petst.h" #include "df/viewscreen_petst.h"
#include "df/viewscreen_tradegoodsst.h" #include "df/viewscreen_tradegoodsst.h"
#include "df/viewscreen_storesst.h" #include "df/viewscreen_storesst.h"
#include "df/ui_unit_view_mode.h" #include "df/ui_unit_view_mode.h"
#include "df/ui_sidebar_menus.h" #include "df/ui_sidebar_menus.h"
#include "df/ui_look_list.h" #include "df/ui_look_list.h"
#include "df/ui_advmode.h"
#include "df/job.h" #include "df/job.h"
#include "df/ui_build_selector.h" #include "df/ui_build_selector.h"
#include "df/building_workshopst.h" #include "df/building_workshopst.h"
@ -273,7 +275,9 @@ DEFINE_GET_FOCUS_STRING_HANDLER(dwarfmode)
break; break;
case Burrows: case Burrows:
if (ui->burrows.in_add_units_mode) if (ui->burrows.in_confirm_delete)
focus += "/ConfirmDelete";
else if (ui->burrows.in_add_units_mode)
focus += "/AddUnits"; focus += "/AddUnits";
else if (ui->burrows.in_edit_name_mode) else if (ui->burrows.in_edit_name_mode)
focus += "/EditName"; focus += "/EditName";
@ -288,6 +292,16 @@ DEFINE_GET_FOCUS_STRING_HANDLER(dwarfmode)
} }
} }
DEFINE_GET_FOCUS_STRING_HANDLER(dungeonmode)
{
using df::global::ui_advmode;
if (!ui_advmode)
return;
focus += "/" + enum_item_key(ui_advmode->menu);
}
DEFINE_GET_FOCUS_STRING_HANDLER(unitlist) DEFINE_GET_FOCUS_STRING_HANDLER(unitlist)
{ {
focus += "/" + enum_item_key(screen->page); focus += "/" + enum_item_key(screen->page);
@ -407,6 +421,35 @@ DEFINE_GET_FOCUS_STRING_HANDLER(stores)
focus += "/Items"; focus += "/Items";
} }
DEFINE_GET_FOCUS_STRING_HANDLER(layer_stockpile)
{
auto list1 = getLayerList(screen, 0);
auto list2 = getLayerList(screen, 1);
auto list3 = getLayerList(screen, 2);
if (!list1 || !list2 || !list3 || !screen->settings) return;
auto group = screen->cur_group;
if (group != vector_get(screen->group_ids, list1->cursor))
return;
focus += "/" + enum_item_key(group);
auto bits = vector_get(screen->group_bits, list1->cursor);
if (bits.whole && !(bits.whole & screen->settings->flags.whole))
{
focus += "/Off";
return;
}
focus += "/On";
if (list2->bright || list3->bright || screen->list_ids.empty()) {
focus += "/" + enum_item_key(screen->cur_list);
if (list3->bright)
focus += (screen->item_names.empty() ? "/None" : "/Item");
}
}
std::string Gui::getFocusString(df::viewscreen *top) std::string Gui::getFocusString(df::viewscreen *top)
{ {
@ -998,16 +1041,29 @@ bool Gui::setDesignationCoords (const int32_t x, const int32_t y, const int32_t
bool Gui::getMousePos (int32_t & x, int32_t & y) bool Gui::getMousePos (int32_t & x, int32_t & y)
{ {
x = gps->mouse_x; if (gps) {
y = gps->mouse_y; x = gps->mouse_x;
y = gps->mouse_y;
}
else {
x = -1;
y = -1;
}
return (x == -1) ? false : true; return (x == -1) ? false : true;
} }
bool Gui::getWindowSize (int32_t &width, int32_t &height) bool Gui::getWindowSize (int32_t &width, int32_t &height)
{ {
width = gps->dimx; if (gps) {
height = gps->dimy; width = gps->dimx;
return true; height = gps->dimy;
return true;
}
else {
width = 80;
height = 25;
return false;
}
} }
bool Gui::getMenuWidth(uint8_t &menu_width, uint8_t &area_map_width) bool Gui::getMenuWidth(uint8_t &menu_width, uint8_t &area_map_width)

@ -761,8 +761,8 @@ bool Materials::ReadCreatureTypesEx (void)
{ {
df::body_part_raw *bp = ca->body_info.body_parts[k]; df::body_part_raw *bp = ca->body_info.body_parts[k];
t_bodypart part; t_bodypart part;
part.id = bp->part_code; part.id = bp->token;
part.category = bp->part_name; part.category = bp->category;
caste.bodypart.push_back(part); caste.bodypart.push_back(part);
} }
using namespace df::enums::mental_attribute_type; using namespace df::enums::mental_attribute_type;

@ -613,12 +613,45 @@ df::nemesis_record *Units::getNemesis(df::unit *unit)
return NULL; return NULL;
} }
static bool casteFlagSet(int race, int caste, df::caste_raw_flags flag)
{
auto creature = df::creature_raw::find(race);
if (!creature)
return false;
auto craw = vector_get(creature->caste, caste);
if (!craw)
return false;
return craw->flags.is_set(flag);
}
static bool isCrazed(df::unit *unit)
{
if (unit->flags3.bits.scuttle)
return false;
if (unit->curse.rem_tags1.bits.CRAZED)
return false;
if (unit->curse.add_tags1.bits.CRAZED)
return true;
return casteFlagSet(unit->race, unit->caste, caste_raw_flags::CRAZED);
}
static bool isOpposedToLife(df::unit *unit)
{
if (unit->curse.rem_tags1.bits.OPPOSED_TO_LIFE)
return false;
if (unit->curse.add_tags1.bits.OPPOSED_TO_LIFE)
return true;
return casteFlagSet(unit->race, unit->caste, caste_raw_flags::CANNOT_UNDEAD);
}
bool DFHack::Units::isDead(df::unit *unit) bool DFHack::Units::isDead(df::unit *unit)
{ {
CHECK_NULL_POINTER(unit); CHECK_NULL_POINTER(unit);
return unit->flags1.bits.dead; return unit->flags1.bits.dead ||
unit->flags3.bits.ghostly;
} }
bool DFHack::Units::isAlive(df::unit *unit) bool DFHack::Units::isAlive(df::unit *unit)
@ -636,8 +669,11 @@ bool DFHack::Units::isSane(df::unit *unit)
if (unit->flags1.bits.dead || if (unit->flags1.bits.dead ||
unit->flags3.bits.ghostly || unit->flags3.bits.ghostly ||
unit->curse.add_tags1.bits.OPPOSED_TO_LIFE || isOpposedToLife(unit) ||
unit->curse.add_tags1.bits.CRAZED) unit->unknown8.unk2)
return false;
if (unit->unknown8.normal_race == unit->unknown8.were_race && isCrazed(unit))
return false; return false;
switch (unit->mood) switch (unit->mood)
@ -657,19 +693,38 @@ bool DFHack::Units::isCitizen(df::unit *unit)
{ {
CHECK_NULL_POINTER(unit); CHECK_NULL_POINTER(unit);
// Copied from the conditions used to decide game over,
// except that the game appears to let melancholy/raving
// dwarves count as citizens.
if (!isDwarf(unit) || !isSane(unit))
return false;
if (unit->flags1.bits.marauder ||
unit->flags1.bits.invader_origin ||
unit->flags1.bits.active_invader ||
unit->flags1.bits.forest ||
unit->flags1.bits.merchant ||
unit->flags1.bits.diplomat)
return false;
if (unit->flags1.bits.tame)
return true;
return unit->civ_id == ui->civ_id && return unit->civ_id == ui->civ_id &&
!unit->flags1.bits.merchant && unit->civ_id != -1 &&
!unit->flags1.bits.diplomat && !unit->flags2.bits.underworld &&
!unit->flags2.bits.resident && !unit->flags2.bits.resident &&
!unit->flags1.bits.dead && !unit->flags2.bits.visitor_uninvited &&
!unit->flags3.bits.ghostly; !unit->flags2.bits.visitor;
} }
bool DFHack::Units::isDwarf(df::unit *unit) bool DFHack::Units::isDwarf(df::unit *unit)
{ {
CHECK_NULL_POINTER(unit); CHECK_NULL_POINTER(unit);
return unit->race == ui->race_id; return unit->race == ui->race_id ||
unit->unknown8.normal_race == ui->race_id;
} }
double DFHack::Units::getAge(df::unit *unit, bool true_age) double DFHack::Units::getAge(df::unit *unit, bool true_age)

@ -34,10 +34,12 @@ distribution.
#include "modules/Windows.h" #include "modules/Windows.h"
using namespace DFHack; using namespace DFHack;
using df::global::gps;
Windows::df_screentile *Windows::getScreenBuffer() Windows::df_screentile *Windows::getScreenBuffer()
{ {
return (df_screentile *) df::global::gps->screen; if (!gps) return NULL;
return (df_screentile *) gps->screen;
} }
Windows::df_window::df_window(int x, int y, unsigned int width, unsigned int height) Windows::df_window::df_window(int x, int y, unsigned int width, unsigned int height)
@ -79,7 +81,7 @@ bool Windows::df_window::unlock (painter * painter)
return false; return false;
} }
Windows::top_level_window::top_level_window(): df_window(0,0,df::global::gps->dimx,df::global::gps->dimy) Windows::top_level_window::top_level_window() : df_window(0,0,gps ? gps->dimx : 80,gps ? gps->dimy : 25)
{ {
buffer = 0; buffer = 0;
} }

@ -63,15 +63,8 @@ struct World::Private
bool Inited; bool Inited;
bool PauseInited; bool PauseInited;
void * pause_state_offset;
bool StartedWeather; bool StartedWeather;
char * weather_offset;
bool StartedMode; bool StartedMode;
void * gamemode_offset;
void * controlmode_offset;
void * controlmodecopy_offset;
int next_persistent_id; int next_persistent_id;
std::multimap<std::string, int> persistent_index; std::multimap<std::string, int> persistent_index;
@ -86,21 +79,14 @@ World::World()
Core & c = Core::getInstance(); Core & c = Core::getInstance();
d = new Private; d = new Private;
d->owner = c.p; d->owner = c.p;
wmap = 0;
d->pause_state_offset = (void *) c.vinfo->getAddress ("pause_state"); if(df::global::pause_state)
if(d->pause_state_offset)
d->PauseInited = true; d->PauseInited = true;
d->weather_offset = (char *) c.vinfo->getAddress( "current_weather" ); if(df::global::current_weather)
if(d->weather_offset)
{
wmap = (weather_map *) d->weather_offset;
d->StartedWeather = true; d->StartedWeather = true;
} if (df::global::game_mode && df::global::control_mode)
d->gamemode_offset = (void *) c.vinfo->getAddress( "game_mode" ); d->StartedMode = true;
d->controlmode_offset = (void *) c.vinfo->getAddress( "control_mode" );
d->StartedMode = true;
d->Inited = true; d->Inited = true;
} }
@ -123,14 +109,13 @@ bool World::Finish()
bool World::ReadPauseState() bool World::ReadPauseState()
{ {
if(!d->PauseInited) return false; if(!d->PauseInited) return false;
uint8_t pauseState = d->owner->readByte (d->pause_state_offset); return *df::global::pause_state;
return pauseState & 1;
} }
void World::SetPauseState(bool paused) void World::SetPauseState(bool paused)
{ {
if(!d->PauseInited) return; if (d->PauseInited)
d->owner->writeByte (d->pause_state_offset, paused); *df::global::pause_state = paused;
} }
uint32_t World::ReadCurrentYear() uint32_t World::ReadCurrentYear()
@ -147,8 +132,8 @@ bool World::ReadGameMode(t_gamemodes& rd)
{ {
if(d->Inited && d->StartedMode) if(d->Inited && d->StartedMode)
{ {
rd.g_mode = (GameMode) d->owner->readDWord( d->controlmode_offset); rd.g_mode = (DFHack::GameMode)*df::global::control_mode;
rd.g_type = (GameType) d->owner->readDWord(d->gamemode_offset); rd.g_type = (DFHack::GameType)*df::global::game_mode;
return true; return true;
} }
return false; return false;
@ -157,8 +142,8 @@ bool World::WriteGameMode(const t_gamemodes & wr)
{ {
if(d->Inited && d->StartedMode) if(d->Inited && d->StartedMode)
{ {
d->owner->writeDWord(d->gamemode_offset,wr.g_type); *df::global::control_mode = wr.g_mode;
d->owner->writeDWord(d->controlmode_offset,wr.g_mode); *df::global::game_mode = wr.g_type;
return true; return true;
} }
return false; return false;
@ -199,18 +184,14 @@ uint32_t World::ReadCurrentDay()
uint8_t World::ReadCurrentWeather() uint8_t World::ReadCurrentWeather()
{ {
if (d->Inited && d->StartedWeather) if (d->Inited && d->StartedWeather)
return(d->owner->readByte(d->weather_offset + 12)); return (*df::global::current_weather)[2][2];
return 0; return 0;
} }
void World::SetCurrentWeather(uint8_t weather) void World::SetCurrentWeather(uint8_t weather)
{ {
if (d->Inited && d->StartedWeather) if (d->Inited && d->StartedWeather)
{ memset(df::global::current_weather, weather, 25);
uint8_t buf[25];
memset(&buf,weather, sizeof(buf));
d->owner->write(d->weather_offset,sizeof(buf),buf);
}
} }
string World::ReadWorldFolder() string World::ReadWorldFolder()

@ -1 +1 @@
Subproject commit 234d0f57a927f306f2052fc2f45d38b3201ddee6 Subproject commit 0a0dc568dff80396efd1b2c9a6ef1614df5786f7

@ -706,7 +706,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out )
{ {
static int step_count = 0; static int step_count = 0;
// check run conditions // check run conditions
if(!world->map.block_index || !enable_autolabor) if(!world || !world->map.block_index || !enable_autolabor)
{ {
// give up if we shouldn't be running' // give up if we shouldn't be running'
return CR_OK; return CR_OK;

@ -25,7 +25,7 @@ command_result df_counters (color_ostream &out, vector <string> & parameters)
for (size_t i = 0; i < counters.size(); i++) for (size_t i = 0; i < counters.size(); i++)
{ {
auto counter = counters[i]; auto counter = counters[i];
out.print("%i (%s): %i\n", counter->id, ENUM_KEY_STR(unit_misc_trait::T_id, counter->id).c_str(), counter->value); out.print("%i (%s): %i\n", counter->id, ENUM_KEY_STR(misc_trait_type, counter->id).c_str(), counter->value);
} }
return CR_OK; return CR_OK;

@ -89,13 +89,13 @@ static void element(const char* name, const uint32_t content, ostream& out, cons
static void printAttributes(color_ostream &con, 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].value, out, " ");
} }
df::unit_soul * s = cre->status.current_soul; df::unit_soul * s = cre->status.current_soul;
if (s) { if (s) {
for (int i = 0; i < NUM_CREATURE_MENTAL_ATTRIBUTES; i++) { for (int i = 0; i < NUM_CREATURE_MENTAL_ATTRIBUTES; i++) {
element(mentals[i], s->mental_attrs[i].unk1, out, " "); element(mentals[i], s->mental_attrs[i].value, out, " ");
} }
} }
out << " </Attributes>" << endl; out << " </Attributes>" << endl;

@ -28,7 +28,7 @@ static int enable_fastdwarf = false;
DFhackCExport command_result plugin_onupdate ( color_ostream &out ) DFhackCExport command_result plugin_onupdate ( color_ostream &out )
{ {
// check run conditions // check run conditions
if(!world->map.block_index || !enable_fastdwarf) if(!world || !world->map.block_index || !enable_fastdwarf)
{ {
// give up if we shouldn't be running' // give up if we shouldn't be running'
return CR_OK; return CR_OK;

@ -28,7 +28,7 @@ using namespace std;
#include "df/body_part_raw.h" #include "df/body_part_raw.h"
#include "MiscUtils.h" #include "MiscUtils.h"
#include "df/unit_inventory_item.h" #include "df/unit_inventory_item.h"
#include "df/body_part_template_flags.h" #include "df/body_part_raw_flags.h"
#include "df/creature_raw.h" #include "df/creature_raw.h"
#include "df/caste_raw.h" #include "df/caste_raw.h"
#include "df/body_detail_plan.h" #include "df/body_detail_plan.h"
@ -292,7 +292,7 @@ static bool moveToInventory(MapExtras::MapCache &mc, df::item *item, df::unit *u
else if (bpIndex < unit->body.body_plan->body_parts.size()) else if (bpIndex < unit->body.body_plan->body_parts.size())
{ {
// The current body part is not the one that was specified in the function call, but we can keep searching // The current body part is not the one that was specified in the function call, but we can keep searching
if (verbose) { Core::printerr("Found bodypart %s; not a match; continuing search.\n", currPart->part_code.c_str()); } if (verbose) { Core::printerr("Found bodypart %s; not a match; continuing search.\n", currPart->token.c_str()); }
continue; continue;
} }
else else
@ -302,35 +302,35 @@ static bool moveToInventory(MapExtras::MapCache &mc, df::item *item, df::unit *u
return false; return false;
} }
if (verbose) { Core::print("Inspecting bodypart %s.\n", currPart->part_code.c_str()); } if (verbose) { Core::print("Inspecting bodypart %s.\n", currPart->token.c_str()); }
// Inspect the current bodypart // Inspect the current bodypart
if (item->getType() == df::enums::item_type::GLOVES && currPart->flags.is_set(df::body_part_template_flags::GRASP) && if (item->getType() == df::enums::item_type::GLOVES && currPart->flags.is_set(df::body_part_raw_flags::GRASP) &&
((item->getGloveHandedness() == const_GloveLeftHandedness && currPart->flags.is_set(df::body_part_template_flags::LEFT)) || ((item->getGloveHandedness() == const_GloveLeftHandedness && currPart->flags.is_set(df::body_part_raw_flags::LEFT)) ||
(item->getGloveHandedness() == const_GloveRightHandedness && currPart->flags.is_set(df::body_part_template_flags::RIGHT)))) (item->getGloveHandedness() == const_GloveRightHandedness && currPart->flags.is_set(df::body_part_raw_flags::RIGHT))))
{ {
if (verbose) { Core::print("Hand found (%s)...", currPart->part_code.c_str()); } if (verbose) { Core::print("Hand found (%s)...", currPart->token.c_str()); }
} }
else if (item->getType() == df::enums::item_type::HELM && currPart->flags.is_set(df::body_part_template_flags::HEAD)) else if (item->getType() == df::enums::item_type::HELM && currPart->flags.is_set(df::body_part_raw_flags::HEAD))
{ {
if (verbose) { Core::print("Head found (%s)...", currPart->part_code.c_str()); } if (verbose) { Core::print("Head found (%s)...", currPart->token.c_str()); }
} }
else if (item->getType() == df::enums::item_type::ARMOR && currPart->flags.is_set(df::body_part_template_flags::UPPERBODY)) else if (item->getType() == df::enums::item_type::ARMOR && currPart->flags.is_set(df::body_part_raw_flags::UPPERBODY))
{ {
if (verbose) { Core::print("Upper body found (%s)...", currPart->part_code.c_str()); } if (verbose) { Core::print("Upper body found (%s)...", currPart->token.c_str()); }
} }
else if (item->getType() == df::enums::item_type::PANTS && currPart->flags.is_set(df::body_part_template_flags::LOWERBODY)) else if (item->getType() == df::enums::item_type::PANTS && currPart->flags.is_set(df::body_part_raw_flags::LOWERBODY))
{ {
if (verbose) { Core::print("Lower body found (%s)...", currPart->part_code.c_str()); } if (verbose) { Core::print("Lower body found (%s)...", currPart->token.c_str()); }
} }
else if (item->getType() == df::enums::item_type::SHOES && currPart->flags.is_set(df::body_part_template_flags::STANCE)) else if (item->getType() == df::enums::item_type::SHOES && currPart->flags.is_set(df::body_part_raw_flags::STANCE))
{ {
if (verbose) { Core::print("Foot found (%s)...", currPart->part_code.c_str()); } if (verbose) { Core::print("Foot found (%s)...", currPart->token.c_str()); }
} }
else if (targetBodyPart && ignoreRestrictions) else if (targetBodyPart && ignoreRestrictions)
{ {
// The BP in question would normally be considered ineligible for equipment. But since it was deliberately specified by the user, we'll proceed anyways. // The BP in question would normally be considered ineligible for equipment. But since it was deliberately specified by the user, we'll proceed anyways.
if (verbose) { Core::print("Non-standard bodypart found (%s)...", targetBodyPart->part_code.c_str()); } if (verbose) { Core::print("Non-standard bodypart found (%s)...", targetBodyPart->token.c_str()); }
} }
else if (targetBodyPart) else if (targetBodyPart)
{ {
@ -538,16 +538,16 @@ command_result df_forceequip(color_ostream &out, vector <string> & parameters)
{ {
// Tentatively assume that the part is a match // Tentatively assume that the part is a match
targetBodyPart = targetUnit->body.body_plan->body_parts.at(bpIndex); targetBodyPart = targetUnit->body.body_plan->body_parts.at(bpIndex);
if (targetBodyPart->part_code.compare(targetBodyPartCode) == 0) if (targetBodyPart->token.compare(targetBodyPartCode) == 0)
{ {
// It is indeed a match; exit the loop (while leaving the variable populated) // It is indeed a match; exit the loop (while leaving the variable populated)
if (verbose) { out.print("Matching bodypart (%s) found.\n", targetBodyPart->part_name.c_str()); } if (verbose) { out.print("Matching bodypart (%s) found.\n", targetBodyPart->token.c_str()); }
break; break;
} }
else else
{ {
// Not a match; nullify the variable (it will get re-populated on the next pass through the loop) // Not a match; nullify the variable (it will get re-populated on the next pass through the loop)
if (verbose) { out.printerr("Bodypart \"%s\" does not match \"%s\".\n", targetBodyPart->part_code.c_str(), targetBodyPartCode.c_str()); } if (verbose) { out.printerr("Bodypart \"%s\" does not match \"%s\".\n", targetBodyPart->token.c_str(), targetBodyPartCode.c_str()); }
targetBodyPart = NULL; targetBodyPart = NULL;
} }
} }

@ -100,37 +100,37 @@ command_result df_showmood (color_ostream &out, vector <string> & parameters)
switch (job->job_type) switch (job->job_type)
{ {
case job_type::StrangeMoodCrafter: case job_type::StrangeMoodCrafter:
out.print("become a Craftsdwarf (or Engraver)"); out.print("claim a Craftsdwarf's Workshop");
break; break;
case job_type::StrangeMoodJeweller: case job_type::StrangeMoodJeweller:
out.print("become a Jeweler"); out.print("claim a Jeweler's Workshop");
break; break;
case job_type::StrangeMoodForge: case job_type::StrangeMoodForge:
out.print("become a Metalworker"); out.print("claim a Metalsmith's Forge");
break; break;
case job_type::StrangeMoodMagmaForge: case job_type::StrangeMoodMagmaForge:
out.print("become a Metalworker using a Magma Forge"); out.print("claim a Magma Forge");
break; break;
case job_type::StrangeMoodCarpenter: case job_type::StrangeMoodCarpenter:
out.print("become a Carpenter"); out.print("claim a Carpenter's Workshop");
break; break;
case job_type::StrangeMoodMason: case job_type::StrangeMoodMason:
out.print("become a Mason (or Miner)"); out.print("claim a Mason's Workshop");
break; break;
case job_type::StrangeMoodBowyer: case job_type::StrangeMoodBowyer:
out.print("become a Bowyer"); out.print("claim a Boywer's Workshop");
break; break;
case job_type::StrangeMoodTanner: case job_type::StrangeMoodTanner:
out.print("become a Leatherworker (or Tanner)"); out.print("claim a Leather Works");
break; break;
case job_type::StrangeMoodWeaver: case job_type::StrangeMoodWeaver:
out.print("become a Clothier (or Weaver)"); out.print("claim a Clothier's Shop");
break; break;
case job_type::StrangeMoodGlassmaker: case job_type::StrangeMoodGlassmaker:
out.print("become a Glassmaker"); out.print("claim a Glass Furnace");
break; break;
case job_type::StrangeMoodMechanics: case job_type::StrangeMoodMechanics:
out.print("become a Mechanic"); out.print("claim a Mechanic's Workshop");
break; break;
case job_type::StrangeMoodBrooding: case job_type::StrangeMoodBrooding:
out.print("enter a macabre mood?"); out.print("enter a macabre mood?");
@ -142,20 +142,28 @@ command_result df_showmood (color_ostream &out, vector <string> & parameters)
out.print("do something else..."); out.print("do something else...");
break; break;
} }
out.print(" and become a legendary %s", ENUM_ATTR_STR(job_skill, caption_noun, unit->job.mood_skill));
if (unit->mood == mood_type::Possessed)
out.print(" (but not really)");
break; break;
default: default:
out.print("insane?"); out.print("insane?");
break; break;
} }
out.print(".\n");
if (unit->sex)
out.print("He has ");
else
out.print("She has ");
if (building) if (building)
{ {
string name; string name;
building->getName(&name); building->getName(&name);
out.print(" and has claimed a %s\n", name.c_str()); out.print("claimed a %s and wants", name.c_str());
} }
else else
out.print(" and has not yet claimed a workshop\n"); out.print("not yet claimed a workshop but will want");
out.print(" the following items:\n");
for (size_t i = 0; i < job->job_items.size(); i++) for (size_t i = 0; i < job->job_items.size(); i++)
{ {

@ -5,10 +5,13 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include "modules/World.h" #include "modules/World.h"
#include "DataDefs.h"
#include "df/weather_type.h"
using std::vector; using std::vector;
using std::string; using std::string;
using namespace DFHack; using namespace DFHack;
using namespace df::enums;
bool locked = false; bool locked = false;
unsigned char locked_data[25]; unsigned char locked_data[25];
@ -82,7 +85,7 @@ command_result weather (color_ostream &con, vector <string> & parameters)
CoreSuspender suspend; CoreSuspender suspend;
DFHack::World * w = Core::getInstance().getWorld(); DFHack::World * w = Core::getInstance().getWorld();
if(!w->wmap) if(!df::global::current_weather)
{ {
con << "Weather support seems broken :(" << std::endl; con << "Weather support seems broken :(" << std::endl;
return CR_FAILURE; return CR_FAILURE;
@ -95,19 +98,19 @@ command_result weather (color_ostream &con, vector <string> & parameters)
{ {
for(int x = 0; x<5;x++) for(int x = 0; x<5;x++)
{ {
switch((*w->wmap)[x][y]) switch((*df::global::current_weather)[x][y])
{ {
case CLEAR: case weather_type::None:
con << "C "; con << "C ";
break; break;
case RAINING: case weather_type::Rain:
con << "R "; con << "R ";
break; break;
case SNOWING: case weather_type::Snow:
con << "S "; con << "S ";
break; break;
default: default:
con << (int) (*w->wmap)[x][y] << " "; con << (int) (*df::global::current_weather)[x][y] << " ";
break; break;
} }
} }
@ -120,17 +123,17 @@ command_result weather (color_ostream &con, vector <string> & parameters)
if(rain) if(rain)
{ {
con << "Here comes the rain." << std::endl; con << "Here comes the rain." << std::endl;
w->SetCurrentWeather(RAINING); w->SetCurrentWeather(weather_type::Rain);
} }
if(snow) if(snow)
{ {
con << "Snow everywhere!" << std::endl; con << "Snow everywhere!" << std::endl;
w->SetCurrentWeather(SNOWING); w->SetCurrentWeather(weather_type::Snow);
} }
if(clear) if(clear)
{ {
con << "Suddenly, sunny weather!" << std::endl; con << "Suddenly, sunny weather!" << std::endl;
w->SetCurrentWeather(CLEAR); w->SetCurrentWeather(weather_type::None);
} }
if(val_override != -1) if(val_override != -1)
{ {

@ -965,6 +965,9 @@ static void compute_job_outputs(color_ostream &out, ProtectedJob *pj)
mat.decode(mat.plant->material_defs.type_##tag, \ mat.decode(mat.plant->material_defs.type_##tag, \
mat.plant->material_defs.idx_##tag); \ mat.plant->material_defs.idx_##tag); \
else mat.decode(-1); else mat.decode(-1);
case BrewDrink:
PLANT_PROCESS_MAT(DRINK, drink);
break;
case MillPlants: case MillPlants:
PLANT_PROCESS_MAT(MILL, mill); PLANT_PROCESS_MAT(MILL, mill);
break; break;

@ -0,0 +1,24 @@
-- Makes fat dwarves non-fat.
--
-- See for more info:
-- http://www.bay12games.com/dwarves/mantisbt/view.php?id=5971
local num_fat = 0
local num_lagging = 0
for _,v in ipairs(df.global.world.units.all) do
local fat = v.counters2.stored_fat
if fat > 850000 then
v.counters2.stored_fat = 500000
if v.race == df.global.ui.race_id then
print(fat,dfhack.TranslateName(dfhack.units.getVisibleName(v)))
num_fat = num_fat + 1
if fat > 999990 then
num_lagging = num_lagging + 1
end
end
end
end
print("Fat dwarves cured: "..num_fat)
print("Lag sources: "..num_lagging)