From 9adf310d7f162ba58da764bed2c918487c692f6b Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Tue, 22 May 2012 12:31:37 +0400
Subject: [PATCH 01/17] Update Units::isCitizen after looking at game-over
detection code.
---
LUA_API.rst | 13 +++++--
Lua API.html | 11 ++++--
library/LuaApi.cpp | 2 ++
library/modules/Units.cpp | 71 ++++++++++++++++++++++++++++++++++-----
library/xml | 2 +-
5 files changed, 86 insertions(+), 13 deletions(-)
diff --git a/LUA_API.rst b/LUA_API.rst
index b0f1a9f31..9fb37375d 100644
--- a/LUA_API.rst
+++ b/LUA_API.rst
@@ -726,7 +726,7 @@ Units module
* ``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)``
@@ -734,7 +734,16 @@ Units module
* ``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])``
diff --git a/Lua API.html b/Lua API.html
index 4b763af25..1576652d6 100644
--- a/Lua API.html
+++ b/Lua API.html
@@ -960,13 +960,20 @@ a lua list containing them.
dfhack.units.getAge(unit[,true_age])
Returns the age of the unit in years as a floating-point value.
diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp
index 6a550db87..8e8a3c4e3 100644
--- a/library/LuaApi.cpp
+++ b/library/LuaApi.cpp
@@ -715,6 +715,8 @@ static const LuaWrapper::FunctionReg dfhack_units_module[] = {
WRAPM(Units, isDead),
WRAPM(Units, isAlive),
WRAPM(Units, isSane),
+ WRAPM(Units, isDwarf),
+ WRAPM(Units, isCitizen),
WRAPM(Units, getAge),
WRAPM(Units, getProfessionName),
WRAPM(Units, getCasteProfessionName),
diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp
index dd26109e7..ee383cc07 100644
--- a/library/modules/Units.cpp
+++ b/library/modules/Units.cpp
@@ -613,12 +613,45 @@ df::nemesis_record *Units::getNemesis(df::unit *unit)
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)
{
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)
@@ -636,8 +669,11 @@ bool DFHack::Units::isSane(df::unit *unit)
if (unit->flags1.bits.dead ||
unit->flags3.bits.ghostly ||
- unit->curse.add_tags1.bits.OPPOSED_TO_LIFE ||
- unit->curse.add_tags1.bits.CRAZED)
+ isOpposedToLife(unit) ||
+ unit->unknown8.unk2)
+ return false;
+
+ if (unit->unknown8.normal_race == unit->unknown8.were_race && isCrazed(unit))
return false;
switch (unit->mood)
@@ -657,19 +693,38 @@ bool DFHack::Units::isCitizen(df::unit *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 &&
- !unit->flags1.bits.merchant &&
- !unit->flags1.bits.diplomat &&
+ unit->civ_id != -1 &&
+ !unit->flags2.bits.underworld &&
!unit->flags2.bits.resident &&
- !unit->flags1.bits.dead &&
- !unit->flags3.bits.ghostly;
+ !unit->flags2.bits.visitor_uninvited &&
+ !unit->flags2.bits.visitor;
}
bool DFHack::Units::isDwarf(df::unit *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)
diff --git a/library/xml b/library/xml
index 234d0f57a..d991d47b0 160000
--- a/library/xml
+++ b/library/xml
@@ -1 +1 @@
-Subproject commit 234d0f57a927f306f2052fc2f45d38b3201ddee6
+Subproject commit d991d47b0f6709205c4e333bb86edb3dcf656429
From 65349039f0f735224982bece5ac294300915cb8d Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Tue, 22 May 2012 17:50:48 +0400
Subject: [PATCH 02/17] Fix workflow bug: properly deduce the output material
of BrewDrink jobs.
---
plugins/workflow.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/plugins/workflow.cpp b/plugins/workflow.cpp
index 1092c86ae..dbf546070 100644
--- a/plugins/workflow.cpp
+++ b/plugins/workflow.cpp
@@ -965,6 +965,9 @@ static void compute_job_outputs(color_ostream &out, ProtectedJob *pj)
mat.decode(mat.plant->material_defs.type_##tag, \
mat.plant->material_defs.idx_##tag); \
else mat.decode(-1);
+ case BrewDrink:
+ PLANT_PROCESS_MAT(DRINK, drink);
+ break;
case MillPlants:
PLANT_PROCESS_MAT(MILL, mill);
break;
From 9a73ea9f14900f8b6fb132f4c0e242f0c4d5a262 Mon Sep 17 00:00:00 2001
From: Quietust
Date: Wed, 23 May 2012 12:51:03 -0500
Subject: [PATCH 03/17] Cleanup World module to use df::global, and fix crashes
when control_mode/game_mode are missing
---
library/include/modules/World.h | 11 --------
library/modules/World.cpp | 45 ++++++++++-----------------------
plugins/weather.cpp | 21 ++++++++-------
3 files changed, 25 insertions(+), 52 deletions(-)
diff --git a/library/include/modules/World.h b/library/include/modules/World.h
index e7b17ce41..81ebfbd60 100644
--- a/library/include/modules/World.h
+++ b/library/include/modules/World.h
@@ -37,16 +37,6 @@ distribution.
namespace DFHack
{
- /**
- * \ingroup grp_world
- */
- enum WeatherType
- {
- CLEAR,
- RAINING,
- SNOWING
- };
- typedef unsigned char weather_map [5][5];
/**
* \ingroup grp_world
*/
@@ -113,7 +103,6 @@ namespace DFHack
class DFHACK_EXPORT World : public Module
{
public:
- weather_map * wmap;
World();
~World();
bool Start();
diff --git a/library/modules/World.cpp b/library/modules/World.cpp
index 6f6a69a59..4b50b44ca 100644
--- a/library/modules/World.cpp
+++ b/library/modules/World.cpp
@@ -63,15 +63,8 @@ struct World::Private
bool Inited;
bool PauseInited;
- void * pause_state_offset;
-
bool StartedWeather;
- char * weather_offset;
-
bool StartedMode;
- void * gamemode_offset;
- void * controlmode_offset;
- void * controlmodecopy_offset;
int next_persistent_id;
std::multimap persistent_index;
@@ -86,21 +79,14 @@ World::World()
Core & c = Core::getInstance();
d = new Private;
d->owner = c.p;
- wmap = 0;
- d->pause_state_offset = (void *) c.vinfo->getAddress ("pause_state");
- if(d->pause_state_offset)
+ if(df::global::pause_state)
d->PauseInited = true;
- d->weather_offset = (char *) c.vinfo->getAddress( "current_weather" );
- if(d->weather_offset)
- {
- wmap = (weather_map *) d->weather_offset;
+ if(df::global::current_weather)
d->StartedWeather = true;
- }
- d->gamemode_offset = (void *) c.vinfo->getAddress( "game_mode" );
- d->controlmode_offset = (void *) c.vinfo->getAddress( "control_mode" );
- d->StartedMode = true;
+ if (df::global::game_mode && df::global::control_mode)
+ d->StartedMode = true;
d->Inited = true;
}
@@ -123,14 +109,13 @@ bool World::Finish()
bool World::ReadPauseState()
{
if(!d->PauseInited) return false;
- uint8_t pauseState = d->owner->readByte (d->pause_state_offset);
- return pauseState & 1;
+ return *df::global::pause_state;
}
void World::SetPauseState(bool paused)
{
- if(!d->PauseInited) return;
- d->owner->writeByte (d->pause_state_offset, paused);
+ if (d->PauseInited)
+ *df::global::pause_state = paused;
}
uint32_t World::ReadCurrentYear()
@@ -147,8 +132,8 @@ bool World::ReadGameMode(t_gamemodes& rd)
{
if(d->Inited && d->StartedMode)
{
- rd.g_mode = (GameMode) d->owner->readDWord( d->controlmode_offset);
- rd.g_type = (GameType) d->owner->readDWord(d->gamemode_offset);
+ rd.g_mode = (DFHack::GameMode)*df::global::control_mode;
+ rd.g_type = (DFHack::GameType)*df::global::game_mode;
return true;
}
return false;
@@ -157,8 +142,8 @@ bool World::WriteGameMode(const t_gamemodes & wr)
{
if(d->Inited && d->StartedMode)
{
- d->owner->writeDWord(d->gamemode_offset,wr.g_type);
- d->owner->writeDWord(d->controlmode_offset,wr.g_mode);
+ *df::global::control_mode = wr.g_mode;
+ *df::global::game_mode = wr.g_type;
return true;
}
return false;
@@ -199,18 +184,14 @@ uint32_t World::ReadCurrentDay()
uint8_t World::ReadCurrentWeather()
{
if (d->Inited && d->StartedWeather)
- return(d->owner->readByte(d->weather_offset + 12));
+ return (*df::global::current_weather)[2][2];
return 0;
}
void World::SetCurrentWeather(uint8_t weather)
{
if (d->Inited && d->StartedWeather)
- {
- uint8_t buf[25];
- memset(&buf,weather, sizeof(buf));
- d->owner->write(d->weather_offset,sizeof(buf),buf);
- }
+ memset(df::global::current_weather, weather, 25);
}
string World::ReadWorldFolder()
diff --git a/plugins/weather.cpp b/plugins/weather.cpp
index 68eb078ad..33fa45fd3 100644
--- a/plugins/weather.cpp
+++ b/plugins/weather.cpp
@@ -5,10 +5,13 @@
#include
#include
#include "modules/World.h"
+#include "DataDefs.h"
+#include "df/weather_type.h"
using std::vector;
using std::string;
using namespace DFHack;
+using namespace df::enums;
bool locked = false;
unsigned char locked_data[25];
@@ -82,7 +85,7 @@ command_result weather (color_ostream &con, vector & parameters)
CoreSuspender suspend;
DFHack::World * w = Core::getInstance().getWorld();
- if(!w->wmap)
+ if(!df::global::current_weather)
{
con << "Weather support seems broken :(" << std::endl;
return CR_FAILURE;
@@ -95,19 +98,19 @@ command_result weather (color_ostream &con, vector & parameters)
{
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 ";
break;
- case RAINING:
+ case weather_type::Rain:
con << "R ";
break;
- case SNOWING:
+ case weather_type::Snow:
con << "S ";
break;
default:
- con << (int) (*w->wmap)[x][y] << " ";
+ con << (int) (*df::global::current_weather)[x][y] << " ";
break;
}
}
@@ -120,17 +123,17 @@ command_result weather (color_ostream &con, vector & parameters)
if(rain)
{
con << "Here comes the rain." << std::endl;
- w->SetCurrentWeather(RAINING);
+ w->SetCurrentWeather(weather_type::Rain);
}
if(snow)
{
con << "Snow everywhere!" << std::endl;
- w->SetCurrentWeather(SNOWING);
+ w->SetCurrentWeather(weather_type::Snow);
}
if(clear)
{
con << "Suddenly, sunny weather!" << std::endl;
- w->SetCurrentWeather(CLEAR);
+ w->SetCurrentWeather(weather_type::None);
}
if(val_override != -1)
{
From 985533460c87fe15f047d9b7ccc9c81f5fbdcf82 Mon Sep 17 00:00:00 2001
From: Quietust
Date: Wed, 23 May 2012 13:10:57 -0500
Subject: [PATCH 04/17] -Wno-sign-compare only works with GCC
---
depends/protobuf/CMakeLists.txt | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/depends/protobuf/CMakeLists.txt b/depends/protobuf/CMakeLists.txt
index dddefb06b..570c77b18 100644
--- a/depends/protobuf/CMakeLists.txt
+++ b/depends/protobuf/CMakeLists.txt
@@ -200,7 +200,9 @@ google/protobuf/compiler/zip_writer.cc
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})
SET(PROTOBUF_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR})
From 64ea06bbfebf795e5e24a634f8a821552835e2f3 Mon Sep 17 00:00:00 2001
From: Quietust
Date: Wed, 23 May 2012 13:38:01 -0500
Subject: [PATCH 05/17] Don't crash if "gps" is null
---
library/modules/Gui.cpp | 23 ++++++++++++++++++-----
library/modules/Windows.cpp | 6 ++++--
2 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/library/modules/Gui.cpp b/library/modules/Gui.cpp
index 2290110a8..111ea94c7 100644
--- a/library/modules/Gui.cpp
+++ b/library/modules/Gui.cpp
@@ -998,16 +998,29 @@ bool Gui::setDesignationCoords (const int32_t x, const int32_t y, const int32_t
bool Gui::getMousePos (int32_t & x, int32_t & y)
{
- x = gps->mouse_x;
- y = gps->mouse_y;
+ if (gps) {
+ x = gps->mouse_x;
+ y = gps->mouse_y;
+ }
+ else {
+ x = -1;
+ y = -1;
+ }
return (x == -1) ? false : true;
}
bool Gui::getWindowSize (int32_t &width, int32_t &height)
{
- width = gps->dimx;
- height = gps->dimy;
- return true;
+ if (gps) {
+ width = gps->dimx;
+ height = gps->dimy;
+ return true;
+ }
+ else {
+ width = 80;
+ height = 25;
+ return false;
+ }
}
bool Gui::getMenuWidth(uint8_t &menu_width, uint8_t &area_map_width)
diff --git a/library/modules/Windows.cpp b/library/modules/Windows.cpp
index e069d964e..218b6f7e0 100644
--- a/library/modules/Windows.cpp
+++ b/library/modules/Windows.cpp
@@ -34,10 +34,12 @@ distribution.
#include "modules/Windows.h"
using namespace DFHack;
+using df::global::gps;
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)
@@ -79,7 +81,7 @@ bool Windows::df_window::unlock (painter * painter)
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;
}
From 2b862655b722234431051f188fe5169960bb3f05 Mon Sep 17 00:00:00 2001
From: Quietust
Date: Wed, 23 May 2012 13:38:16 -0500
Subject: [PATCH 06/17] Allow compiling RelWithDebInfo on Windows
---
library/CMakeLists.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 32b7d9dad..c49ac6884 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -208,6 +208,8 @@ IF(UNIX)
SET_SOURCE_FILES_PROPERTIES(DataStatics.cpp DataStaticsCtor.cpp DataStaticsFields.cpp
PROPERTIES COMPILE_FLAGS "-g0 -O1")
ELSE(WIN32)
+ SET_SOURCE_FILES_PROPERTIES(DataStatics.cpp DataStaticsCtor.cpp DataStaticsFields.cpp
+ PROPERTIES COMPILE_FLAGS "/O1 /bigobj")
ENDIF()
From ae41ddc04a2b3a076bd18af984f163e46c74b65f Mon Sep 17 00:00:00 2001
From: Quietust
Date: Wed, 23 May 2012 13:43:41 -0500
Subject: [PATCH 07/17] Don't crash if world is undefined
---
plugins/autolabor.cpp | 2 +-
plugins/fastdwarf.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/plugins/autolabor.cpp b/plugins/autolabor.cpp
index d89ddd7c6..de1a1aef6 100644
--- a/plugins/autolabor.cpp
+++ b/plugins/autolabor.cpp
@@ -706,7 +706,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out )
{
static int step_count = 0;
// 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'
return CR_OK;
diff --git a/plugins/fastdwarf.cpp b/plugins/fastdwarf.cpp
index 643a097c4..5a2e2f206 100644
--- a/plugins/fastdwarf.cpp
+++ b/plugins/fastdwarf.cpp
@@ -28,7 +28,7 @@ static int enable_fastdwarf = false;
DFhackCExport command_result plugin_onupdate ( color_ostream &out )
{
// 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'
return CR_OK;
From 800cbca578a08dd7bc70441ecd5a01a380bd7118 Mon Sep 17 00:00:00 2001
From: Quietust
Date: Fri, 25 May 2012 21:31:47 -0500
Subject: [PATCH 08/17] Some improvements to showmood - show relevant skill,
cleanup messages
---
plugins/showmood.cpp | 36 ++++++++++++++++++++++--------------
1 file changed, 22 insertions(+), 14 deletions(-)
diff --git a/plugins/showmood.cpp b/plugins/showmood.cpp
index 7407e6af1..7926e2ac5 100644
--- a/plugins/showmood.cpp
+++ b/plugins/showmood.cpp
@@ -100,37 +100,37 @@ command_result df_showmood (color_ostream &out, vector & parameters)
switch (job->job_type)
{
case job_type::StrangeMoodCrafter:
- out.print("become a Craftsdwarf (or Engraver)");
+ out.print("claim a Craftsdwarf's Workshop");
break;
case job_type::StrangeMoodJeweller:
- out.print("become a Jeweler");
+ out.print("claim a Jeweler's Workshop");
break;
case job_type::StrangeMoodForge:
- out.print("become a Metalworker");
+ out.print("claim a Metalsmith's Forge");
break;
case job_type::StrangeMoodMagmaForge:
- out.print("become a Metalworker using a Magma Forge");
+ out.print("claim a Magma Forge");
break;
case job_type::StrangeMoodCarpenter:
- out.print("become a Carpenter");
+ out.print("claim a Carpenter's Workshop");
break;
case job_type::StrangeMoodMason:
- out.print("become a Mason (or Miner)");
+ out.print("claim a Mason's Workshop");
break;
case job_type::StrangeMoodBowyer:
- out.print("become a Bowyer");
+ out.print("claim a Boywer's Workshop");
break;
case job_type::StrangeMoodTanner:
- out.print("become a Leatherworker (or Tanner)");
+ out.print("claim a Leather Works");
break;
case job_type::StrangeMoodWeaver:
- out.print("become a Clothier (or Weaver)");
+ out.print("claim a Clothier's Shop");
break;
case job_type::StrangeMoodGlassmaker:
- out.print("become a Glassmaker");
+ out.print("claim a Glass Furnace");
break;
case job_type::StrangeMoodMechanics:
- out.print("become a Mechanic");
+ out.print("claim a Mechanic's Workshop");
break;
case job_type::StrangeMoodBrooding:
out.print("enter a macabre mood?");
@@ -142,20 +142,28 @@ command_result df_showmood (color_ostream &out, vector & parameters)
out.print("do something else...");
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;
-
default:
out.print("insane?");
break;
}
+ out.print(".\n");
+ if (unit->sex)
+ out.print("He has ");
+ else
+ out.print("She has ");
if (building)
{
string 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
- 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++)
{
From e72bf1ac9aa4d9c56f8435c5b86f538c06d651b9 Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Sat, 26 May 2012 14:49:27 +0400
Subject: [PATCH 09/17] Sync to changes in df-structures.
---
library/modules/Materials.cpp | 4 ++--
library/xml | 2 +-
plugins/devel/counters.cpp | 2 +-
plugins/forceequip.cpp | 22 +++++++++++-----------
4 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/library/modules/Materials.cpp b/library/modules/Materials.cpp
index f49dd82e2..f8f99f81e 100644
--- a/library/modules/Materials.cpp
+++ b/library/modules/Materials.cpp
@@ -761,8 +761,8 @@ bool Materials::ReadCreatureTypesEx (void)
{
df::body_part_raw *bp = ca->body_info.body_parts[k];
t_bodypart part;
- part.id = bp->part_code;
- part.category = bp->part_name;
+ part.id = bp->token;
+ part.category = bp->category;
caste.bodypart.push_back(part);
}
using namespace df::enums::mental_attribute_type;
diff --git a/library/xml b/library/xml
index d991d47b0..7d5c349a4 160000
--- a/library/xml
+++ b/library/xml
@@ -1 +1 @@
-Subproject commit d991d47b0f6709205c4e333bb86edb3dcf656429
+Subproject commit 7d5c349a40dc1f211de2d37aeece4a3d9d631ed2
diff --git a/plugins/devel/counters.cpp b/plugins/devel/counters.cpp
index 66d8c63a4..332945677 100644
--- a/plugins/devel/counters.cpp
+++ b/plugins/devel/counters.cpp
@@ -25,7 +25,7 @@ command_result df_counters (color_ostream &out, vector & parameters)
for (size_t i = 0; i < counters.size(); 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;
diff --git a/plugins/forceequip.cpp b/plugins/forceequip.cpp
index 0d493143b..723f29474 100644
--- a/plugins/forceequip.cpp
+++ b/plugins/forceequip.cpp
@@ -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())
{
// 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;
}
else
@@ -302,35 +302,35 @@ static bool moveToInventory(MapExtras::MapCache &mc, df::item *item, df::unit *u
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
if (item->getType() == df::enums::item_type::GLOVES && currPart->flags.is_set(df::body_part_template_flags::GRASP) &&
((item->getGloveHandedness() == const_GloveLeftHandedness && currPart->flags.is_set(df::body_part_template_flags::LEFT)) ||
(item->getGloveHandedness() == const_GloveRightHandedness && currPart->flags.is_set(df::body_part_template_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))
{
- 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))
{
- 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))
{
- 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))
{
- 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)
{
// 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)
{
@@ -538,16 +538,16 @@ command_result df_forceequip(color_ostream &out, vector & parameters)
{
// Tentatively assume that the part is a match
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)
- 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;
}
else
{
// 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;
}
}
From f71a843c6e00705bb2031643e1d93e6fd7442063 Mon Sep 17 00:00:00 2001
From: Quietust
Date: Mon, 28 May 2012 11:06:23 -0500
Subject: [PATCH 10/17] Don't throw a fatal exception just because os-type
isn't something we recognize - ignore it and move on
---
library/VersionInfoFactory.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/library/VersionInfoFactory.cpp b/library/VersionInfoFactory.cpp
index 36dbd9aae..972ab31b4 100644
--- a/library/VersionInfoFactory.cpp
+++ b/library/VersionInfoFactory.cpp
@@ -107,7 +107,7 @@ void VersionInfoFactory::ParseVersion (TiXmlElement* entry, VersionInfo* mem)
}
else
{
- throw Error::SymbolsXmlBadAttribute("os-type");
+ return; // ignore it if it's invalid
}
// process additional entries
From 884cf53b0bee55ccdcf2ee98ba9cc30ea9236e4e Mon Sep 17 00:00:00 2001
From: Quietust
Date: Wed, 30 May 2012 08:02:53 -0500
Subject: [PATCH 11/17] body_part_raw has its own set of flags which do NOT
match body_part_template
---
plugins/forceequip.cpp | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/plugins/forceequip.cpp b/plugins/forceequip.cpp
index 723f29474..abf4a95db 100644
--- a/plugins/forceequip.cpp
+++ b/plugins/forceequip.cpp
@@ -28,7 +28,7 @@ using namespace std;
#include "df/body_part_raw.h"
#include "MiscUtils.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/caste_raw.h"
#include "df/body_detail_plan.h"
@@ -305,25 +305,25 @@ static bool moveToInventory(MapExtras::MapCache &mc, df::item *item, df::unit *u
if (verbose) { Core::print("Inspecting bodypart %s.\n", currPart->token.c_str()); }
// Inspect the current bodypart
- if (item->getType() == df::enums::item_type::GLOVES && currPart->flags.is_set(df::body_part_template_flags::GRASP) &&
- ((item->getGloveHandedness() == const_GloveLeftHandedness && currPart->flags.is_set(df::body_part_template_flags::LEFT)) ||
- (item->getGloveHandedness() == const_GloveRightHandedness && currPart->flags.is_set(df::body_part_template_flags::RIGHT))))
+ 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_raw_flags::LEFT)) ||
+ (item->getGloveHandedness() == const_GloveRightHandedness && currPart->flags.is_set(df::body_part_raw_flags::RIGHT))))
{
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->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->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->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->token.c_str()); }
}
From e143c312bf26cbbe9a65175b398546f0bc19945c Mon Sep 17 00:00:00 2001
From: Quietust
Date: Thu, 31 May 2012 19:13:11 -0500
Subject: [PATCH 12/17] Sync with df-structures changes
---
plugins/dwarfexport/dwarfexport.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/plugins/dwarfexport/dwarfexport.cpp b/plugins/dwarfexport/dwarfexport.cpp
index 5db1bf226..64fbcd653 100644
--- a/plugins/dwarfexport/dwarfexport.cpp
+++ b/plugins/dwarfexport/dwarfexport.cpp
@@ -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) {
out << " " << endl;
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;
if (s) {
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 << " " << endl;
From b7edbf2076e20ef5a05979e687a5cdf93ddf203e Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Tue, 5 Jun 2012 14:00:52 +0400
Subject: [PATCH 13/17] Support 7-argument vmethods.
---
library/include/DataFuncs.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/library/include/DataFuncs.h b/library/include/DataFuncs.h
index aff04128c..637a532f8 100644
--- a/library/include/DataFuncs.h
+++ b/library/include/DataFuncs.h
@@ -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
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_TARGSC
From d35d8d3431f1c02f70c281558fa211d3bd7642ca Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Tue, 5 Jun 2012 14:06:29 +0400
Subject: [PATCH 14/17] Add the script to fix lagging fat dwarves.
---
library/xml | 2 +-
scripts/fix/fat-dwarves.lua | 24 ++++++++++++++++++++++++
2 files changed, 25 insertions(+), 1 deletion(-)
create mode 100644 scripts/fix/fat-dwarves.lua
diff --git a/library/xml b/library/xml
index 7d5c349a4..8c0794489 160000
--- a/library/xml
+++ b/library/xml
@@ -1 +1 @@
-Subproject commit 7d5c349a40dc1f211de2d37aeece4a3d9d631ed2
+Subproject commit 8c07944891f09391cc02098074ffc8080b43b184
diff --git a/scripts/fix/fat-dwarves.lua b/scripts/fix/fat-dwarves.lua
new file mode 100644
index 000000000..5394f6770
--- /dev/null
+++ b/scripts/fix/fat-dwarves.lua
@@ -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)
From 7aff2d6bc06c0fd8e14df08c070517bd53374dbf Mon Sep 17 00:00:00 2001
From: Kelly Martin
Date: Tue, 5 Jun 2012 14:33:06 -0500
Subject: [PATCH 15/17] Sync structures for .34.11
---
library/xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/library/xml b/library/xml
index 8c0794489..fc618cce6 160000
--- a/library/xml
+++ b/library/xml
@@ -1 +1 @@
-Subproject commit 8c07944891f09391cc02098074ffc8080b43b184
+Subproject commit fc618cce63f0037442ec8d650a11cbe823f0443a
From 9dbcaa2733878bf089ac12514ed22d9b8ebe27a9 Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Wed, 6 Jun 2012 18:54:06 +0400
Subject: [PATCH 16/17] Support adventure mode and stockpile screens in focus
strings.
---
library/modules/Gui.cpp | 45 ++++++++++++++++++++++++++++++++++++++++-
library/xml | 2 +-
2 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/library/modules/Gui.cpp b/library/modules/Gui.cpp
index 111ea94c7..63ba811c1 100644
--- a/library/modules/Gui.cpp
+++ b/library/modules/Gui.cpp
@@ -58,12 +58,14 @@ using namespace DFHack;
#include "df/viewscreen_layer_overall_healthst.h"
#include "df/viewscreen_layer_assigntradest.h"
#include "df/viewscreen_layer_militaryst.h"
+#include "df/viewscreen_layer_stockpilest.h"
#include "df/viewscreen_petst.h"
#include "df/viewscreen_tradegoodsst.h"
#include "df/viewscreen_storesst.h"
#include "df/ui_unit_view_mode.h"
#include "df/ui_sidebar_menus.h"
#include "df/ui_look_list.h"
+#include "df/ui_advmode.h"
#include "df/job.h"
#include "df/ui_build_selector.h"
#include "df/building_workshopst.h"
@@ -273,7 +275,9 @@ DEFINE_GET_FOCUS_STRING_HANDLER(dwarfmode)
break;
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";
else if (ui->burrows.in_edit_name_mode)
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)
{
focus += "/" + enum_item_key(screen->page);
@@ -407,6 +421,35 @@ DEFINE_GET_FOCUS_STRING_HANDLER(stores)
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)
{
diff --git a/library/xml b/library/xml
index fc618cce6..0a0dc568d 160000
--- a/library/xml
+++ b/library/xml
@@ -1 +1 @@
-Subproject commit fc618cce63f0037442ec8d650a11cbe823f0443a
+Subproject commit 0a0dc568dff80396efd1b2c9a6ef1614df5786f7
From 36d2e6efdeb2a1d8855da18fa9bd4fba268f8ffe Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Wed, 6 Jun 2012 19:05:07 +0400
Subject: [PATCH 17/17] Add an example of focus string usage and a lua command
keybinding.
---
dfhack.init-example | 3 +++
1 file changed, 3 insertions(+)
diff --git a/dfhack.init-example b/dfhack.init-example
index 7bceda2d0..4af4246fc 100644
--- a/dfhack.init-example
+++ b/dfhack.init-example
@@ -13,6 +13,9 @@ keybinding add Ctrl-Shift-K autodump-destroy-here
# any 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 #
##############################