Merge pull request #555 from lethosor/travis

Add .travis.yml and fix whitespace issues
develop
Lethosor 2015-02-16 17:05:29 -05:00
commit e9cc242322
157 changed files with 5894 additions and 5737 deletions

@ -0,0 +1,6 @@
language: cpp
script:
- python travis/lint.py
- python travis/pr-check-base.py
notifications:
email: false

@ -1601,8 +1601,8 @@ void Core::onUpdate(color_ostream &out)
void Core::handleLoadAndUnloadScripts(color_ostream& out, state_change_event event) { void Core::handleLoadAndUnloadScripts(color_ostream& out, state_change_event event) {
if (!df::global::world) if (!df::global::world)
return; return;
//TODO: use different separators for windows //TODO: use different separators for windows
#ifdef _WIN32 #ifdef _WIN32
static const std::string separator = "\\"; static const std::string separator = "\\";
#else #else

@ -143,7 +143,7 @@ DFhackCExport uint32_t SDL_GetTicks(void)
/***** Surfaces /***** Surfaces
SDL_CreateRGBSurface SDL_CreateRGBSurface
SDL_Surface * SDLCALL SDL_CreateRGBSurface SDL_Surface * SDLCALL SDL_CreateRGBSurface
(Uint32 flags, int width, int height, int depth, (Uint32 flags, int width, int height, int depth,
Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
SDL_CreateRGBSurfaceFrom SDL_CreateRGBSurfaceFrom
@ -216,7 +216,7 @@ SDL_SaveBMP_RW
SDL_SetAlpha SDL_SetAlpha
int SDLCALL SDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha); int SDLCALL SDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha);
SDL_SetColorKey SDL_SetColorKey
int SDLCALL SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key); int SDLCALL SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key);
@ -311,16 +311,16 @@ DFhackCExport int SDL_UpperBlit(DFHack::DFSDL_Surface* src, DFHack::DFSDL_Rect*
/***** Even more surface /***** Even more surface
SDL_GL_GetAttribute SDL_GL_GetAttribute
int SDLCALL SDL_GL_GetAttribute(SDL_GLattr attr, int* value); int SDLCALL SDL_GL_GetAttribute(SDL_GLattr attr, int* value);
SDL_GL_SetAttribute SDL_GL_SetAttribute
int SDLCALL SDL_GL_SetAttribute(SDL_GLattr attr, int value); int SDLCALL SDL_GL_SetAttribute(SDL_GLattr attr, int value);
SDL_WM_SetCaption SDL_WM_SetCaption
void SDLCALL SDL_WM_SetCaption(const char *title, const char *icon); void SDLCALL SDL_WM_SetCaption(const char *title, const char *icon);
SDL_WM_SetIcon SDL_WM_SetIcon
void SDLCALL SDL_WM_SetIcon(SDL_Surface *icon, Uint8 *mask); void SDLCALL SDL_WM_SetIcon(SDL_Surface *icon, Uint8 *mask);
SDL_FillRect SDL_FillRect
int SDLCALL SDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color); int SDLCALL SDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color);
*/ */
@ -787,7 +787,7 @@ bool FirstCall()
_SDL_mutexP = (int (*)(vPtr))GetProcAddress(realSDLlib,"SDL_mutexP"); _SDL_mutexP = (int (*)(vPtr))GetProcAddress(realSDLlib,"SDL_mutexP");
_SDL_mutexV = (int (*)(vPtr))GetProcAddress(realSDLlib,"SDL_mutexV"); _SDL_mutexV = (int (*)(vPtr))GetProcAddress(realSDLlib,"SDL_mutexV");
_SDL_strlcpy = (size_t (*)(char*, const char*, size_t))GetProcAddress(realSDLlib,"SDL_strlcpy"); _SDL_strlcpy = (size_t (*)(char*, const char*, size_t))GetProcAddress(realSDLlib,"SDL_strlcpy");
// stuff for SDL_Image // stuff for SDL_Image
_SDL_ClearError = (void (*)())GetProcAddress(realSDLlib,"SDL_ClearError"); _SDL_ClearError = (void (*)())GetProcAddress(realSDLlib,"SDL_ClearError");
_SDL_Error = (void (*)(int))GetProcAddress(realSDLlib,"SDL_Error"); _SDL_Error = (void (*)(int))GetProcAddress(realSDLlib,"SDL_Error");
@ -799,7 +799,7 @@ bool FirstCall()
_SDL_SetError = (void (*)(const char*, ...))GetProcAddress(realSDLlib,"SDL_SetError"); _SDL_SetError = (void (*)(const char*, ...))GetProcAddress(realSDLlib,"SDL_SetError");
_SDL_UnloadObject = (void (*)(vPtr))GetProcAddress(realSDLlib,"SDL_UnloadObject"); _SDL_UnloadObject = (void (*)(vPtr))GetProcAddress(realSDLlib,"SDL_UnloadObject");
_SDL_FillRect = (int (*)(void*,void*,uint32_t))GetProcAddress(realSDLlib,"SDL_FillRect"); _SDL_FillRect = (int (*)(void*,void*,uint32_t))GetProcAddress(realSDLlib,"SDL_FillRect");
// new in DF 0.31.04 // new in DF 0.31.04
_SDL_CreateSemaphore = (void* (*)(uint32_t))GetProcAddress(realSDLlib,"SDL_CreateSemaphore"); _SDL_CreateSemaphore = (void* (*)(uint32_t))GetProcAddress(realSDLlib,"SDL_CreateSemaphore");
_SDL_CreateThread = (vPtr (*)(int (*fn)(void *), void *data))GetProcAddress(realSDLlib,"SDL_CreateThread"); _SDL_CreateThread = (vPtr (*)(int (*fn)(void *), void *data))GetProcAddress(realSDLlib,"SDL_CreateThread");
@ -812,7 +812,7 @@ bool FirstCall()
_SDL_SemTryWait = (int (*)(void *))GetProcAddress(realSDLlib,"SDL_SemTryWait"); _SDL_SemTryWait = (int (*)(void *))GetProcAddress(realSDLlib,"SDL_SemTryWait");
_SDL_SemWait = (int (*)(void *))GetProcAddress(realSDLlib,"SDL_SemWait"); _SDL_SemWait = (int (*)(void *))GetProcAddress(realSDLlib,"SDL_SemWait");
_SDL_ThreadID = (uint32_t (*)(void))GetProcAddress(realSDLlib,"SDL_ThreadID"); _SDL_ThreadID = (uint32_t (*)(void))GetProcAddress(realSDLlib,"SDL_ThreadID");
_SDL_EnableUNICODE(1); _SDL_EnableUNICODE(1);
fprintf(stderr,"Initized HOOKS!\n"); fprintf(stderr,"Initized HOOKS!\n");

@ -345,7 +345,7 @@ namespace DFHack
bool is_direct_instance(virtual_ptr instance_ptr) { bool is_direct_instance(virtual_ptr instance_ptr) {
if (!instance_ptr) return false; if (!instance_ptr) return false;
return vtable_ptr ? (vtable_ptr == get_vtable(instance_ptr)) return vtable_ptr ? (vtable_ptr == get_vtable(instance_ptr))
: (this == get(instance_ptr)); : (this == get(instance_ptr));
} }

@ -42,7 +42,7 @@ distribution.
/** /**
* [peterix@peterix dfhack]$ man wcscpy_s * [peterix@peterix dfhack]$ man wcscpy_s
* No manual entry for wcscpy_s * No manual entry for wcscpy_s
* *
* Proprietary extensions. * Proprietary extensions.
*/ */
// disable stupid // disable stupid

@ -78,7 +78,7 @@ namespace SDL
K_GREATER = 62, K_GREATER = 62,
K_QUESTION = 63, K_QUESTION = 63,
K_AT = 64, K_AT = 64,
/* /*
Skip uppercase letters Skip uppercase letters
*/ */
K_LEFTBRACKET = 91, K_LEFTBRACKET = 91,

@ -335,7 +335,7 @@ namespace DFHack
* zilpin: Find a tile type similar to the one given, but with a different class. * zilpin: Find a tile type similar to the one given, but with a different class.
* Useful for tile-editing operations. * Useful for tile-editing operations.
* If no match found, returns the sourceType * If no match found, returns the sourceType
* *
* @todo Definitely needs improvement for wall directions, etc. * @todo Definitely needs improvement for wall directions, etc.
*/ */
DFHACK_EXPORT df::tiletype findSimilarTileType( const df::tiletype sourceTileType, const df::tiletype_shape tshape ); DFHACK_EXPORT df::tiletype findSimilarTileType( const df::tiletype sourceTileType, const df::tiletype_shape tshape );

@ -193,14 +193,14 @@ void clearBuildings(color_ostream& out);
/** /**
* Iterates over the items stored on a stockpile. * Iterates over the items stored on a stockpile.
* (For stockpiles with containers, yields the containers, not their contents.) * (For stockpiles with containers, yields the containers, not their contents.)
* *
* Usage: * Usage:
* *
* Buildings::StockpileIterator stored; * Buildings::StockpileIterator stored;
* for (stored.begin(stockpile); !stored.done(); ++stored) { * for (stored.begin(stockpile); !stored.done(); ++stored) {
* df::item *item = *stored; * df::item *item = *stored;
* } * }
* *
* Implementation detail: Uses tile blocks for speed. * Implementation detail: Uses tile blocks for speed.
* For each tile block that contains at least part of the stockpile, * For each tile block that contains at least part of the stockpile,
* starting at the top left and moving right, row by row, * starting at the top left and moving right, row by row,
@ -212,14 +212,14 @@ class DFHACK_EXPORT StockpileIterator : public std::iterator<std::input_iterator
df::map_block* block; df::map_block* block;
size_t current; size_t current;
df::item *item; df::item *item;
public: public:
StockpileIterator() { StockpileIterator() {
stockpile = NULL; stockpile = NULL;
block = NULL; block = NULL;
item = NULL; item = NULL;
} }
StockpileIterator& operator++() { StockpileIterator& operator++() {
while (stockpile) { while (stockpile) {
if (block) { if (block) {
@ -230,7 +230,7 @@ public:
block = Maps::getTileBlock(stockpile->x1, stockpile->y1, stockpile->z); block = Maps::getTileBlock(stockpile->x1, stockpile->y1, stockpile->z);
current = 0; current = 0;
} }
while (current >= block->items.size()) { while (current >= block->items.size()) {
// Out of items in this block; find the next block to search. // Out of items in this block; find the next block to search.
if (block->map_pos.x + 16 < stockpile->x2) { if (block->map_pos.x + 16 < stockpile->x2) {
@ -246,39 +246,39 @@ public:
return *this; return *this;
} }
} }
// If the current item isn't properly stored, move on to the next. // If the current item isn't properly stored, move on to the next.
item = df::item::find(block->items[current]); item = df::item::find(block->items[current]);
if (!item->flags.bits.on_ground) { if (!item->flags.bits.on_ground) {
continue; continue;
} }
if (!Buildings::containsTile(stockpile, item->pos, false)) { if (!Buildings::containsTile(stockpile, item->pos, false)) {
continue; continue;
} }
// Ignore empty bins, barrels, and wheelbarrows assigned here. // Ignore empty bins, barrels, and wheelbarrows assigned here.
if (item->isAssignedToThisStockpile(stockpile->id)) { if (item->isAssignedToThisStockpile(stockpile->id)) {
auto ref = Items::getGeneralRef(item, df::general_ref_type::CONTAINS_ITEM); auto ref = Items::getGeneralRef(item, df::general_ref_type::CONTAINS_ITEM);
if (!ref) continue; if (!ref) continue;
} }
// Found a valid item; yield it. // Found a valid item; yield it.
break; break;
} }
return *this; return *this;
} }
void begin(df::building_stockpilest* sp) { void begin(df::building_stockpilest* sp) {
stockpile = sp; stockpile = sp;
operator++(); operator++();
} }
df::item* operator*() { df::item* operator*() {
return item; return item;
} }
bool done() { bool done() {
return block == NULL; return block == NULL;
} }

@ -59,7 +59,7 @@ namespace DFHack {
} }
}; };
struct InventoryItem { struct InventoryItem {
//it has to keep the id of an item because the item itself may have been deallocated //it has to keep the id of an item because the item itself may have been deallocated
int32_t itemId; int32_t itemId;
@ -74,7 +74,7 @@ namespace DFHack {
InventoryChangeData() {} InventoryChangeData() {}
InventoryChangeData(int32_t id_in, InventoryItem* old_in, InventoryItem* new_in): unitId(id_in), item_old(old_in), item_new(new_in) {} InventoryChangeData(int32_t id_in, InventoryItem* old_in, InventoryItem* new_in): unitId(id_in), item_old(old_in), item_new(new_in) {}
}; };
struct UnitAttackData { struct UnitAttackData {
int32_t attacker; int32_t attacker;
int32_t defender; int32_t defender;
@ -89,7 +89,7 @@ namespace DFHack {
int32_t attackReport; int32_t attackReport;
int32_t defendReport; int32_t defendReport;
}; };
DFHACK_EXPORT void registerListener(EventType::EventType e, EventHandler handler, Plugin* plugin); DFHACK_EXPORT void registerListener(EventType::EventType e, EventHandler handler, Plugin* plugin);
DFHACK_EXPORT int32_t registerTick(EventHandler handler, int32_t when, Plugin* plugin, bool absolute=false); DFHACK_EXPORT int32_t registerTick(EventHandler handler, int32_t when, Plugin* plugin, bool absolute=false);
DFHACK_EXPORT void unregister(EventType::EventType e, EventHandler handler, Plugin* plugin); DFHACK_EXPORT void unregister(EventType::EventType e, EventHandler handler, Plugin* plugin);

@ -72,7 +72,7 @@ class BlockInfo
Block *mblock; Block *mblock;
MapCache *parent; MapCache *parent;
df::map_block *block; df::map_block *block;
df::map_block_column *column; //for plants df::map_block_column *column; //for plants
public: public:
enum GroundType { enum GroundType {

@ -181,7 +181,7 @@ extern DFHACK_EXPORT bool IsValid();
* Method for reading the geological surrounding of the currently loaded region. * Method for reading the geological surrounding of the currently loaded region.
* assign is a reference to an array of nine vectors of unsigned words that are to be filled with the data * assign is a reference to an array of nine vectors of unsigned words that are to be filled with the data
* array is indexed by the BiomeOffset enum * array is indexed by the BiomeOffset enum
* *
* I omitted resolving the layer matgloss in this API, because it would * I omitted resolving the layer matgloss in this API, because it would
* introduce overhead by calling some method for each tile. You have to do it * introduce overhead by calling some method for each tile. You have to do it
* yourself. * yourself.

@ -63,7 +63,7 @@ namespace Windows
uint8_t bright; uint8_t bright;
}; };
// our silly painter things and window things follow. // our silly painter things and window things follow.
class df_window; class df_window;
struct df_tilebuf struct df_tilebuf

@ -138,13 +138,13 @@
* only defined for compatibility. These macros should always return false * only defined for compatibility. These macros should always return false
* on Windows. * on Windows.
*/ */
#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO) #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO)
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) #define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) #define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) #define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) #define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

@ -41,7 +41,7 @@ jobs_furnace={
}, },
--[[ [df.furnace_type.MetalsmithsForge]={ --[[ [df.furnace_type.MetalsmithsForge]={
unpack(concat(furnaces,mechanism,anvil,crafts,coins,flask)) unpack(concat(furnaces,mechanism,anvil,crafts,coins,flask))
}, },
]] ]]
--MetalsmithsForge, --MetalsmithsForge,
@ -86,7 +86,7 @@ jobs_furnace={
}, },
} }
jobs_workshop={ jobs_workshop={
[df.workshop_type.Jewelers]={ [df.workshop_type.Jewelers]={
{ {
name="cut gems", name="cut gems",
@ -146,7 +146,7 @@ jobs_workshop={
items={{}}, items={{}},
job_fields={job_type=df.job_type.ConstructArmorStand} job_fields={job_type=df.job_type.ConstructArmorStand}
}, },
{ {
name="construct blocks", name="construct blocks",
items={{}}, items={{}},
@ -226,13 +226,13 @@ jobs_workshop={
[df.workshop_type.Carpenters]={ [df.workshop_type.Carpenters]={
--training weapons, wooden shields --training weapons, wooden shields
defaults={item_type=df.item_type.WOOD,vector_id=df.job_item_vector_id.WOOD}, defaults={item_type=df.item_type.WOOD,vector_id=df.job_item_vector_id.WOOD},
{ {
name="make barrel", name="make barrel",
items={{}}, items={{}},
job_fields={job_type=df.job_type.MakeBarrel} job_fields={job_type=df.job_type.MakeBarrel}
}, },
{ {
name="make bucket", name="make bucket",
items={{}}, items={{}},
@ -550,7 +550,7 @@ function getJobs(buildingId,workshopId,customId)
c_jobs=jobs_workshop[workshopId] c_jobs=jobs_workshop[workshopId]
elseif buildingId==df.building_type.Furnace then elseif buildingId==df.building_type.Furnace then
c_jobs=jobs_furnace[workshopId] c_jobs=jobs_furnace[workshopId]
if workshopId == df.furnace_type.Smelter or workshopId == df.furnace_type.MagmaSmelter then if workshopId == df.furnace_type.Smelter or workshopId == df.furnace_type.MagmaSmelter then
c_jobs=utils.clone(c_jobs,true) c_jobs=utils.clone(c_jobs,true)
addSmeltJobs(c_jobs,workshopId == df.furnace_type.Smelter) addSmeltJobs(c_jobs,workshopId == df.furnace_type.Smelter)
@ -563,7 +563,7 @@ function getJobs(buildingId,workshopId,customId)
else else
c_jobs=utils.clone(c_jobs,true) c_jobs=utils.clone(c_jobs,true)
end end
addReactionJobs(c_jobs,buildingId,workshopId,customId) addReactionJobs(c_jobs,buildingId,workshopId,customId)
for jobId,contents in pairs(c_jobs) do for jobId,contents in pairs(c_jobs) do
if jobId~="defaults" then if jobId~="defaults" then

@ -27,22 +27,22 @@ local _ENV = mkmodule('dumper')
local dumplua_closure = [[ local dumplua_closure = [[
local closures = {} local closures = {}
local function closure(t) local function closure(t)
closures[#closures+1] = t closures[#closures+1] = t
t[1] = assert(loadstring(t[1])) t[1] = assert(loadstring(t[1]))
return t[1] return t[1]
end end
for _,t in pairs(closures) do for _,t in pairs(closures) do
for i = 2,#t do for i = 2,#t do
debug.setupvalue(t[1], i-1, t[i]) debug.setupvalue(t[1], i-1, t[i])
end end
end end
]] ]]
local lua_reserved_keywords = { local lua_reserved_keywords = {
'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for',
'function', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat', 'function', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat',
'return', 'then', 'true', 'until', 'while' } 'return', 'then', 'true', 'until', 'while' }
local function keys(t) local function keys(t)
@ -63,7 +63,7 @@ local function keys(t)
end end
local c_functions = {} local c_functions = {}
for _,lib in pairs{'_G', 'string', 'table', 'math', for _,lib in pairs{'_G', 'string', 'table', 'math',
'io', 'os', 'coroutine', 'package', 'debug'} do 'io', 'os', 'coroutine', 'package', 'debug'} do
local t = _G[lib] or {} local t = _G[lib] or {}
lib = lib .. "." lib = lib .. "."
@ -79,9 +79,9 @@ function DataDumper(value, varname, fastmode, ident, indent_step)
indent_step = indent_step or 2 indent_step = indent_step or 2
local defined, dumplua = {} local defined, dumplua = {}
-- Local variables for speed optimization -- Local variables for speed optimization
local string_format, type, string_dump, string_rep = local string_format, type, string_dump, string_rep =
string.format, type, string.dump, string.rep string.format, type, string.dump, string.rep
local tostring, pairs, table_concat = local tostring, pairs, table_concat =
tostring, pairs, table.concat tostring, pairs, table.concat
local keycache, strvalcache, out, closure_cnt = {}, {}, {}, 0 local keycache, strvalcache, out, closure_cnt = {}, {}, {}, 0
setmetatable(strvalcache, {__index = function(t,value) setmetatable(strvalcache, {__index = function(t,value)
@ -94,8 +94,8 @@ function DataDumper(value, varname, fastmode, ident, indent_step)
number = function(value) return value end, number = function(value) return value end,
boolean = function(value) return tostring(value) end, boolean = function(value) return tostring(value) end,
['nil'] = function(value) return 'nil' end, ['nil'] = function(value) return 'nil' end,
['function'] = function(value) ['function'] = function(value)
return string_format("loadstring(%q)", string_dump(value)) return string_format("loadstring(%q)", string_dump(value))
end, end,
userdata = function() error("Cannot dump userdata") end, userdata = function() error("Cannot dump userdata") end,
thread = function() error("Cannot dump threads") end, thread = function() error("Cannot dump threads") end,
@ -124,7 +124,7 @@ function DataDumper(value, varname, fastmode, ident, indent_step)
for _,k in ipairs(lua_reserved_keywords) do for _,k in ipairs(lua_reserved_keywords) do
keycache[k] = '["'..k..'"] = ' keycache[k] = '["'..k..'"] = '
end end
if fastmode then if fastmode then
fcts.table = function (value) fcts.table = function (value)
-- Table value -- Table value
local numidx = 1 local numidx = 1
@ -142,9 +142,9 @@ function DataDumper(value, varname, fastmode, ident, indent_step)
out[#out] = string.sub(out[#out], 1, -2); out[#out] = string.sub(out[#out], 1, -2);
end end
out[#out+1] = "}" out[#out+1] = "}"
return "" return ""
end end
else else
fcts.table = function (value, ident, path) fcts.table = function (value, ident, path)
if test_defined(value, path) then return "nil" end if test_defined(value, path) then return "nil" end
-- Table value -- Table value
@ -174,7 +174,7 @@ function DataDumper(value, varname, fastmode, ident, indent_step)
if totallen > 80 then if totallen > 80 then
sep = "\n" .. string_rep(' ', indent_step*(ident+1)) sep = "\n" .. string_rep(' ', indent_step*(ident+1))
end end
str = "{"..sep..table_concat(str, ","..sep).." "..sep:sub(1,-1-indent_step).."}" str = "{"..sep..table_concat(str, ","..sep).." "..sep:sub(1,-1-indent_step).."}"
if meta then if meta then
sep = sep:sub(1,-3) sep = sep:sub(1,-3)
return "setmetatable("..sep..str..","..sep..metastr..sep:sub(1,-3)..")" return "setmetatable("..sep..str..","..sep..metastr..sep:sub(1,-3)..")"

@ -129,9 +129,9 @@ function BuildingDialog:initBuiltinMode()
cb = self:callback('initCustomMode') cb = self:callback('initCustomMode')
}) })
end end
for i=0,df.building_type._last_item do for i=0,df.building_type._last_item do
if (not WORKSHOP_ABSTRACT[i] or self.use_abstract)and not WORKSHOP_SPECIAL[i] then if (not WORKSHOP_ABSTRACT[i] or self.use_abstract)and not WORKSHOP_SPECIAL[i] then
self:addBuilding(choices, df.building_type[i], i, -1,-1,nil) self:addBuilding(choices, df.building_type[i], i, -1,-1,nil)

@ -1,300 +1,300 @@
local _ENV = mkmodule('makeown') local _ENV = mkmodule('makeown')
--[[ --[[
'tweak makeown' as a lua include 'tweak makeown' as a lua include
make_own(unit) -- removes foreign flags, sets civ_id to fort civ_id, and sets clothes ownership make_own(unit) -- removes foreign flags, sets civ_id to fort civ_id, and sets clothes ownership
make_citizen(unit) -- called by make_own if unit.race == fort race make_citizen(unit) -- called by make_own if unit.race == fort race
eventually ought to migrate to hack/lua/plugins/tweak.lua eventually ought to migrate to hack/lua/plugins/tweak.lua
and local _ENV = mkmodule('plugin.tweak') and local _ENV = mkmodule('plugin.tweak')
in order to link to functions in the compiled plugin (when/if they become available to lua) in order to link to functions in the compiled plugin (when/if they become available to lua)
--]] --]]
local utils = require 'utils' local utils = require 'utils'
local function fix_clothing_ownership(unit) local function fix_clothing_ownership(unit)
-- extracted/translated from tweak makeown plugin -- extracted/translated from tweak makeown plugin
-- to be called by tweak-fixmigrant/makeown -- to be called by tweak-fixmigrant/makeown
-- units forced into the fort by removing the flags do not own their clothes -- units forced into the fort by removing the flags do not own their clothes
-- which has the result that they drop all their clothes and become unhappy because they are naked -- which has the result that they drop all their clothes and become unhappy because they are naked
-- so we need to make them own their clothes and add them to their uniform -- so we need to make them own their clothes and add them to their uniform
local fixcount = 0 --int fixcount = 0; local fixcount = 0 --int fixcount = 0;
for j=0,#unit.inventory-1 do --for(size_t j=0; j<unit->inventory.size(); j++) for j=0,#unit.inventory-1 do --for(size_t j=0; j<unit->inventory.size(); j++)
local inv_item = unit.inventory[j] --unidf::unit_inventory_item* inv_item = unit->inventory[j]; local inv_item = unit.inventory[j] --unidf::unit_inventory_item* inv_item = unit->inventory[j];
local item = inv_item.item --df::item* item = inv_item->item; local item = inv_item.item --df::item* item = inv_item->item;
-- unforbid items (for the case of kidnapping caravan escorts who have their stuff forbidden by default) -- unforbid items (for the case of kidnapping caravan escorts who have their stuff forbidden by default)
-- moved forbid false to inside if so that armor/weapons stay equiped -- moved forbid false to inside if so that armor/weapons stay equiped
if inv_item.mode == df.unit_inventory_item.T_mode.Worn then --if(inv_item->mode == df::unit_inventory_item::T_mode::Worn) if inv_item.mode == df.unit_inventory_item.T_mode.Worn then --if(inv_item->mode == df::unit_inventory_item::T_mode::Worn)
-- ignore armor? -- ignore armor?
-- it could be leather boots, for example, in which case it would not be nice to forbid ownership -- it could be leather boots, for example, in which case it would not be nice to forbid ownership
--if(item->getEffectiveArmorLevel() != 0) --if(item->getEffectiveArmorLevel() != 0)
-- continue; -- continue;
if not dfhack.items.getOwner(item) then --if(!Items::getOwner(item)) if not dfhack.items.getOwner(item) then --if(!Items::getOwner(item))
if dfhack.items.setOwner(item,unit) then --if(Items::setOwner(item, unit)) if dfhack.items.setOwner(item,unit) then --if(Items::setOwner(item, unit))
item.flags.forbid = false --inv_item->item->flags.bits.forbid = 0; item.flags.forbid = false --inv_item->item->flags.bits.forbid = 0;
-- add to uniform, so they know they should wear their clothes -- add to uniform, so they know they should wear their clothes
unit.military.uniforms[0]:insert('#',item.id) --insert_into_vector(unit->military.uniforms[0], item->id); unit.military.uniforms[0]:insert('#',item.id) --insert_into_vector(unit->military.uniforms[0], item->id);
fixcount = fixcount + 1 --fixcount++; fixcount = fixcount + 1 --fixcount++;
else else
----out << "could not change ownership for item!" << endl; ----out << "could not change ownership for item!" << endl;
print("Makeown: could not change ownership for an item!") print("Makeown: could not change ownership for an item!")
end end
end end
end end
end end
-- clear uniform_drop (without this they would drop their clothes and pick them up some time later) -- clear uniform_drop (without this they would drop their clothes and pick them up some time later)
-- dirty? -- dirty?
unit.military.uniform_drop:resize(0) --unit->military.uniform_drop.clear(); unit.military.uniform_drop:resize(0) --unit->military.uniform_drop.clear();
----out << "ownership for " << fixcount << " clothes fixed" << endl; ----out << "ownership for " << fixcount << " clothes fixed" << endl;
print("Makeown: claimed ownership for "..tostring(fixcount).." worn items") print("Makeown: claimed ownership for "..tostring(fixcount).." worn items")
--return true --return CR_OK; --return true --return CR_OK;
end end
local function entity_link(hf, eid, do_event, add, replace_idx) local function entity_link(hf, eid, do_event, add, replace_idx)
do_event = (do_event == nil) and true or do_event do_event = (do_event == nil) and true or do_event
add = (add == nil) and true or add add = (add == nil) and true or add
replace_idx = replace_idx or -1 replace_idx = replace_idx or -1
local link = add and df.histfig_entity_link_memberst:new() or df.histfig_entity_link_former_memberst:new() local link = add and df.histfig_entity_link_memberst:new() or df.histfig_entity_link_former_memberst:new()
link.entity_id = eid link.entity_id = eid
if replace_idx > -1 then if replace_idx > -1 then
local e = hf.entity_links[replace_idx] local e = hf.entity_links[replace_idx]
link.link_strength = (e.link_strength > 3) and (e.link_strength - 2) or e.link_strength link.link_strength = (e.link_strength > 3) and (e.link_strength - 2) or e.link_strength
hf.entity_links[replace_idx] = link -- replace member link with former member link hf.entity_links[replace_idx] = link -- replace member link with former member link
e:delete() e:delete()
else else
link.link_strength = 100 link.link_strength = 100
hf.entity_links:insert('#', link) hf.entity_links:insert('#', link)
end end
if do_event then if do_event then
event = add and df.history_event_add_hf_entity_linkst:new() or df.history_event_remove_hf_entity_linkst:new() event = add and df.history_event_add_hf_entity_linkst:new() or df.history_event_remove_hf_entity_linkst:new()
event.year = df.global.cur_year event.year = df.global.cur_year
event.seconds = df.global.cur_year_tick event.seconds = df.global.cur_year_tick
event.civ = eid event.civ = eid
event.histfig = hf.id event.histfig = hf.id
event.link_type = 0 event.link_type = 0
event.position_id = -1 event.position_id = -1
event.id = df.global.hist_event_next_id event.id = df.global.hist_event_next_id
df.global.world.history.events:insert('#',event) df.global.world.history.events:insert('#',event)
df.global.hist_event_next_id = df.global.hist_event_next_id + 1 df.global.hist_event_next_id = df.global.hist_event_next_id + 1
end end
end end
local function change_state(hf, site_id, pos) local function change_state(hf, site_id, pos)
hf.info.unk_14.unk_0 = 3 -- state? arrived? hf.info.unk_14.unk_0 = 3 -- state? arrived?
hf.info.unk_14.region:assign(pos) hf.info.unk_14.region:assign(pos)
hf.info.unk_14.site = site_id hf.info.unk_14.site = site_id
event = df.history_event_change_hf_statest:new() event = df.history_event_change_hf_statest:new()
event.year = df.global.cur_year event.year = df.global.cur_year
event.seconds = df.global.cur_year_tick event.seconds = df.global.cur_year_tick
event.hfid = hf.id event.hfid = hf.id
event.state = 3 event.state = 3
event.site = site_id event.site = site_id
event.region_pos:assign(pos) event.region_pos:assign(pos)
event.substate = -1; event.region = -1; event.layer = -1; event.substate = -1; event.region = -1; event.layer = -1;
event.id = df.global.hist_event_next_id event.id = df.global.hist_event_next_id
df.global.world.history.events:insert('#',event) df.global.world.history.events:insert('#',event)
df.global.hist_event_next_id = df.global.hist_event_next_id + 1 df.global.hist_event_next_id = df.global.hist_event_next_id + 1
end end
function make_citizen(unit) function make_citizen(unit)
local dfg = df.global local dfg = df.global
local civ_id = dfg.ui.civ_id local civ_id = dfg.ui.civ_id
local group_id = dfg.ui.group_id local group_id = dfg.ui.group_id
local events = dfg.world.history.events local events = dfg.world.history.events
local fortent = dfg.ui.main.fortress_entity local fortent = dfg.ui.main.fortress_entity
local civent = fortent and df.historical_entity.find(fortent.entity_links[0].target) local civent = fortent and df.historical_entity.find(fortent.entity_links[0].target)
-- utils.binsearch(dfg.world.entities.all, fortent.entity_links[0].target, 'id') -- utils.binsearch(dfg.world.entities.all, fortent.entity_links[0].target, 'id')
local event local event
local region_pos = df.world_site.find(dfg.ui.site_id).pos -- used with state events and hf state local region_pos = df.world_site.find(dfg.ui.site_id).pos -- used with state events and hf state
local hf local hf
-- assume that hf id 1 and hf id 2 are equal. I am unaware of instances of when they are not. -- assume that hf id 1 and hf id 2 are equal. I am unaware of instances of when they are not.
-- occationally a unit does not have both flags set (missing flags1.important_historical_figure) -- occationally a unit does not have both flags set (missing flags1.important_historical_figure)
-- and I don't know what that means yet. -- and I don't know what that means yet.
if unit.flags1.important_historical_figure and unit.flags2.important_historical_figure then if unit.flags1.important_historical_figure and unit.flags2.important_historical_figure then
-- aready hf, find it (unlikely to happen) -- aready hf, find it (unlikely to happen)
hf = utils.binsearch(dfg.world.history.figures, unit.hist_figure_id, 'id') hf = utils.binsearch(dfg.world.history.figures, unit.hist_figure_id, 'id')
--elseif unit.flags1.important_historical_figure or unit.flags2.important_historical_figure then --elseif unit.flags1.important_historical_figure or unit.flags2.important_historical_figure then
-- something wrong, try to fix it? -- something wrong, try to fix it?
--[[ --[[
if unit.hist_figure_id == -1 then if unit.hist_figure_id == -1 then
unit.hist_figure_id = unit.hist_figure_id2 unit.hist_figure_id = unit.hist_figure_id2
end end
if unit.hist_figure_id > -1 then if unit.hist_figure_id > -1 then
unit.hist_figure_id2 = unit.hist_figure_id unit.hist_figure_id2 = unit.hist_figure_id
unit.flags1.important_historical_figure = true unit.flags1.important_historical_figure = true
unit.flags2.important_historical_figure = true unit.flags2.important_historical_figure = true
hf = utils.binsearch(dfg.world.history.figures, unit.hist_figure_id, 'id') hf = utils.binsearch(dfg.world.history.figures, unit.hist_figure_id, 'id')
else else
unit.flags1.important_historical_figure = false unit.flags1.important_historical_figure = false
unit.flags2.important_historical_figure = false unit.flags2.important_historical_figure = false
end end
--]] --]]
--else --else
-- make one -- make one
end end
--local new_hf = false --local new_hf = false
if not hf then if not hf then
--new_hf = true --new_hf = true
hf = df.historical_figure:new() hf = df.historical_figure:new()
hf.profession = unit.profession hf.profession = unit.profession
hf.race = unit.race hf.race = unit.race
hf.caste = unit.caste hf.caste = unit.caste
hf.sex = unit.sex hf.sex = unit.sex
hf.appeared_year = dfg.cur_year hf.appeared_year = dfg.cur_year
hf.born_year = unit.relations.birth_year hf.born_year = unit.relations.birth_year
hf.born_seconds = unit.relations.birth_time hf.born_seconds = unit.relations.birth_time
hf.curse_year = unit.relations.curse_year hf.curse_year = unit.relations.curse_year
hf.curse_seconds = unit.relations.curse_time hf.curse_seconds = unit.relations.curse_time
hf.anon_1 = unit.relations.anon_2 hf.anon_1 = unit.relations.anon_2
hf.anon_2 = unit.relations.anon_3 hf.anon_2 = unit.relations.anon_3
hf.old_year = unit.relations.old_year hf.old_year = unit.relations.old_year
hf.old_seconds = unit.relations.old_time hf.old_seconds = unit.relations.old_time
hf.died_year = -1 hf.died_year = -1
hf.died_seconds = -1 hf.died_seconds = -1
hf.name:assign(unit.name) hf.name:assign(unit.name)
hf.civ_id = unit.civ_id hf.civ_id = unit.civ_id
hf.population_id = unit.population_id hf.population_id = unit.population_id
hf.breed_id = -1 hf.breed_id = -1
hf.unit_id = unit.id hf.unit_id = unit.id
hf.id = dfg.hist_figure_next_id -- id must be set before adding links (for the events) hf.id = dfg.hist_figure_next_id -- id must be set before adding links (for the events)
--history_event_add_hf_entity_linkst not reported for civ on starting 7 --history_event_add_hf_entity_linkst not reported for civ on starting 7
entity_link(hf, civ_id, false) -- so lets skip event here entity_link(hf, civ_id, false) -- so lets skip event here
entity_link(hf, group_id) entity_link(hf, group_id)
hf.info = df.historical_figure_info:new() hf.info = df.historical_figure_info:new()
hf.info.unk_14 = df.historical_figure_info.T_unk_14:new() -- hf state? hf.info.unk_14 = df.historical_figure_info.T_unk_14:new() -- hf state?
--unk_14.region_id = -1; unk_14.beast_id = -1; unk_14.unk_14 = 0 --unk_14.region_id = -1; unk_14.beast_id = -1; unk_14.unk_14 = 0
hf.info.unk_14.unk_18 = -1; hf.info.unk_14.unk_1c = -1 hf.info.unk_14.unk_18 = -1; hf.info.unk_14.unk_1c = -1
-- set values that seem related to state and do event -- set values that seem related to state and do event
change_state(hf, dfg.ui.site_id, region_pos) change_state(hf, dfg.ui.site_id, region_pos)
--lets skip skills for now --lets skip skills for now
--local skills = df.historical_figure_info.T_skills:new() -- skills snap shot --local skills = df.historical_figure_info.T_skills:new() -- skills snap shot
-- ... -- ...
--info.skills = skills --info.skills = skills
dfg.world.history.figures:insert('#', hf) dfg.world.history.figures:insert('#', hf)
dfg.hist_figure_next_id = dfg.hist_figure_next_id + 1 dfg.hist_figure_next_id = dfg.hist_figure_next_id + 1
--new_hf_loc = df.global.world.history.figures[#df.global.world.history.figures - 1] --new_hf_loc = df.global.world.history.figures[#df.global.world.history.figures - 1]
fortent.histfig_ids:insert('#', hf.id) fortent.histfig_ids:insert('#', hf.id)
fortent.hist_figures:insert('#', hf) fortent.hist_figures:insert('#', hf)
civent.histfig_ids:insert('#', hf.id) civent.histfig_ids:insert('#', hf.id)
civent.hist_figures:insert('#', hf) civent.hist_figures:insert('#', hf)
unit.flags1.important_historical_figure = true unit.flags1.important_historical_figure = true
unit.flags2.important_historical_figure = true unit.flags2.important_historical_figure = true
unit.hist_figure_id = hf.id unit.hist_figure_id = hf.id
unit.hist_figure_id2 = hf.id unit.hist_figure_id2 = hf.id
print("Makeown-citizen: created historical figure") print("Makeown-citizen: created historical figure")
else else
-- only insert into civ/fort if not already there -- only insert into civ/fort if not already there
-- Migrants change previous histfig_entity_link_memberst to histfig_entity_link_former_memberst -- Migrants change previous histfig_entity_link_memberst to histfig_entity_link_former_memberst
-- for group entities, add link_member for new group, and reports events for remove from group, -- for group entities, add link_member for new group, and reports events for remove from group,
-- remove from civ, change state, add civ, and add group -- remove from civ, change state, add civ, and add group
hf.civ_id = civ_id -- ensure current civ_id hf.civ_id = civ_id -- ensure current civ_id
local found_civlink = false
local found_fortlink = false
local v = hf.entity_links
for k=#v-1,0,-1 do
if df.histfig_entity_link_memberst:is_instance(v[k]) then
entity_link(hf, v[k].entity_id, true, false, k)
end
end
if hf.info and hf.info.unk_14 then
change_state(hf, dfg.ui.site_id, region_pos)
-- leave info nil if not found for now
end
if not found_civlink then entity_link(hf,civ_id) end
if not found_fortlink then entity_link(hf,group_id) end
--change entity_links
local found = false
for _,v in ipairs(civent.histfig_ids) do
if v == hf.id then found = true; break end
end
if not found then
civent.histfig_ids:insert('#', hf.id)
civent.hist_figures:insert('#', hf)
end
found = false
for _,v in ipairs(fortent.histfig_ids) do
if v == hf.id then found = true; break end
end
if not found then
fortent.histfig_ids:insert('#', hf.id)
fortent.hist_figures:insert('#', hf)
end
print("Makeown-citizen: migrated historical figure")
end -- hf
local found_civlink = false local nemesis = dfhack.units.getNemesis(unit)
local found_fortlink = false if not nemesis then
local v = hf.entity_links nemesis = df.nemesis_record:new()
for k=#v-1,0,-1 do nemesis.figure = hf
if df.histfig_entity_link_memberst:is_instance(v[k]) then nemesis.unit = unit
entity_link(hf, v[k].entity_id, true, false, k) nemesis.unit_id = unit.id
end nemesis.save_file_id = civent.save_file_id
end nemesis.unk10, nemesis.unk11, nemesis.unk12 = -1, -1, -1
--group_leader_id = -1
if hf.info and hf.info.unk_14 then nemesis.id = dfg.nemesis_next_id
change_state(hf, dfg.ui.site_id, region_pos) nemesis.member_idx = civent.next_member_idx
-- leave info nil if not found for now civent.next_member_idx = civent.next_member_idx + 1
end
if not found_civlink then entity_link(hf,civ_id) end
if not found_fortlink then entity_link(hf,group_id) end
--change entity_links
local found = false
for _,v in ipairs(civent.histfig_ids) do
if v == hf.id then found = true; break end
end
if not found then
civent.histfig_ids:insert('#', hf.id)
civent.hist_figures:insert('#', hf)
end
found = false
for _,v in ipairs(fortent.histfig_ids) do
if v == hf.id then found = true; break end
end
if not found then
fortent.histfig_ids:insert('#', hf.id)
fortent.hist_figures:insert('#', hf)
end
print("Makeown-citizen: migrated historical figure")
end -- hf
local nemesis = dfhack.units.getNemesis(unit) dfg.world.nemesis.all:insert('#', nemesis)
if not nemesis then dfg.nemesis_next_id = dfg.nemesis_next_id + 1
nemesis = df.nemesis_record:new()
nemesis.figure = hf
nemesis.unit = unit
nemesis.unit_id = unit.id
nemesis.save_file_id = civent.save_file_id
nemesis.unk10, nemesis.unk11, nemesis.unk12 = -1, -1, -1
--group_leader_id = -1
nemesis.id = dfg.nemesis_next_id
nemesis.member_idx = civent.next_member_idx
civent.next_member_idx = civent.next_member_idx + 1
dfg.world.nemesis.all:insert('#', nemesis) nemesis_link = df.general_ref_is_nemesisst:new()
dfg.nemesis_next_id = dfg.nemesis_next_id + 1 nemesis_link.nemesis_id = nemesis.id
unit.general_refs:insert('#', nemesis_link)
nemesis_link = df.general_ref_is_nemesisst:new() --new_nemesis_loc = df.global.world.nemesis.all[#df.global.world.nemesis.all - 1]
nemesis_link.nemesis_id = nemesis.id fortent.nemesis_ids:insert('#', nemesis.id)
unit.general_refs:insert('#', nemesis_link) fortent.nemesis:insert('#', nemesis)
civent.nemesis_ids:insert('#', nemesis.id)
--new_nemesis_loc = df.global.world.nemesis.all[#df.global.world.nemesis.all - 1] civent.nemesis:insert('#', nemesis)
fortent.nemesis_ids:insert('#', nemesis.id) print("Makeown-citizen: created nemesis entry")
fortent.nemesis:insert('#', nemesis) else-- only insert into civ/fort if not already there
civent.nemesis_ids:insert('#', nemesis.id) local found = false
civent.nemesis:insert('#', nemesis) for _,v in ipairs(civent.nemesis_ids) do
print("Makeown-citizen: created nemesis entry") if v == nemesis.id then found = true; break end
else-- only insert into civ/fort if not already there end
local found = false if not found then
for _,v in ipairs(civent.nemesis_ids) do civent.nemesis_ids:insert('#', nemesis.id)
if v == nemesis.id then found = true; break end civent.nemesis:insert('#', nemesis)
end end
if not found then found = false
civent.nemesis_ids:insert('#', nemesis.id) for _,v in ipairs(fortent.nemesis_ids) do
civent.nemesis:insert('#', nemesis) if v == nemesis.id then found = true; break end
end end
found = false if not found then
for _,v in ipairs(fortent.nemesis_ids) do fortent.nemesis_ids:insert('#', nemesis.id)
if v == nemesis.id then found = true; break end fortent.nemesis:insert('#', nemesis)
end end
if not found then print("Makeown-citizen: migrated nemesis entry")
fortent.nemesis_ids:insert('#', nemesis.id) end -- nemesis
fortent.nemesis:insert('#', nemesis)
end
print("Makeown-citizen: migrated nemesis entry")
end -- nemesis
end end
function make_own(unit) function make_own(unit)
--tweak makeown --tweak makeown
unit.flags2.resident = false; unit.flags1.merchant = false; unit.flags1.forest = false; unit.flags2.resident = false; unit.flags1.merchant = false; unit.flags1.forest = false;
unit.civ_id = df.global.ui.civ_id unit.civ_id = df.global.ui.civ_id
if unit.profession == df.profession.MERCHANT then unit.profession = df.profession.TRADER end if unit.profession == df.profession.MERCHANT then unit.profession = df.profession.TRADER end
if unit.profession2 == df.profession.MERCHANT then unit.profession2 = df.profession.TRADER end if unit.profession2 == df.profession.MERCHANT then unit.profession2 = df.profession.TRADER end
fix_clothing_ownership(unit) fix_clothing_ownership(unit)
if unit.race == df.global.ui.race_id then if unit.race == df.global.ui.race_id then
make_citizen(unit) make_citizen(unit)
end end
end end

@ -111,7 +111,7 @@ void DFHack::EventManager::unregisterAll(Plugin* plugin) {
for ( auto i = handlers[EventType::TICK].find(plugin); i != handlers[EventType::TICK].end(); i++ ) { for ( auto i = handlers[EventType::TICK].find(plugin); i != handlers[EventType::TICK].end(); i++ ) {
if ( (*i).first != plugin ) if ( (*i).first != plugin )
break; break;
removeFromTickQueue((*i).second); removeFromTickQueue((*i).second);
} }
for ( size_t a = 0; a < (size_t)EventType::EVENT_MAX; a++ ) { for ( size_t a = 0; a < (size_t)EventType::EVENT_MAX; a++ ) {
@ -248,12 +248,12 @@ void DFHack::EventManager::onStateChange(color_ostream& out, state_change_event
return; return;
if (!df::global::world) if (!df::global::world)
return; return;
nextItem = *df::global::item_next_id; nextItem = *df::global::item_next_id;
nextBuilding = *df::global::building_next_id; nextBuilding = *df::global::building_next_id;
nextInvasion = df::global::ui->invasions.next_id; nextInvasion = df::global::ui->invasions.next_id;
lastJobId = -1 + *df::global::job_next_id; lastJobId = -1 + *df::global::job_next_id;
constructions.clear(); constructions.clear();
for ( auto i = df::global::world->constructions.begin(); i != df::global::world->constructions.end(); i++ ) { for ( auto i = df::global::world->constructions.begin(); i != df::global::world->constructions.end(); i++ ) {
df::construction* constr = *i; df::construction* constr = *i;
@ -296,7 +296,7 @@ void DFHack::EventManager::onStateChange(color_ostream& out, state_change_event
for ( size_t a = 0; a < EventType::EVENT_MAX; a++ ) { for ( size_t a = 0; a < EventType::EVENT_MAX; a++ ) {
eventLastTick[a] = -1;//-1000000; eventLastTick[a] = -1;//-1000000;
} }
gameLoaded = true; gameLoaded = true;
} }
} }
@ -309,7 +309,7 @@ void DFHack::EventManager::manageEvents(color_ostream& out) {
return; return;
CoreSuspender suspender; CoreSuspender suspender;
int32_t tick = df::global::world->frame_counter; int32_t tick = df::global::world->frame_counter;
for ( size_t a = 0; a < EventType::EVENT_MAX; a++ ) { for ( size_t a = 0; a < EventType::EVENT_MAX; a++ ) {
@ -323,10 +323,10 @@ void DFHack::EventManager::manageEvents(color_ostream& out) {
eventFrequency = bob.freq; eventFrequency = bob.freq;
} }
else eventFrequency = 1; else eventFrequency = 1;
if ( tick >= eventLastTick[a] && tick - eventLastTick[a] < eventFrequency ) if ( tick >= eventLastTick[a] && tick - eventLastTick[a] < eventFrequency )
continue; continue;
eventManager[a](out); eventManager[a](out);
eventLastTick[a] = tick; eventLastTick[a] = tick;
} }
@ -369,12 +369,12 @@ static void manageJobInitiatedEvent(color_ostream& out) {
lastJobId = *df::global::job_next_id - 1; lastJobId = *df::global::job_next_id - 1;
return; return;
} }
if ( lastJobId+1 == *df::global::job_next_id ) { if ( lastJobId+1 == *df::global::job_next_id ) {
return; //no new jobs return; //no new jobs
} }
multimap<Plugin*,EventHandler> copy(handlers[EventType::JOB_INITIATED].begin(), handlers[EventType::JOB_INITIATED].end()); multimap<Plugin*,EventHandler> copy(handlers[EventType::JOB_INITIATED].begin(), handlers[EventType::JOB_INITIATED].end());
for ( df::job_list_link* link = &df::global::world->job_list; link != NULL; link = link->next ) { for ( df::job_list_link* link = &df::global::world->job_list; link != NULL; link = link->next ) {
if ( link->item == NULL ) if ( link->item == NULL )
continue; continue;
@ -384,7 +384,7 @@ static void manageJobInitiatedEvent(color_ostream& out) {
(*i).second.eventHandler(out, (void*)link->item); (*i).second.eventHandler(out, (void*)link->item);
} }
} }
lastJobId = *df::global::job_next_id - 1; lastJobId = *df::global::job_next_id - 1;
} }
@ -402,7 +402,7 @@ static void manageJobCompletedEvent(color_ostream& out) {
return; return;
int32_t tick0 = eventLastTick[EventType::JOB_COMPLETED]; int32_t tick0 = eventLastTick[EventType::JOB_COMPLETED];
int32_t tick1 = df::global::world->frame_counter; int32_t tick1 = df::global::world->frame_counter;
multimap<Plugin*,EventHandler> copy(handlers[EventType::JOB_COMPLETED].begin(), handlers[EventType::JOB_COMPLETED].end()); multimap<Plugin*,EventHandler> copy(handlers[EventType::JOB_COMPLETED].begin(), handlers[EventType::JOB_COMPLETED].end());
map<int32_t, df::job*> nowJobs; map<int32_t, df::job*> nowJobs;
for ( df::job_list_link* link = &df::global::world->job_list; link != NULL; link = link->next ) { for ( df::job_list_link* link = &df::global::world->job_list; link != NULL; link = link->next ) {
@ -410,14 +410,14 @@ static void manageJobCompletedEvent(color_ostream& out) {
continue; continue;
nowJobs[link->item->id] = link->item; nowJobs[link->item->id] = link->item;
} }
#if 0 #if 0
//testing info on job initiation/completion //testing info on job initiation/completion
//newly allocated jobs //newly allocated jobs
for ( auto j = nowJobs.begin(); j != nowJobs.end(); j++ ) { for ( auto j = nowJobs.begin(); j != nowJobs.end(); j++ ) {
if ( prevJobs.find((*j).first) != prevJobs.end() ) if ( prevJobs.find((*j).first) != prevJobs.end() )
continue; continue;
df::job& job1 = *(*j).second; df::job& job1 = *(*j).second;
out.print("new job\n" out.print("new job\n"
" location : 0x%X\n" " location : 0x%X\n"
@ -445,12 +445,12 @@ static void manageJobCompletedEvent(color_ostream& out) {
continue; continue;
} }
df::job& job1 = *(*j).second; df::job& job1 = *(*j).second;
if ( job0.flags.bits.working == job1.flags.bits.working && if ( job0.flags.bits.working == job1.flags.bits.working &&
(job0.completion_timer == job1.completion_timer || (job1.completion_timer > 0 && job0.completion_timer-1 == job1.completion_timer)) && (job0.completion_timer == job1.completion_timer || (job1.completion_timer > 0 && job0.completion_timer-1 == job1.completion_timer)) &&
getWorkerID(&job0) == getWorkerID(&job1) ) getWorkerID(&job0) == getWorkerID(&job1) )
continue; continue;
out.print("job change\n" out.print("job change\n"
" location : 0x%X -> 0x%X\n" " location : 0x%X -> 0x%X\n"
" id : %d -> %d\n" " id : %d -> %d\n"
@ -472,12 +472,12 @@ static void manageJobCompletedEvent(color_ostream& out) {
); );
} }
#endif #endif
for ( auto i = prevJobs.begin(); i != prevJobs.end(); i++ ) { for ( auto i = prevJobs.begin(); i != prevJobs.end(); i++ ) {
//if it happened within a tick, must have been cancelled by the user or a plugin: not completed //if it happened within a tick, must have been cancelled by the user or a plugin: not completed
if ( tick1 <= tick0 ) if ( tick1 <= tick0 )
continue; continue;
if ( nowJobs.find((*i).first) != nowJobs.end() ) { if ( nowJobs.find((*i).first) != nowJobs.end() ) {
//could have just finished if it's a repeat job //could have just finished if it's a repeat job
df::job& job0 = *(*i).second; df::job& job0 = *(*i).second;
@ -488,19 +488,19 @@ static void manageJobCompletedEvent(color_ostream& out) {
continue; continue;
if ( job1.completion_timer != -1 ) if ( job1.completion_timer != -1 )
continue; continue;
//still false positive if cancelled at EXACTLY the right time, but experiments show this doesn't happen //still false positive if cancelled at EXACTLY the right time, but experiments show this doesn't happen
for ( auto j = copy.begin(); j != copy.end(); j++ ) { for ( auto j = copy.begin(); j != copy.end(); j++ ) {
(*j).second.eventHandler(out, (void*)&job0); (*j).second.eventHandler(out, (void*)&job0);
} }
continue; continue;
} }
//recently finished or cancelled job //recently finished or cancelled job
df::job& job0 = *(*i).second; df::job& job0 = *(*i).second;
if ( job0.flags.bits.repeat || job0.completion_timer != 0 ) if ( job0.flags.bits.repeat || job0.completion_timer != 0 )
continue; continue;
for ( auto j = copy.begin(); j != copy.end(); j++ ) { for ( auto j = copy.begin(); j != copy.end(); j++ ) {
(*j).second.eventHandler(out, (void*)&job0); (*j).second.eventHandler(out, (void*)&job0);
} }
@ -511,7 +511,7 @@ static void manageJobCompletedEvent(color_ostream& out) {
Job::deleteJobStruct((*i).second, true); Job::deleteJobStruct((*i).second, true);
} }
prevJobs.clear(); prevJobs.clear();
//create new jobs //create new jobs
for ( auto j = nowJobs.begin(); j != nowJobs.end(); j++ ) { for ( auto j = nowJobs.begin(); j != nowJobs.end(); j++ ) {
/*map<int32_t, df::job*>::iterator i = prevJobs.find((*j).first); /*map<int32_t, df::job*>::iterator i = prevJobs.find((*j).first);
@ -538,7 +538,7 @@ static void manageUnitDeathEvent(color_ostream& out) {
//dead: if dead since last check, trigger events //dead: if dead since last check, trigger events
if ( livingUnits.find(unit->id) == livingUnits.end() ) if ( livingUnits.find(unit->id) == livingUnits.end() )
continue; continue;
for ( auto i = copy.begin(); i != copy.end(); i++ ) { for ( auto i = copy.begin(); i != copy.end(); i++ ) {
(*i).second.eventHandler(out, (void*)unit->id); (*i).second.eventHandler(out, (void*)unit->id);
} }
@ -554,7 +554,7 @@ static void manageItemCreationEvent(color_ostream& out) {
if ( nextItem >= *df::global::item_next_id ) { if ( nextItem >= *df::global::item_next_id ) {
return; return;
} }
multimap<Plugin*,EventHandler> copy(handlers[EventType::ITEM_CREATED].begin(), handlers[EventType::ITEM_CREATED].end()); multimap<Plugin*,EventHandler> copy(handlers[EventType::ITEM_CREATED].begin(), handlers[EventType::ITEM_CREATED].end());
size_t index = df::item::binsearch_index(df::global::world->items.all, nextItem, false); size_t index = df::item::binsearch_index(df::global::world->items.all, nextItem, false);
if ( index != 0 ) index--; if ( index != 0 ) index--;
@ -607,7 +607,7 @@ static void manageBuildingEvent(color_ostream& out) {
} }
} }
nextBuilding = *df::global::building_next_id; nextBuilding = *df::global::building_next_id;
//now alert people about destroyed buildings //now alert people about destroyed buildings
for ( auto a = buildings.begin(); a != buildings.end(); ) { for ( auto a = buildings.begin(); a != buildings.end(); ) {
int32_t id = *a; int32_t id = *a;
@ -616,7 +616,7 @@ static void manageBuildingEvent(color_ostream& out) {
a++; a++;
continue; continue;
} }
for ( auto b = copy.begin(); b != copy.end(); b++ ) { for ( auto b = copy.begin(); b != copy.end(); b++ ) {
EventHandler bob = (*b).second; EventHandler bob = (*b).second;
bob.eventHandler(out, (void*)id); bob.eventHandler(out, (void*)id);
@ -629,7 +629,7 @@ static void manageConstructionEvent(color_ostream& out) {
if (!df::global::world) if (!df::global::world)
return; return;
//unordered_set<df::construction*> constructionsNow(df::global::world->constructions.begin(), df::global::world->constructions.end()); //unordered_set<df::construction*> constructionsNow(df::global::world->constructions.begin(), df::global::world->constructions.end());
multimap<Plugin*,EventHandler> copy(handlers[EventType::CONSTRUCTION].begin(), handlers[EventType::CONSTRUCTION].end()); multimap<Plugin*,EventHandler> copy(handlers[EventType::CONSTRUCTION].begin(), handlers[EventType::CONSTRUCTION].end());
for ( auto a = constructions.begin(); a != constructions.end(); ) { for ( auto a = constructions.begin(); a != constructions.end(); ) {
df::construction& construction = (*a).second; df::construction& construction = (*a).second;
@ -645,7 +645,7 @@ static void manageConstructionEvent(color_ostream& out) {
} }
a = constructions.erase(a); a = constructions.erase(a);
} }
//for ( auto a = constructionsNow.begin(); a != constructionsNow.end(); a++ ) { //for ( auto a = constructionsNow.begin(); a != constructionsNow.end(); a++ ) {
for ( auto a = df::global::world->constructions.begin(); a != df::global::world->constructions.end(); a++ ) { for ( auto a = df::global::world->constructions.begin(); a != df::global::world->constructions.end(); a++ ) {
df::construction* construction = *a; df::construction* construction = *a;
@ -680,7 +680,7 @@ static void manageSyndromeEvent(color_ostream& out) {
highestTime = startTime; highestTime = startTime;
if ( startTime <= lastSyndromeTime ) if ( startTime <= lastSyndromeTime )
continue; continue;
SyndromeData data(unit->id, b); SyndromeData data(unit->id, b);
for ( auto c = copy.begin(); c != copy.end(); c++ ) { for ( auto c = copy.begin(); c != copy.end(); c++ ) {
EventHandler handle = (*c).second; EventHandler handle = (*c).second;
@ -710,7 +710,7 @@ static void manageEquipmentEvent(color_ostream& out) {
if (!df::global::world) if (!df::global::world)
return; return;
multimap<Plugin*,EventHandler> copy(handlers[EventType::INVENTORY_CHANGE].begin(), handlers[EventType::INVENTORY_CHANGE].end()); multimap<Plugin*,EventHandler> copy(handlers[EventType::INVENTORY_CHANGE].begin(), handlers[EventType::INVENTORY_CHANGE].end());
unordered_map<int32_t, InventoryItem> itemIdToInventoryItem; unordered_map<int32_t, InventoryItem> itemIdToInventoryItem;
unordered_set<int32_t> currentlyEquipped; unordered_set<int32_t> currentlyEquipped;
for ( auto a = df::global::world->units.all.begin(); a != df::global::world->units.all.end(); a++ ) { for ( auto a = df::global::world->units.all.begin(); a != df::global::world->units.all.end(); a++ ) {
@ -720,7 +720,7 @@ static void manageEquipmentEvent(color_ostream& out) {
/*if ( unit->flags1.bits.dead ) /*if ( unit->flags1.bits.dead )
continue; continue;
*/ */
auto oldEquipment = equipmentLog.find(unit->id); auto oldEquipment = equipmentLog.find(unit->id);
bool hadEquipment = oldEquipment != equipmentLog.end(); bool hadEquipment = oldEquipment != equipmentLog.end();
vector<InventoryItem>* temp; vector<InventoryItem>* temp;
@ -750,13 +750,13 @@ static void manageEquipmentEvent(color_ostream& out) {
continue; continue;
} }
InventoryItem item_old = (*c).second; InventoryItem item_old = (*c).second;
df::unit_inventory_item& item0 = item_old.item; df::unit_inventory_item& item0 = item_old.item;
df::unit_inventory_item& item1 = item_new.item; df::unit_inventory_item& item1 = item_new.item;
if ( item0.mode == item1.mode && item0.body_part_id == item1.body_part_id && item0.wound_id == item1.wound_id ) if ( item0.mode == item1.mode && item0.body_part_id == item1.body_part_id && item0.wound_id == item1.wound_id )
continue; continue;
//some sort of change in how it's equipped //some sort of change in how it's equipped
InventoryChangeData data(unit->id, &item_old, &item_new); InventoryChangeData data(unit->id, &item_old, &item_new);
for ( auto h = copy.begin(); h != copy.end(); h++ ) { for ( auto h = copy.begin(); h != copy.end(); h++ ) {
EventHandler handle = (*h).second; EventHandler handle = (*h).second;
@ -777,7 +777,7 @@ static void manageEquipmentEvent(color_ostream& out) {
} }
if ( !hadEquipment ) if ( !hadEquipment )
delete temp; delete temp;
//update equipment //update equipment
vector<InventoryItem>& equipment = equipmentLog[unit->id]; vector<InventoryItem>& equipment = equipmentLog[unit->id];
equipment.clear(); equipment.clear();
@ -795,7 +795,7 @@ static void updateReportToRelevantUnits() {
if ( df::global::world->frame_counter <= reportToRelevantUnitsTime ) if ( df::global::world->frame_counter <= reportToRelevantUnitsTime )
return; return;
reportToRelevantUnitsTime = df::global::world->frame_counter; reportToRelevantUnitsTime = df::global::world->frame_counter;
for ( size_t a = 0; a < df::global::world->units.all.size(); a++ ) { for ( size_t a = 0; a < df::global::world->units.all.size(); a++ ) {
df::unit* unit = df::global::world->units.all[a]; df::unit* unit = df::global::world->units.all[a];
for ( int16_t b = df::enum_traits<df::unit_report_type>::first_item_value; b <= df::enum_traits<df::unit_report_type>::last_item_value; b++ ) { for ( int16_t b = df::enum_traits<df::unit_report_type>::first_item_value; b <= df::enum_traits<df::unit_report_type>::last_item_value; b++ ) {
@ -862,7 +862,7 @@ static void manageUnitAttackEvent(color_ostream& out) {
strikeReports.insert(report->id); strikeReports.insert(report->id);
} }
} }
if ( strikeReports.empty() ) if ( strikeReports.empty() )
return; return;
updateReportToRelevantUnits(); updateReportToRelevantUnits();
@ -883,37 +883,37 @@ static void manageUnitAttackEvent(color_ostream& out) {
break; break;
reportStr = reportStr + report2->text; reportStr = reportStr + report2->text;
} }
std::vector<int32_t>& relevantUnits = reportToRelevantUnits[report->id]; std::vector<int32_t>& relevantUnits = reportToRelevantUnits[report->id];
if ( relevantUnits.size() != 2 ) { if ( relevantUnits.size() != 2 ) {
continue; continue;
} }
df::unit* unit1 = df::unit::find(relevantUnits[0]); df::unit* unit1 = df::unit::find(relevantUnits[0]);
df::unit* unit2 = df::unit::find(relevantUnits[1]); df::unit* unit2 = df::unit::find(relevantUnits[1]);
df::unit_wound* wound1 = getWound(unit1,unit2); df::unit_wound* wound1 = getWound(unit1,unit2);
df::unit_wound* wound2 = getWound(unit2,unit1); df::unit_wound* wound2 = getWound(unit2,unit1);
if ( wound1 && !alreadyDone[unit1->id][unit2->id] ) { if ( wound1 && !alreadyDone[unit1->id][unit2->id] ) {
UnitAttackData data; UnitAttackData data;
data.attacker = unit1->id; data.attacker = unit1->id;
data.defender = unit2->id; data.defender = unit2->id;
data.wound = wound1->id; data.wound = wound1->id;
alreadyDone[data.attacker][data.defender] = 1; alreadyDone[data.attacker][data.defender] = 1;
for ( auto b = copy.begin(); b != copy.end(); b++ ) { for ( auto b = copy.begin(); b != copy.end(); b++ ) {
EventHandler handle = (*b).second; EventHandler handle = (*b).second;
handle.eventHandler(out, (void*)&data); handle.eventHandler(out, (void*)&data);
} }
} }
if ( wound2 && !alreadyDone[unit1->id][unit2->id] ) { if ( wound2 && !alreadyDone[unit1->id][unit2->id] ) {
UnitAttackData data; UnitAttackData data;
data.attacker = unit2->id; data.attacker = unit2->id;
data.defender = unit1->id; data.defender = unit1->id;
data.wound = wound2->id; data.wound = wound2->id;
alreadyDone[data.attacker][data.defender] = 1; alreadyDone[data.attacker][data.defender] = 1;
for ( auto b = copy.begin(); b != copy.end(); b++ ) { for ( auto b = copy.begin(); b != copy.end(); b++ ) {
EventHandler handle = (*b).second; EventHandler handle = (*b).second;
@ -932,7 +932,7 @@ static void manageUnitAttackEvent(color_ostream& out) {
handle.eventHandler(out, (void*)&data); handle.eventHandler(out, (void*)&data);
} }
} }
if ( unit2->flags1.bits.dead ) { if ( unit2->flags1.bits.dead ) {
UnitAttackData data; UnitAttackData data;
data.attacker = unit1->id; data.attacker = unit1->id;
@ -944,7 +944,7 @@ static void manageUnitAttackEvent(color_ostream& out) {
handle.eventHandler(out, (void*)&data); handle.eventHandler(out, (void*)&data);
} }
} }
if ( !wound1 && !wound2 ) { if ( !wound1 && !wound2 ) {
//if ( unit1->flags1.bits.dead || unit2->flags1.bits.dead ) //if ( unit1->flags1.bits.dead || unit2->flags1.bits.dead )
// continue; // continue;
@ -992,7 +992,7 @@ static std::string getVerb(df::unit* unit, std::string reportStr) {
static InteractionData getAttacker(color_ostream& out, df::report* attackEvent, df::unit* lastAttacker, df::report* defendEvent, vector<df::unit*>& relevantUnits) { static InteractionData getAttacker(color_ostream& out, df::report* attackEvent, df::unit* lastAttacker, df::report* defendEvent, vector<df::unit*>& relevantUnits) {
vector<df::unit*> attackers = relevantUnits; vector<df::unit*> attackers = relevantUnits;
vector<df::unit*> defenders = relevantUnits; vector<df::unit*> defenders = relevantUnits;
//find valid interactions: TODO //find valid interactions: TODO
/*map<int32_t,vector<df::interaction*> > validInteractions; /*map<int32_t,vector<df::interaction*> > validInteractions;
for ( size_t a = 0; a < relevantUnits.size(); a++ ) { for ( size_t a = 0; a < relevantUnits.size(); a++ ) {
@ -1000,7 +1000,7 @@ static InteractionData getAttacker(color_ostream& out, df::report* attackEvent,
vector<df::interaction*>& interactions = validInteractions[unit->id]; vector<df::interaction*>& interactions = validInteractions[unit->id];
for ( size_t b = 0; b < unit->body. for ( size_t b = 0; b < unit->body.
}*/ }*/
//if attackEvent //if attackEvent
// attacker must be same location // attacker must be same location
// attacker name must start attack str // attacker name must start attack str
@ -1019,7 +1019,7 @@ static InteractionData getAttacker(color_ostream& out, df::report* attackEvent,
a--; a--;
continue; continue;
} }
std::string verbC = getVerb(attackers[a], attackEvent->text); std::string verbC = getVerb(attackers[a], attackEvent->text);
if ( verbC.length() == 0 ) { if ( verbC.length() == 0 ) {
attackers.erase(attackers.begin()+a); attackers.erase(attackers.begin()+a);
@ -1029,7 +1029,7 @@ static InteractionData getAttacker(color_ostream& out, df::report* attackEvent,
attackVerb = verbC; attackVerb = verbC;
} }
} }
//if defendEvent //if defendEvent
// defender must be same location // defender must be same location
// defender name must start defend str // defender name must start defend str
@ -1052,7 +1052,7 @@ static InteractionData getAttacker(color_ostream& out, df::report* attackEvent,
defendVerb = verbC; defendVerb = verbC;
} }
} }
//keep in mind one attacker zero defenders is perfectly valid for self-cast //keep in mind one attacker zero defenders is perfectly valid for self-cast
if ( attackers.size() == 1 && defenders.size() == 1 && attackers[0] == defenders[0] ) { if ( attackers.size() == 1 && defenders.size() == 1 && attackers[0] == defenders[0] ) {
//out.print("%s,%d\n",__FILE__,__LINE__); //out.print("%s,%d\n",__FILE__,__LINE__);
@ -1070,7 +1070,7 @@ static InteractionData getAttacker(color_ostream& out, df::report* attackEvent,
defenders.erase(a); defenders.erase(a);
} }
} }
//if trying attack-defend pair and it fails to find attacker, try defend only //if trying attack-defend pair and it fails to find attacker, try defend only
InteractionData result = /*(InteractionData)*/ { std::string(), std::string(), -1, -1, -1, -1 }; InteractionData result = /*(InteractionData)*/ { std::string(), std::string(), -1, -1, -1, -1 };
if ( attackers.size() > 1 ) { if ( attackers.size() > 1 ) {
@ -1141,7 +1141,7 @@ static void manageInteractionEvent(color_ostream& out) {
} }
if ( a < reports.size() ) if ( a < reports.size() )
updateReportToRelevantUnits(); updateReportToRelevantUnits();
df::report* lastAttackEvent = NULL; df::report* lastAttackEvent = NULL;
df::unit* lastAttacker = NULL; df::unit* lastAttacker = NULL;
df::unit* lastDefender = NULL; df::unit* lastDefender = NULL;

@ -1362,23 +1362,23 @@ int32_t Items::createItem(df::item_type item_type, int16_t item_subtype, int16_t
prod->product_dimension = 1; prod->product_dimension = 1;
break; break;
} }
//makeItem //makeItem
vector<df::item*> out_items; vector<df::item*> out_items;
vector<df::reaction_reagent*> in_reag; vector<df::reaction_reagent*> in_reag;
vector<df::item*> in_items; vector<df::item*> in_items;
df::enums::game_type::game_type type = *df::global::gametype; df::enums::game_type::game_type type = *df::global::gametype;
prod->produce(unit, &out_items, &in_reag, &in_items, 1, job_skill::NONE, prod->produce(unit, &out_items, &in_reag, &in_items, 1, job_skill::NONE,
df::historical_entity::find(unit->civ_id), df::historical_entity::find(unit->civ_id),
((type == df::enums::game_type::DWARF_MAIN) || (type == df::enums::game_type::DWARF_RECLAIM)) ? df::world_site::find(df::global::ui->site_id) : NULL); ((type == df::enums::game_type::DWARF_MAIN) || (type == df::enums::game_type::DWARF_RECLAIM)) ? df::world_site::find(df::global::ui->site_id) : NULL);
if ( out_items.size() != 1 ) if ( out_items.size() != 1 )
return -1; return -1;
for (size_t a = 0; a < out_items.size(); a++ ) { for (size_t a = 0; a < out_items.size(); a++ ) {
out_items[a]->moveToGround(unit->pos.x, unit->pos.y, unit->pos.z); out_items[a]->moveToGround(unit->pos.x, unit->pos.y, unit->pos.z);
} }
return out_items[0]->id; return out_items[0]->id;
} }

@ -204,7 +204,7 @@ df::map_block *Maps::ensureTileBlock (int32_t x, int32_t y, int32_t z)
slot->temperature_1[tx][ty] = column[z2]->temperature_1[tx][ty]; slot->temperature_1[tx][ty] = column[z2]->temperature_1[tx][ty];
slot->temperature_2[tx][ty] = column[z2]->temperature_2[tx][ty]; slot->temperature_2[tx][ty] = column[z2]->temperature_2[tx][ty];
} }
df::global::world->map.map_blocks.push_back(slot); df::global::world->map.map_blocks.push_back(slot);
return slot; return slot;
} }
@ -593,7 +593,7 @@ bool Maps::canStepBetween(df::coord pos1, df::coord pos2)
if ( !index_tile<uint16_t>(block1->walkable,pos1) || !index_tile<uint16_t>(block2->walkable,pos2) ) { if ( !index_tile<uint16_t>(block1->walkable,pos1) || !index_tile<uint16_t>(block2->walkable,pos2) ) {
return false; return false;
} }
if ( block1->designation[pos1.x&0xF][pos1.y&0xF].bits.flow_size >= 4 || if ( block1->designation[pos1.x&0xF][pos1.y&0xF].bits.flow_size >= 4 ||
block2->designation[pos2.x&0xF][pos2.y&0xF].bits.flow_size >= 4 ) block2->designation[pos2.x&0xF][pos2.y&0xF].bits.flow_size >= 4 )
return false; return false;
@ -640,7 +640,7 @@ bool Maps::canStepBetween(df::coord pos1, df::coord pos2)
} }
if ( !foundWall ) if ( !foundWall )
return false; //unusable ramp return false; //unusable ramp
//there has to be an unforbidden hatch above the ramp //there has to be an unforbidden hatch above the ramp
if ( index_tile<df::tile_occupancy>(block2->occupancy,pos2).bits.building != tile_building_occ::Dynamic ) if ( index_tile<df::tile_occupancy>(block2->occupancy,pos2).bits.building != tile_building_occ::Dynamic )
return false; return false;
@ -657,7 +657,7 @@ bool Maps::canStepBetween(df::coord pos1, df::coord pos2)
} }
return false; return false;
} }
//diagonal up: has to be a ramp //diagonal up: has to be a ramp
if ( shape1 == tiletype_shape::RAMP /*&& shape2 == tiletype_shape::RAMP*/ ) { if ( shape1 == tiletype_shape::RAMP /*&& shape2 == tiletype_shape::RAMP*/ ) {
df::coord up = df::coord(pos1.x,pos1.y,pos1.z+1); df::coord up = df::coord(pos1.x,pos1.y,pos1.z+1);
@ -681,11 +681,11 @@ bool Maps::canStepBetween(df::coord pos1, df::coord pos2)
df::tiletype_shape shapeUp = ENUM_ATTR(tiletype,shape,*typeUp); df::tiletype_shape shapeUp = ENUM_ATTR(tiletype,shape,*typeUp);
if ( shapeUp != tiletype_shape::RAMP_TOP ) if ( shapeUp != tiletype_shape::RAMP_TOP )
return false; return false;
df::map_block* blockUp = getTileBlock(up); df::map_block* blockUp = getTileBlock(up);
if ( !blockUp ) if ( !blockUp )
return false; return false;
df::tile_building_occ occupancy = index_tile<df::tile_occupancy>(blockUp->occupancy,up).bits.building; df::tile_building_occ occupancy = index_tile<df::tile_occupancy>(blockUp->occupancy,up).bits.building;
if ( occupancy == tile_building_occ::Obstacle || occupancy == tile_building_occ::Floored || occupancy == tile_building_occ::Impassable ) if ( occupancy == tile_building_occ::Obstacle || occupancy == tile_building_occ::Floored || occupancy == tile_building_occ::Impassable )
return false; return false;

@ -1616,12 +1616,12 @@ std::string Units::getCasteProfessionName(int race, int casteid, df::profession
{ {
std::string prof, race_prefix; std::string prof, race_prefix;
if (pid < (df::profession)0 || !is_valid_enum_item(pid)) if (pid < (df::profession)0 || !is_valid_enum_item(pid))
return ""; return "";
int16_t current_race = df::global::ui->race_id; int16_t current_race = df::global::ui->race_id;
if (df::global::gamemode && *df::global::gamemode == df::game_mode::ADVENTURE) if (df::global::gamemode && *df::global::gamemode == df::game_mode::ADVENTURE)
current_race = world->units.active[0]->race; current_race = world->units.active[0]->race;
bool use_race_prefix = (race >= 0 && race != current_race); bool use_race_prefix = (race >= 0 && race != current_race);
if (auto creature = df::creature_raw::find(race)) if (auto creature = df::creature_raw::find(race))
{ {

@ -25,7 +25,7 @@ DFHACK_PLUGIN("dfusion")
static int loadObjectFile(lua_State* L) static int loadObjectFile(lua_State* L)
{ {
std::string path; std::string path;
path=luaL_checkstring(L,1); path=luaL_checkstring(L,1);
OutFile::File f(path); OutFile::File f(path);
@ -36,7 +36,7 @@ static int loadObjectFile(lua_State* L)
lua_setfield(L,table_pos,"data_size"); lua_setfield(L,table_pos,"data_size");
char* buf=new char[size]; char* buf=new char[size];
f.GetText(buf); f.GetText(buf);
//Lua::PushDFObject(L,DFHack::,buf); //Lua::PushDFObject(L,DFHack::,buf);
//Lua::Push(L,buf); //Lua::Push(L,buf);
lua_pushlightuserdata(L,buf); lua_pushlightuserdata(L,buf);
@ -52,7 +52,7 @@ static int loadObjectFile(lua_State* L)
Lua::Push(L,symbols[i].pos); Lua::Push(L,symbols[i].pos);
lua_setfield(L,-2,"pos"); lua_setfield(L,-2,"pos");
lua_settable(L,-3); lua_settable(L,-3);
} }
lua_setfield(L,table_pos,"symbols"); lua_setfield(L,table_pos,"symbols");

@ -9,29 +9,29 @@
class Hexsearch class Hexsearch
{ {
public: public:
typedef std::vector<int> SearchArgType; typedef std::vector<int> SearchArgType;
enum SearchConst //TODO add more enum SearchConst //TODO add more
{ {
ANYBYTE=0x101,DWORD_,ANYDWORD,ADDRESS ANYBYTE=0x101,DWORD_,ANYDWORD,ADDRESS
}; };
Hexsearch(const SearchArgType &args,char * startpos,char * endpos); Hexsearch(const SearchArgType &args,char * startpos,char * endpos);
~Hexsearch(); ~Hexsearch();
void Reset(){pos_=startpos_;}; void Reset(){pos_=startpos_;};
void SetStart(char * pos){pos_=pos;}; void SetStart(char * pos){pos_=pos;};
void * FindNext();
std::vector<void *> FindAll();
void * FindNext();
std::vector<void *> FindAll();
private: private:
bool Compare(int a,int b); bool Compare(int a,int b);
void ReparseArgs(); void ReparseArgs();
SearchArgType args_; SearchArgType args_;
char * pos_,* startpos_,* endpos_; char * pos_,* startpos_,* endpos_;
std::vector<int> BadCharShifts,GoodSuffixShift; std::vector<int> BadCharShifts,GoodSuffixShift;
void PrepareGoodSuffixTable(); void PrepareGoodSuffixTable();
void PrepareBadCharShift(); void PrepareBadCharShift();
}; };
#endif #endif

@ -11,19 +11,19 @@ namespace lua
class Hexsearch class Hexsearch
{ {
int tblid; int tblid;
::Hexsearch *p; ::Hexsearch *p;
public: public:
Hexsearch(lua_State *L,int id); Hexsearch(lua_State *L,int id);
~Hexsearch(); ~Hexsearch();
int GetTableId(){return tblid;}; int GetTableId(){return tblid;};
int find(lua_State *L); int find(lua_State *L);
int findall(lua_State *L); int findall(lua_State *L);
int reset(lua_State *L); int reset(lua_State *L);
DEF_LUNE(Hexsearch); DEF_LUNE(Hexsearch);
}; };
void RegisterHexsearch(lua::state &st); void RegisterHexsearch(lua::state &st);

@ -18,25 +18,25 @@ class PlugManager
{ {
public: public:
mapPlugs GetList(){return plugs;}; mapPlugs GetList(){return plugs;};
uint32_t AddNewPlug(std::string name,uint32_t size,uint32_t loc=0); uint32_t AddNewPlug(std::string name,uint32_t size,uint32_t loc=0);
uint32_t FindPlugin(std::string name); uint32_t FindPlugin(std::string name);
static PlugManager &GetInst() static PlugManager &GetInst()
{ {
void *p; void *p;
p=DFHack::Core::getInstance().GetData("dfusion_manager"); p=DFHack::Core::getInstance().GetData("dfusion_manager");
if(p==0) if(p==0)
{ {
p=new PlugManager; p=new PlugManager;
DFHack::Core::getInstance().RegisterData(p,"dfusion_manager"); DFHack::Core::getInstance().RegisterData(p,"dfusion_manager");
} }
return *static_cast<PlugManager*>(p); return *static_cast<PlugManager*>(p);
}; };
protected: protected:
private: private:
PlugManager(){}; PlugManager(){};
mapPlugs plugs; mapPlugs plugs;
}; };
void RegisterMisc(lua::state &st); void RegisterMisc(lua::state &st);

@ -16,7 +16,7 @@ using std::string;
namespace lua namespace lua
{ {
//global lua state singleton //global lua state singleton
class glua class glua
{ {
public: public:
@ -26,13 +26,13 @@ namespace lua
static glua *ptr; static glua *ptr;
state mystate; state mystate;
}; };
//registers basic lua commands //registers basic lua commands
void RegBasics(lua::state &L); void RegBasics(lua::state &L);
//dumps lua function trace, useless unless called from lua. //dumps lua function trace, useless unless called from lua.
string DebugDump(lua::state &L); string DebugDump(lua::state &L);
//register functions, first registers into global scope, second into current table //register functions, first registers into global scope, second into current table
void RegFunctions(lua::state &L,luaL_Reg const *arr); void RegFunctions(lua::state &L,luaL_Reg const *arr);
void RegFunctionsLocal(lua::state &L,luaL_Reg const *arr); void RegFunctionsLocal(lua::state &L,luaL_Reg const *arr);
} }

@ -5,7 +5,7 @@ File::File(std::string path)
{ {
//mystream.exceptions ( std::fstream::eofbit | std::fstream::failbit | std::fstream::badbit ); //mystream.exceptions ( std::fstream::eofbit | std::fstream::failbit | std::fstream::badbit );
mystream.open(path.c_str(),std::fstream::binary|std::ios::in|std::ios::out); mystream.open(path.c_str(),std::fstream::binary|std::ios::in|std::ios::out);
if(mystream) if(mystream)
{ {

@ -3,7 +3,7 @@
Hexsearch::Hexsearch(const SearchArgType &args,char * startpos,char * endpos):args_(args),pos_(startpos),startpos_(startpos),endpos_(endpos) Hexsearch::Hexsearch(const SearchArgType &args,char * startpos,char * endpos):args_(args),pos_(startpos),startpos_(startpos),endpos_(endpos)
{ {
ReparseArgs(); ReparseArgs();
} }
Hexsearch::~Hexsearch() Hexsearch::~Hexsearch()
{ {
@ -11,106 +11,106 @@ Hexsearch::~Hexsearch()
} }
inline bool Hexsearch::Compare(int a,int b) inline bool Hexsearch::Compare(int a,int b)
{ {
if(b==Hexsearch::ANYBYTE) if(b==Hexsearch::ANYBYTE)
return true; return true;
if(a==b) if(a==b)
return true; return true;
return false; return false;
} }
void Hexsearch::ReparseArgs() void Hexsearch::ReparseArgs()
{ {
union union
{ {
uint32_t val; uint32_t val;
uint8_t bytes[4]; uint8_t bytes[4];
}B; }B;
SearchArgType targ; SearchArgType targ;
targ=args_; targ=args_;
args_.clear(); args_.clear();
for(size_t i=0;i<targ.size();) for(size_t i=0;i<targ.size();)
{ {
if(targ[i]==DWORD_) if(targ[i]==DWORD_)
{ {
i++; i++;
B.val=targ[i]; B.val=targ[i];
for(int j=0;j<4;j++) for(int j=0;j<4;j++)
{ {
args_.push_back(B.bytes[j]); args_.push_back(B.bytes[j]);
} }
i++; i++;
} }
else if (targ[i]==ANYDWORD) else if (targ[i]==ANYDWORD)
{ {
i++; i++;
for(int j=0;j<4;j++) for(int j=0;j<4;j++)
args_.push_back(ANYBYTE); args_.push_back(ANYBYTE);
} }
else else
{ {
args_.push_back(targ[i]); args_.push_back(targ[i]);
i++; i++;
} }
} }
} }
void * Hexsearch::FindNext() //TODO rewrite using Boyer-Moore algorithm void * Hexsearch::FindNext() //TODO rewrite using Boyer-Moore algorithm
{ {
DFHack::Core &inst=DFHack::Core::getInstance(); DFHack::Core &inst=DFHack::Core::getInstance();
DFHack::Process *p=inst.p; DFHack::Process *p=inst.p;
uint8_t *buf; uint8_t *buf;
buf=new uint8_t[args_.size()]; buf=new uint8_t[args_.size()];
while(pos_<endpos_) while(pos_<endpos_)
{ {
bool found=true; bool found=true;
p->readByte(pos_,buf[0]); p->readByte(pos_,buf[0]);
if(Compare(buf[0],args_[0])) if(Compare(buf[0],args_[0]))
{ {
p->read(pos_,args_.size(),buf); p->read(pos_,args_.size(),buf);
for(size_t i=0;i<args_.size();i++) for(size_t i=0;i<args_.size();i++)
{ {
if(!Compare(buf[i],args_[i])) if(!Compare(buf[i],args_[i]))
{ {
pos_+=i; pos_+=i;
found=false; found=false;
break; break;
} }
} }
if(found) if(found)
{ {
pos_+=args_.size(); pos_+=args_.size();
delete [] buf; delete [] buf;
return pos_-args_.size(); return pos_-args_.size();
} }
} }
pos_ = pos_ + 1; pos_ = pos_ + 1;
} }
delete [] buf; delete [] buf;
return 0; return 0;
} }
std::vector<void *> Hexsearch::FindAll() std::vector<void *> Hexsearch::FindAll()
{ {
std::vector<void *> ret; std::vector<void *> ret;
void * cpos=pos_; void * cpos=pos_;
while(cpos!=0) while(cpos!=0)
{ {
cpos=FindNext(); cpos=FindNext();
if(cpos!=0) if(cpos!=0)
ret.push_back(cpos); ret.push_back(cpos);
} }
return ret; return ret;
} }
void Hexsearch::PrepareBadCharShift() void Hexsearch::PrepareBadCharShift()
{ {
BadCharShifts.resize(256,-1); BadCharShifts.resize(256,-1);
int i=0; int i=0;
for(SearchArgType::reverse_iterator it=args_.rbegin();it!=args_.rend();it++) for(SearchArgType::reverse_iterator it=args_.rbegin();it!=args_.rend();it++)
{ {
BadCharShifts[*it]=i; BadCharShifts[*it]=i;
i++; i++;
} }
} }
void Hexsearch::PrepareGoodSuffixTable() void Hexsearch::PrepareGoodSuffixTable()
{ {
GoodSuffixShift.resize(args_.size()+1,0); GoodSuffixShift.resize(args_.size()+1,0);
} }

@ -2,60 +2,60 @@
int lua::Hexsearch::find(lua_State *L) int lua::Hexsearch::find(lua_State *L)
{ {
lua::state st(L); lua::state st(L);
void * pos=p->FindNext(); void * pos=p->FindNext();
st.push(reinterpret_cast<size_t>(pos)); st.push(reinterpret_cast<size_t>(pos));
return 1; return 1;
} }
int lua::Hexsearch::findall(lua_State *L) int lua::Hexsearch::findall(lua_State *L)
{ {
lua::state st(L); lua::state st(L);
std::vector<void *> pos=p->FindAll(); std::vector<void *> pos=p->FindAll();
st.newtable(); st.newtable();
for(unsigned i=0;i<pos.size();i++) for(unsigned i=0;i<pos.size();i++)
{ {
st.push(i+1); st.push(i+1);
st.push(reinterpret_cast<size_t>(pos[i])); st.push(reinterpret_cast<size_t>(pos[i]));
st.settable(); st.settable();
} }
return 1; return 1;
} }
lua::Hexsearch::Hexsearch(lua_State *L,int id):tblid(id) lua::Hexsearch::Hexsearch(lua_State *L,int id):tblid(id)
{ {
lua::state st(L); lua::state st(L);
char * start,* end; char * start,* end;
::Hexsearch::SearchArgType args; ::Hexsearch::SearchArgType args;
start= (char *)st.as<uint32_t>(1); start= (char *)st.as<uint32_t>(1);
end=(char *)st.as<uint32_t>(2); end=(char *)st.as<uint32_t>(2);
for(int i=3;i<=st.gettop();i++) for(int i=3;i<=st.gettop();i++)
{ {
args.push_back(st.as<int>(i)); args.push_back(st.as<int>(i));
} }
p=new ::Hexsearch(args,start,end); p=new ::Hexsearch(args,start,end);
} }
lua::Hexsearch::~Hexsearch() lua::Hexsearch::~Hexsearch()
{ {
delete p; delete p;
} }
int lua::Hexsearch::reset(lua_State *L) int lua::Hexsearch::reset(lua_State *L)
{ {
lua::state st(L); lua::state st(L);
p->Reset(); p->Reset();
return 0; return 0;
} }
IMP_LUNE(lua::Hexsearch,hexsearch); IMP_LUNE(lua::Hexsearch,hexsearch);
LUNE_METHODS_START(lua::Hexsearch) LUNE_METHODS_START(lua::Hexsearch)
method(lua::Hexsearch,find), method(lua::Hexsearch,find),
method(lua::Hexsearch,findall), method(lua::Hexsearch,findall),
method(lua::Hexsearch,reset), method(lua::Hexsearch,reset),
LUNE_METHODS_END(); LUNE_METHODS_END();
#define __ADDCONST(name) st.push(::Hexsearch:: name); st.setglobal(#name) #define __ADDCONST(name) st.push(::Hexsearch:: name); st.setglobal(#name)
void lua::RegisterHexsearch(lua::state &st) void lua::RegisterHexsearch(lua::state &st)
{ {
Lune<lua::Hexsearch>::Register(st); Lune<lua::Hexsearch>::Register(st);
__ADDCONST(ANYBYTE); __ADDCONST(ANYBYTE);
__ADDCONST(ANYDWORD); __ADDCONST(ANYDWORD);
__ADDCONST(DWORD_); __ADDCONST(DWORD_);
} }
#undef __ADDCONST #undef __ADDCONST

@ -1,21 +1,21 @@
#include "lua_Misc.h" #include "lua_Misc.h"
uint32_t lua::PlugManager::AddNewPlug(std::string name,uint32_t size,uint32_t loc) uint32_t lua::PlugManager::AddNewPlug(std::string name,uint32_t size,uint32_t loc)
{ {
void *p; void *p;
if(size!=0) if(size!=0)
p=new unsigned char[size]; p=new unsigned char[size];
else else
p=(void*)loc; p=(void*)loc;
plugs[name]=p; plugs[name]=p;
return (uint32_t)p; return (uint32_t)p;
} }
uint32_t lua::PlugManager::FindPlugin(std::string name) uint32_t lua::PlugManager::FindPlugin(std::string name)
{ {
mapPlugs::iterator it=plugs.find(name); mapPlugs::iterator it=plugs.find(name);
if(it!=plugs.end()) if(it!=plugs.end())
return (uint32_t)it->second; return (uint32_t)it->second;
else else
return 0; return 0;
} }
@ -24,10 +24,10 @@ static int LoadMod(lua_State *L)
lua::state st(L); lua::state st(L);
std::string modfile=st.as<std::string>(1); std::string modfile=st.as<std::string>(1);
std::string modname=st.as<std::string>(2); std::string modname=st.as<std::string>(2);
uint32_t size_add=st.as<uint32_t>(0,3); uint32_t size_add=st.as<uint32_t>(0,3);
OutFile::File f(modfile); OutFile::File f(modfile);
uint32_t size=f.GetTextSize(); uint32_t size=f.GetTextSize();
uint32_t pos=lua::PlugManager::GetInst().AddNewPlug(modname,size+size_add); uint32_t pos=lua::PlugManager::GetInst().AddNewPlug(modname,size+size_add);
char *buf; char *buf;
buf=new char[size]; buf=new char[size];
f.GetText(buf); f.GetText(buf);
@ -133,22 +133,22 @@ static int GetMod(lua_State *L)
const luaL_Reg lua_misc_func[]= const luaL_Reg lua_misc_func[]=
{ {
{"loadmod",LoadMod}, {"loadmod",LoadMod},
{"getmod",GetMod}, {"getmod",GetMod},
{"loadobj",LoadObj}, {"loadobj",LoadObj},
{"loadobjsymbols",LoadObjSymbols}, {"loadobjsymbols",LoadObjSymbols},
{"findmarker",FindMarker}, {"findmarker",FindMarker},
{"newmod",NewMod}, {"newmod",NewMod},
{NULL,NULL} {NULL,NULL}
}; };
void lua::RegisterMisc(lua::state &st) void lua::RegisterMisc(lua::state &st)
{ {
st.getglobal("engine"); st.getglobal("engine");
if(st.is<lua::nil>()) if(st.is<lua::nil>())
{ {
st.pop(); st.pop();
st.newtable(); st.newtable();
} }
lua::RegFunctionsLocal(st, lua_misc_func); lua::RegFunctionsLocal(st, lua_misc_func);
st.setglobal("engine"); st.setglobal("engine");
} }

@ -2,268 +2,268 @@
static DFHack::Process* GetProcessPtr(lua::state &st) static DFHack::Process* GetProcessPtr(lua::state &st)
{ {
return DFHack::Core::getInstance().p; return DFHack::Core::getInstance().p;
} }
static int lua_Process_readDWord(lua_State *S) static int lua_Process_readDWord(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
uint32_t ret=c->readDWord( (void *) st.as<uint32_t>(1)); uint32_t ret=c->readDWord( (void *) st.as<uint32_t>(1));
st.push(ret); st.push(ret);
return 1; return 1;
} }
static int lua_Process_writeDWord(lua_State *S) static int lua_Process_writeDWord(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
c->writeDWord((void *) st.as<uint32_t>(1),st.as<uint32_t>(2)); c->writeDWord((void *) st.as<uint32_t>(1),st.as<uint32_t>(2));
return 0; return 0;
} }
static int lua_Process_readFloat(lua_State *S) static int lua_Process_readFloat(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
float ret=c->readFloat((void *) st.as<uint32_t>(1)); float ret=c->readFloat((void *) st.as<uint32_t>(1));
st.push(ret); st.push(ret);
return 1; return 1;
} }
static int lua_Process_readWord(lua_State *S) static int lua_Process_readWord(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
uint16_t ret=c->readWord((void *) st.as<uint32_t>(1)); uint16_t ret=c->readWord((void *) st.as<uint32_t>(1));
st.push(ret); st.push(ret);
return 1; return 1;
} }
static int lua_Process_writeWord(lua_State *S) static int lua_Process_writeWord(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
c->writeWord((void *) st.as<uint32_t>(1),st.as<uint16_t>(2)); c->writeWord((void *) st.as<uint32_t>(1),st.as<uint16_t>(2));
return 0; return 0;
} }
static int lua_Process_readByte(lua_State *S) static int lua_Process_readByte(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
uint8_t ret=c->readByte((void *) st.as<uint32_t>(1)); uint8_t ret=c->readByte((void *) st.as<uint32_t>(1));
st.push(ret); st.push(ret);
return 1; return 1;
} }
static int lua_Process_writeByte(lua_State *S) static int lua_Process_writeByte(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
c->writeByte((void *) st.as<uint32_t>(1),st.as<uint8_t>(2)); c->writeByte((void *) st.as<uint32_t>(1),st.as<uint8_t>(2));
return 0; return 0;
} }
static int lua_Process_read(lua_State *S) static int lua_Process_read(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
size_t len=st.as<uint32_t>(2); size_t len=st.as<uint32_t>(2);
uint8_t* buf; uint8_t* buf;
if(!st.is<lua::nil>(3)) if(!st.is<lua::nil>(3))
buf=(uint8_t*)lua_touserdata(st,3); buf=(uint8_t*)lua_touserdata(st,3);
else else
buf=new uint8_t[len]; buf=new uint8_t[len];
c->read((void *) st.as<uint32_t>(1),len,buf); c->read((void *) st.as<uint32_t>(1),len,buf);
st.pushlightuserdata(buf); st.pushlightuserdata(buf);
return 1; return 1;
} }
static int lua_Process_write(lua_State *S) static int lua_Process_write(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
c-> write((void *) st.as<uint32_t>(1),st.as<uint32_t>(2),static_cast<uint8_t*>(lua_touserdata(st,3))); c-> write((void *) st.as<uint32_t>(1),st.as<uint32_t>(2),static_cast<uint8_t*>(lua_touserdata(st,3)));
return 0; return 0;
} }
static int lua_Process_readSTLString (lua_State *S) static int lua_Process_readSTLString (lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
std::string r=c->readSTLString((void *) st.as<uint32_t>(1)); std::string r=c->readSTLString((void *) st.as<uint32_t>(1));
st.push(r); st.push(r);
return 1; return 1;
} }
static int lua_Process_writeSTLString(lua_State *S) static int lua_Process_writeSTLString(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
c->writeSTLString((void *) st.as<uint32_t>(1),st.as<std::string>(2)); c->writeSTLString((void *) st.as<uint32_t>(1),st.as<std::string>(2));
return 0; return 0;
} }
static int lua_Process_copySTLString(lua_State *S) static int lua_Process_copySTLString(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
c->copySTLString((void *) st.as<uint32_t>(1),st.as<uint32_t>(2)); c->copySTLString((void *) st.as<uint32_t>(1),st.as<uint32_t>(2));
return 0; return 0;
} }
static int lua_Process_doReadClassName(lua_State *S) static int lua_Process_doReadClassName(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
std::string r=c->doReadClassName((void*)st.as<size_t>(1)); std::string r=c->doReadClassName((void*)st.as<size_t>(1));
st.push(r); st.push(r);
return 1; return 1;
} }
static int lua_Process_readClassName(lua_State *S) static int lua_Process_readClassName(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
std::string r=c->readClassName((void*)st.as<size_t>(1)); std::string r=c->readClassName((void*)st.as<size_t>(1));
st.push(r); st.push(r);
return 1; return 1;
} }
static int lua_Process_readCString (lua_State *S) static int lua_Process_readCString (lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
std::string r=c->readCString((void *) st.as<uint32_t>(1)); std::string r=c->readCString((void *) st.as<uint32_t>(1));
st.push(r); st.push(r);
return 1; return 1;
} }
static int lua_Process_isSuspended(lua_State *S) static int lua_Process_isSuspended(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
st.push(c->isSuspended()); st.push(c->isSuspended());
return 1; return 1;
} }
static int lua_Process_isIdentified(lua_State *S) static int lua_Process_isIdentified(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
st.push(c->isIdentified()); st.push(c->isIdentified());
return 1; return 1;
} }
static int lua_Process_getMemRanges(lua_State *S) static int lua_Process_getMemRanges(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
std::vector<DFHack::t_memrange> ranges; std::vector<DFHack::t_memrange> ranges;
c->getMemRanges(ranges); c->getMemRanges(ranges);
st.newtable(); st.newtable();
for(size_t i=0;i<ranges.size();i++) for(size_t i=0;i<ranges.size();i++)
{ {
st.push(i); st.push(i);
st.newtable(); st.newtable();
st.push((uint32_t)ranges[i].start); // WARNING!! lua has only 32bit numbers, possible loss of data!! st.push((uint32_t)ranges[i].start); // WARNING!! lua has only 32bit numbers, possible loss of data!!
st.setfield("start"); st.setfield("start");
st.push((uint32_t)ranges[i].end); st.push((uint32_t)ranges[i].end);
st.setfield("end"); st.setfield("end");
st.push(std::string(ranges[i].name)); st.push(std::string(ranges[i].name));
st.setfield("name"); st.setfield("name");
st.push(ranges[i].read); st.push(ranges[i].read);
st.setfield("read"); st.setfield("read");
st.push(ranges[i].write); st.push(ranges[i].write);
st.setfield("write"); st.setfield("write");
st.push(ranges[i].execute); st.push(ranges[i].execute);
st.setfield("execute"); st.setfield("execute");
st.push(ranges[i].shared); st.push(ranges[i].shared);
st.setfield("shared"); st.setfield("shared");
st.push(ranges[i].valid); st.push(ranges[i].valid);
st.setfield("valid"); st.setfield("valid");
st.settable(); st.settable();
} }
return 1; return 1;
} }
static int lua_Process_getBase(lua_State *S) static int lua_Process_getBase(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
uint32_t base=c->getBase(); uint32_t base=c->getBase();
st.push(base); st.push(base);
return 1; return 1;
} }
/*static int lua_Process_getPID(lua_State *S) /*static int lua_Process_getPID(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
int ret=c->getPID(); int ret=c->getPID();
st.push(ret); st.push(ret);
return 1; return 1;
}*/ }*/
static int lua_Process_getPath(lua_State *S) static int lua_Process_getPath(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
std::string ret=c->getPath(); std::string ret=c->getPath();
st.push(ret); st.push(ret);
return 1; return 1;
} }
static int lua_Process_setPermisions(lua_State *S) static int lua_Process_setPermisions(lua_State *S)
{ {
lua::state st(S); lua::state st(S);
DFHack::Process* c=GetProcessPtr(st); DFHack::Process* c=GetProcessPtr(st);
DFHack::t_memrange range,trange; DFHack::t_memrange range,trange;
st.getfield("start",1); st.getfield("start",1);
range.start= (void *)st.as<uint64_t>(); range.start= (void *)st.as<uint64_t>();
st.pop(); st.pop();
st.getfield("end",1); st.getfield("end",1);
range.end= (void *)st.as<uint64_t>(); range.end= (void *)st.as<uint64_t>();
st.pop(); st.pop();
st.getfield("read",2); st.getfield("read",2);
trange.read=st.as<bool>(); trange.read=st.as<bool>();
st.pop(); st.pop();
st.getfield("write",2); st.getfield("write",2);
trange.write=st.as<bool>(); trange.write=st.as<bool>();
st.pop(); st.pop();
st.getfield("execute",2); st.getfield("execute",2);
trange.execute=st.as<bool>(); trange.execute=st.as<bool>();
st.pop(); st.pop();
c->setPermisions(range,trange); c->setPermisions(range,trange);
return 0; return 0;
} }
#define PROC_FUNC(name) {#name,lua_Process_ ## name} #define PROC_FUNC(name) {#name,lua_Process_ ## name}
const luaL_Reg lua_process_func[]= const luaL_Reg lua_process_func[]=
{ {
PROC_FUNC(readDWord), PROC_FUNC(readDWord),
PROC_FUNC(writeDWord), PROC_FUNC(writeDWord),
PROC_FUNC(readFloat), PROC_FUNC(readFloat),
PROC_FUNC(readWord), PROC_FUNC(readWord),
PROC_FUNC(writeWord), PROC_FUNC(writeWord),
PROC_FUNC(readByte), PROC_FUNC(readByte),
PROC_FUNC(writeByte), PROC_FUNC(writeByte),
PROC_FUNC(read), PROC_FUNC(read),
PROC_FUNC(write), PROC_FUNC(write),
PROC_FUNC(readSTLString), PROC_FUNC(readSTLString),
PROC_FUNC(writeSTLString), PROC_FUNC(writeSTLString),
PROC_FUNC(copySTLString), PROC_FUNC(copySTLString),
PROC_FUNC(doReadClassName), PROC_FUNC(doReadClassName),
PROC_FUNC(readClassName), PROC_FUNC(readClassName),
PROC_FUNC(readCString ), PROC_FUNC(readCString ),
PROC_FUNC(isSuspended), PROC_FUNC(isSuspended),
PROC_FUNC(isIdentified), PROC_FUNC(isIdentified),
PROC_FUNC(getMemRanges), PROC_FUNC(getMemRanges),
PROC_FUNC(getBase), PROC_FUNC(getBase),
//PROC_FUNC(getPID), //not implemented //PROC_FUNC(getPID), //not implemented
PROC_FUNC(getPath), PROC_FUNC(getPath),
PROC_FUNC(setPermisions), PROC_FUNC(setPermisions),
{NULL,NULL} {NULL,NULL}
}; };
#undef PROC_FUNC #undef PROC_FUNC
void lua::RegisterProcess(lua::state &st) void lua::RegisterProcess(lua::state &st)
{ {
st.getglobal("Process"); st.getglobal("Process");
if(st.is<lua::nil>()) if(st.is<lua::nil>())
{ {
st.pop(); st.pop();
st.newtable(); st.newtable();
} }
lua::RegFunctionsLocal(st, lua_process_func); lua::RegFunctionsLocal(st, lua_process_func);
st.setglobal("Process"); st.setglobal("Process");
} }

@ -1,4 +1,4 @@
// automatically chop trees // automatically chop trees
#include "uicommon.h" #include "uicommon.h"
@ -549,7 +549,7 @@ public:
} }
std::string getFocusString() { return "autochop"; } std::string getFocusString() { return "autochop"; }
void updateAutochopBurrows() void updateAutochopBurrows()
{ {
watchedBurrows.clear(); watchedBurrows.clear();
@ -586,7 +586,7 @@ struct autochop_hook : public df::viewscreen_dwarfmodest
using namespace df::enums::ui_sidebar_mode; using namespace df::enums::ui_sidebar_mode;
return (ui->main.mode == DesignateChopTrees); return (ui->main.mode == DesignateChopTrees);
} }
void sendKey(const df::interface_key &key) void sendKey(const df::interface_key &key)
{ {
set<df::interface_key> tmp; set<df::interface_key> tmp;

@ -220,7 +220,7 @@ struct dump_hook : public df::viewscreen_dwarfmodest
links += sp->links.give_to_workshop.size(); links += sp->links.give_to_workshop.size();
links += sp->links.take_from_workshop.size(); links += sp->links.take_from_workshop.size();
bool state = monitor.isMonitored(sp); bool state = monitor.isMonitored(sp);
if (links + 12 >= y) { if (links + 12 >= y) {
y = dims.y2; y = dims.y2;
OutputString(COLOR_WHITE, x, y, "Auto: "); OutputString(COLOR_WHITE, x, y, "Auto: ");

@ -59,8 +59,8 @@ struct MaterialDescriptor
bool matches(const MaterialDescriptor &a) const bool matches(const MaterialDescriptor &a) const
{ {
return a.valid && valid && return a.valid && valid &&
a.type == type && a.type == type &&
a.index == index && a.index == index &&
a.item_type == item_type && a.item_type == item_type &&
a.item_subtype == item_subtype; a.item_subtype == item_subtype;
@ -141,15 +141,15 @@ static bool allow_future_placement = false;
static inline bool in_material_choice_stage() static inline bool in_material_choice_stage()
{ {
return Gui::build_selector_hotkey(Core::getTopViewscreen()) && return Gui::build_selector_hotkey(Core::getTopViewscreen()) &&
ui_build_selector->building_type == df::building_type::Construction && ui_build_selector->building_type == df::building_type::Construction &&
ui->main.mode == ui_sidebar_mode::Build && ui->main.mode == ui_sidebar_mode::Build &&
ui_build_selector->stage == 2; ui_build_selector->stage == 2;
} }
static inline bool in_placement_stage() static inline bool in_placement_stage()
{ {
return Gui::dwarfmode_hotkey(Core::getTopViewscreen()) && return Gui::dwarfmode_hotkey(Core::getTopViewscreen()) &&
ui->main.mode == ui_sidebar_mode::Build && ui->main.mode == ui_sidebar_mode::Build &&
ui_build_selector && ui_build_selector &&
ui_build_selector->building_type == df::building_type::Construction && ui_build_selector->building_type == df::building_type::Construction &&
@ -158,7 +158,7 @@ static inline bool in_placement_stage()
static inline bool in_type_choice_stage() static inline bool in_type_choice_stage()
{ {
return Gui::dwarfmode_hotkey(Core::getTopViewscreen()) && return Gui::dwarfmode_hotkey(Core::getTopViewscreen()) &&
ui->main.mode == ui_sidebar_mode::Build && ui->main.mode == ui_sidebar_mode::Build &&
ui_build_selector && ui_build_selector &&
ui_build_selector->building_type < 0; ui_build_selector->building_type < 0;
@ -269,7 +269,7 @@ static bool check_autoselect(MaterialDescriptor &material, bool toggle)
size_t idx; size_t idx;
if (is_material_in_autoselect(idx, material)) if (is_material_in_autoselect(idx, material))
{ {
if (toggle) if (toggle)
vector_erase_at(get_curr_constr_prefs(), idx); vector_erase_at(get_curr_constr_prefs(), idx);
return true; return true;
@ -440,7 +440,7 @@ static bool is_valid_building_site(building_site &site, bool orthogonal_check, b
} }
else if (orthogonal_check) else if (orthogonal_check)
{ {
if (shape != tiletype_shape::RAMP && if (shape != tiletype_shape::RAMP &&
shape_basic != tiletype_shape_basic::Floor && shape_basic != tiletype_shape_basic::Floor &&
shape_basic != tiletype_shape_basic::Stair) shape_basic != tiletype_shape_basic::Stair)
return false; return false;
@ -945,7 +945,7 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest
{ {
// First valid site is guaranteed to be anchored, either on a tile or against a valid orthogonal tile // First valid site is guaranteed to be anchored, either on a tile or against a valid orthogonal tile
// Use it as an anchor point to generate materials list // Use it as an anchor point to generate materials list
anchor = valid_building_sites.front(); anchor = valid_building_sites.front();
valid_building_sites.pop_front(); valid_building_sites.pop_front();
valid_building_sites.push_back(anchor); valid_building_sites.push_back(anchor);
} }
@ -1057,8 +1057,8 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest
int16_t last_used_constr_subtype = (in_material_choice_stage()) ? ui_build_selector->building_subtype : -1; int16_t last_used_constr_subtype = (in_material_choice_stage()) ? ui_build_selector->building_subtype : -1;
INTERPOSE_NEXT(feed)(input); INTERPOSE_NEXT(feed)(input);
if (revert_to_last_used_type && if (revert_to_last_used_type &&
last_used_constr_subtype >= 0 && last_used_constr_subtype >= 0 &&
in_type_choice_stage() && in_type_choice_stage() &&
hotkeys.find(last_used_constr_subtype) != hotkeys.end()) hotkeys.find(last_used_constr_subtype) != hotkeys.end())
{ {

@ -226,7 +226,7 @@ struct melt_hook : public df::viewscreen_dwarfmodest
int left_margin = dims.menu_x1 + 1; int left_margin = dims.menu_x1 + 1;
int x = left_margin; int x = left_margin;
int y = dims.y2 - 6; int y = dims.y2 - 6;
int links = 0; int links = 0;
links += sp->links.give_to_pile.size(); links += sp->links.give_to_pile.size();
links += sp->links.take_from_pile.size(); links += sp->links.take_from_pile.size();

@ -142,7 +142,7 @@ static bool check_mandates(df::item *item)
if (mandate->mode != 0) if (mandate->mode != 0)
continue; continue;
if (item->getType() != mandate->item_type || if (item->getType() != mandate->item_type ||
(mandate->item_subtype != -1 && item->getSubtype() != mandate->item_subtype)) (mandate->item_subtype != -1 && item->getSubtype() != mandate->item_subtype))
continue; continue;
@ -421,14 +421,14 @@ struct trade_hook : public df::viewscreen_dwarfmodest
int left_margin = dims.menu_x1 + 1; int left_margin = dims.menu_x1 + 1;
int x = left_margin; int x = left_margin;
int y = dims.y2 - 5; int y = dims.y2 - 5;
int links = 0; int links = 0;
links += sp->links.give_to_pile.size(); links += sp->links.give_to_pile.size();
links += sp->links.take_from_pile.size(); links += sp->links.take_from_pile.size();
links += sp->links.give_to_workshop.size(); links += sp->links.give_to_workshop.size();
links += sp->links.take_from_workshop.size(); links += sp->links.take_from_workshop.size();
bool state = monitor.isMonitored(sp); bool state = monitor.isMonitored(sp);
if (links + 12 >= y) { if (links + 12 >= y) {
y = dims.y2; y = dims.y2;
OutputString(COLOR_WHITE, x, y, "Auto: "); OutputString(COLOR_WHITE, x, y, "Auto: ");

@ -72,12 +72,12 @@ pair<uint32_t, uint32_t> get_building_size(df::building* b)
char get_tile_dig(MapExtras::MapCache mc, int32_t x, int32_t y, int32_t z) char get_tile_dig(MapExtras::MapCache mc, int32_t x, int32_t y, int32_t z)
{ {
df::tiletype tt = mc.tiletypeAt(DFCoord(x, y, z)); df::tiletype tt = mc.tiletypeAt(DFCoord(x, y, z));
df::tiletype_shape ts = tileShape(tt); df::tiletype_shape ts = tileShape(tt);
switch (ts) switch (ts)
{ {
case tiletype_shape::EMPTY: case tiletype_shape::EMPTY:
case tiletype_shape::RAMP_TOP: case tiletype_shape::RAMP_TOP:
return 'h'; return 'h';
case tiletype_shape::FLOOR: case tiletype_shape::FLOOR:
case tiletype_shape::BOULDER: case tiletype_shape::BOULDER:
@ -102,7 +102,7 @@ char get_tile_dig(MapExtras::MapCache mc, int32_t x, int32_t y, int32_t z)
string get_tile_build(uint32_t x, uint32_t y, df::building* b) string get_tile_build(uint32_t x, uint32_t y, df::building* b)
{ {
if (! b) if (! b)
return " "; return " ";
bool at_nw_corner = x == b->x1 && y == b->y1; bool at_nw_corner = x == b->x1 && y == b->y1;
bool at_se_corner = x == b->x2 && y == b->y2; bool at_se_corner = x == b->x2 && y == b->y2;
@ -366,7 +366,7 @@ string get_tile_build(uint32_t x, uint32_t y, df::building* b)
out << "CS"; out << "CS";
if (ts->use_dump) if (ts->use_dump)
{ {
if (ts->dump_x_shift == 0) if (ts->dump_x_shift == 0)
{ {
if (ts->dump_y_shift > 0) if (ts->dump_y_shift > 0)
out << "dd"; out << "dd";
@ -429,7 +429,7 @@ string get_tile_build(uint32_t x, uint32_t y, df::building* b)
case building_type::AxleVertical: case building_type::AxleVertical:
return "Mv"; return "Mv";
case building_type::Rollers: case building_type::Rollers:
if (! at_nw_corner) if (! at_nw_corner)
return "`"; return "`";
out << "Mr"; out << "Mr";
switch (((df::building_rollersst*) b)->direction) switch (((df::building_rollersst*) b)->direction)
@ -440,7 +440,7 @@ string get_tile_build(uint32_t x, uint32_t y, df::building* b)
out << "s"; out << "s";
case screw_pump_direction::FromSouth: case screw_pump_direction::FromSouth:
out << "s"; out << "s";
case screw_pump_direction::FromWest: case screw_pump_direction::FromWest:
out << "s"; out << "s";
} }
out << "(" << size.first << "x" << size.second << ")"; out << "(" << size.first << "x" << size.second << ")";
@ -533,7 +533,7 @@ string get_tile_place(uint32_t x, uint32_t y, df::building* b)
out << "p"; out << "p";
break; break;
case df::stockpile_group_set::mask_armor: case df::stockpile_group_set::mask_armor:
out << "d"; out << "d";
break; break;
default: //multiple stockpile type default: //multiple stockpile type
return "`"; return "`";

@ -332,7 +332,7 @@ static int addBuilding(lua_State* L)
newDefinition.connections.can_connect.push_back(-1);//TODO add this too... newDefinition.connections.can_connect.push_back(-1);//TODO add this too...
newDefinition.connections.tiles.push_back(df::coord(x,y,0)); newDefinition.connections.tiles.push_back(df::coord(x,y,0));
lua_pop(L,1); lua_pop(L,1);
} }
lua_pop(L,1); lua_pop(L,1);

File diff suppressed because it is too large Load Diff

@ -52,8 +52,8 @@ struct MaterialDescriptor
bool matches(const MaterialDescriptor &a) const bool matches(const MaterialDescriptor &a) const
{ {
return a.valid && valid && return a.valid && valid &&
a.type == type && a.type == type &&
a.index == index && a.index == index &&
a.item_type == item_type && a.item_type == item_type &&
a.item_subtype == item_subtype; a.item_subtype == item_subtype;
@ -190,7 +190,7 @@ private:
masks_column.filterDisplay(); masks_column.filterDisplay();
} }
void populateMaterials() void populateMaterials()
{ {
materials_column.clear(); materials_column.clear();
@ -248,7 +248,7 @@ private:
materials_column.sort(); materials_column.sort();
} }
void addMaterialEntry(df::dfhack_material_category &selected_category, void addMaterialEntry(df::dfhack_material_category &selected_category,
MaterialInfo &material, std::string name) MaterialInfo &material, std::string name)
{ {
if (!selected_category.whole || material.matches(selected_category)) if (!selected_category.whole || material.matches(selected_category))
@ -350,7 +350,7 @@ private:
} }
}; };
// START Planning // START Planning
class PlannedBuilding class PlannedBuilding
{ {
public: public:

@ -51,7 +51,7 @@ struct buildingplan_hook : public df::viewscreen_dwarfmodest
bool isInPlannedBuildingQueryMode() bool isInPlannedBuildingQueryMode()
{ {
return (ui->main.mode == df::ui_sidebar_mode::QueryBuilding || return (ui->main.mode == df::ui_sidebar_mode::QueryBuilding ||
ui->main.mode == df::ui_sidebar_mode::BuildingItems) && ui->main.mode == df::ui_sidebar_mode::BuildingItems) &&
planner.getSelectedPlannedBuilding(); planner.getSelectedPlannedBuilding();
} }
@ -91,7 +91,7 @@ struct buildingplan_hook : public df::viewscreen_dwarfmodest
{ {
if (getNoblePositionOfSelectedBuildingOwner().size() > 0) if (getNoblePositionOfSelectedBuildingOwner().size() > 0)
return canReserveRoom(world->selected_building); return canReserveRoom(world->selected_building);
else else
return false; return false;
} }
@ -119,7 +119,7 @@ struct buildingplan_hook : public df::viewscreen_dwarfmodest
{ {
show_help = true; show_help = true;
} }
if (is_planmode_enabled(type)) if (is_planmode_enabled(type))
{ {
if (planner.inQuickFortMode() && planner.in_dummmy_screen) if (planner.inQuickFortMode() && planner.in_dummmy_screen)
@ -184,7 +184,7 @@ struct buildingplan_hook : public df::viewscreen_dwarfmodest
{ {
planner.removeSelectedPlannedBuilding(); // Remove persistent data planner.removeSelectedPlannedBuilding(); // Remove persistent data
} }
} }
else if (isInNobleRoomQueryMode()) else if (isInNobleRoomQueryMode())
{ {
@ -347,7 +347,7 @@ static command_result buildingplan_cmd(color_ostream &out, vector <string> & par
{ {
show_debugging = (toLower(parameters[1]) == "on"); show_debugging = (toLower(parameters[1]) == "on");
out << "Debugging " << ((show_debugging) ? "enabled" : "disabled") << endl; out << "Debugging " << ((show_debugging) ? "enabled" : "disabled") << endl;
} }
} }
return CR_OK; return CR_OK;

@ -92,7 +92,7 @@ command_result catsplosion (color_ostream &out, std::vector <std::string> & para
female_counts[raw->creature_id].size(); //auto initialize the females as well female_counts[raw->creature_id].size(); //auto initialize the females as well
} }
} }
// print (optional) // print (optional)
//if (showcreatures == 1) //if (showcreatures == 1)
{ {

@ -127,7 +127,7 @@ command_result df_changeitem(color_ostream &out, vector <string> & parameters)
for (size_t i = 0; i < parameters.size(); i++) for (size_t i = 0; i < parameters.size(); i++)
{ {
string & p = parameters[i]; string & p = parameters[i];
if (p == "help" || p == "?") if (p == "help" || p == "?")
{ {
out << changeitem_help << endl; out << changeitem_help << endl;
@ -328,7 +328,7 @@ command_result changeitem_execute(
out << " quality: " << describeQuality(item->getQuality()) << endl; out << " quality: " << describeQuality(item->getQuality()) << endl;
//if(item->isImproved()) //if(item->isImproved())
// out << " imp.quality: " << describeQuality(item->getImprovementQuality()) << endl; // out << " imp.quality: " << describeQuality(item->getImprovementQuality()) << endl;
out << " material: " << mat_old.getToken() << endl; out << " material: " << mat_old.getToken() << endl;
return CR_OK; return CR_OK;
} }
@ -350,7 +350,7 @@ command_result changeitem_execute(
// fixme: changing material of cloth items needs more work... // fixme: changing material of cloth items needs more work...
// <_Q> cloth items have a "CLOTH" improvement which tells you about the cloth that was used to make it // <_Q> cloth items have a "CLOTH" improvement which tells you about the cloth that was used to make it
if(force||(mat_old.subtype == mat_new.subtype && mat_old.mode==mat_new.mode)) if(force||(mat_old.subtype == mat_new.subtype && mat_old.mode==mat_new.mode))
{ {
item->setMaterial(mat_new.type); item->setMaterial(mat_new.type);

@ -32,8 +32,8 @@ DFHACK_PLUGIN("changelayer");
REQUIRE_GLOBAL(world); REQUIRE_GLOBAL(world);
REQUIRE_GLOBAL(cursor); REQUIRE_GLOBAL(cursor);
const string changelayer_help = const string changelayer_help =
" Allows to change the material of whole geology layers.\n" " Allows to change the material of whole geology layers.\n"
" Can have impact on all surrounding regions, not only your embark!\n" " Can have impact on all surrounding regions, not only your embark!\n"
" By default changing stone to soil and vice versa is not allowed.\n" " By default changing stone to soil and vice versa is not allowed.\n"
" By default changes only the layer at the cursor position.\n" " By default changes only the layer at the cursor position.\n"
@ -47,7 +47,7 @@ const string changelayer_help =
" all_biomes - Change layer for all biomes on your map.\n" " all_biomes - Change layer for all biomes on your map.\n"
" Result may be undesirable since the same layer\n" " Result may be undesirable since the same layer\n"
" can AND WILL be on different z-levels for different biomes.\n" " can AND WILL be on different z-levels for different biomes.\n"
" Use the tool 'probe' to get an idea how layers and biomes\n" " Use the tool 'probe' to get an idea how layers and biomes\n"
" are distributed on your map.\n" " are distributed on your map.\n"
" all_layers - Change all layers on your map.\n" " all_layers - Change all layers on your map.\n"
" Candy mountain, anyone?\n" " Candy mountain, anyone?\n"
@ -70,7 +70,7 @@ const string changelayer_help =
" changelayer MARBLE allbiomes alllayers\n" " changelayer MARBLE allbiomes alllayers\n"
" Convert all layers of all biomes into marble.\n"; " Convert all layers of all biomes into marble.\n";
const string changelayer_trouble = const string changelayer_trouble =
"Known problems with changelayer:\n\n" "Known problems with changelayer:\n\n"
" Nothing happens, the material stays the old.\n" " Nothing happens, the material stays the old.\n"
" Pause/unpause the game and/or move the cursor a bit. Then retry.\n" " Pause/unpause the game and/or move the cursor a bit. Then retry.\n"
@ -108,7 +108,7 @@ static bool warned = false;
command_result changelayer (color_ostream &out, std::vector <std::string> & parameters) command_result changelayer (color_ostream &out, std::vector <std::string> & parameters)
{ {
CoreSuspender suspend; CoreSuspender suspend;
string material; string material;
bool force = false; bool force = false;
@ -209,13 +209,13 @@ command_result changelayer (color_ostream &out, std::vector <std::string> & para
// there is no Maps::WriteGeology or whatever, and I didn't want to mess with the library and add it // there is no Maps::WriteGeology or whatever, and I didn't want to mess with the library and add it
// so I copied the stuff which reads the geology information and modified it to be able to change it // so I copied the stuff which reads the geology information and modified it to be able to change it
// //
// a more elegant solution would probably look like this: // a more elegant solution would probably look like this:
// 1) modify Maps::ReadGeology to accept and fill one more optional vector // 1) modify Maps::ReadGeology to accept and fill one more optional vector
// where the geolayer ids of the 9 biomes are stored // where the geolayer ids of the 9 biomes are stored
// 2) call ReadGeology here, modify the data in the vectors without having to do all that map stuff // 2) call ReadGeology here, modify the data in the vectors without having to do all that map stuff
// 3) write Maps::WriteGeology, pass the vectors, let it do it's work // 3) write Maps::WriteGeology, pass the vectors, let it do it's work
// Step 1) is optional, but it would make implementing 3) easier. // Step 1) is optional, but it would make implementing 3) easier.
// Otherwise that "check which geo_index is used by biome X" loop would need to be done again. // Otherwise that "check which geo_index is used by biome X" loop would need to be done again.
// no need to touch the same geology more than once // no need to touch the same geology more than once
@ -226,17 +226,17 @@ command_result changelayer (color_ostream &out, std::vector <std::string> & para
// iterate over 8 surrounding regions + local region // iterate over 8 surrounding regions + local region
for (int i = eNorthWest; i < eBiomeCount; i++) for (int i = eNorthWest; i < eBiomeCount; i++)
{ {
if(verbose) if(verbose)
out << "---Biome: " << i; out << "---Biome: " << i;
if(!all_biomes && i!=biome) if(!all_biomes && i!=biome)
{ {
if(verbose) if(verbose)
out << "-skipping" << endl; out << "-skipping" << endl;
continue; continue;
} }
else else
{ {
if(verbose) if(verbose)
out << "-checking" << endl; out << "-checking" << endl;
} }
@ -304,9 +304,9 @@ command_result changelayer (color_ostream &out, std::vector <std::string> & para
if(conversionAllowed(out, mat_new, mat_old, force)) if(conversionAllowed(out, mat_new, mat_old, force))
{ {
if(verbose) if(verbose)
out << "changing geolayer " << j out << "changing geolayer " << j
<< " from " << mat_old.getToken() << " from " << mat_old.getToken()
<< " to " << mat_new.getToken() << " to " << mat_new.getToken()
<< endl; << endl;
geolayers[j]->mat_index = mat_new.index; geolayers[j]->mat_index = mat_new.index;
} }
@ -329,7 +329,7 @@ command_result changelayer (color_ostream &out, std::vector <std::string> & para
} }
out.print("Done.\n"); out.print("Done.\n");
// Give control back to DF. // Give control back to DF.
return CR_OK; return CR_OK;
} }

@ -326,7 +326,7 @@ command_result df_createitem (color_ostream &out, vector <string> & parameters)
out.printerr("The creature you specified has no such caste!\n"); out.printerr("The creature you specified has no such caste!\n");
return CR_FAILURE; return CR_FAILURE;
} }
} }
} }
if (mat_type == -1) if (mat_type == -1)
{ {

@ -127,7 +127,7 @@ void setUnitNickname(df::unit *unit, const std::string &nick)
std::string determineCurse(df::unit * unit) std::string determineCurse(df::unit * unit)
{ {
string cursetype = "unknown"; string cursetype = "unknown";
// ghosts: ghostly, duh // ghosts: ghostly, duh
// as of DF 34.05 and higher vampire ghosts and the like should not be possible // as of DF 34.05 and higher vampire ghosts and the like should not be possible
// if they get reintroduced later it will become necessary to watch 'ghostly' seperately // if they get reintroduced later it will become necessary to watch 'ghostly' seperately
@ -140,17 +140,17 @@ std::string determineCurse(df::unit * unit)
cursetype = "zombie"; cursetype = "zombie";
// necromancers: alive, don't eat, don't drink, don't age // necromancers: alive, don't eat, don't drink, don't age
if(!unit->curse.add_tags1.bits.NOT_LIVING if(!unit->curse.add_tags1.bits.NOT_LIVING
&& unit->curse.add_tags1.bits.NO_EAT && unit->curse.add_tags1.bits.NO_EAT
&& unit->curse.add_tags1.bits.NO_DRINK && unit->curse.add_tags1.bits.NO_DRINK
&& unit->curse.add_tags2.bits.NO_AGING && unit->curse.add_tags2.bits.NO_AGING
) )
cursetype = "necromancer"; cursetype = "necromancer";
// werecreatures: alive, DO eat, DO drink, don't age // werecreatures: alive, DO eat, DO drink, don't age
if(!unit->curse.add_tags1.bits.NOT_LIVING if(!unit->curse.add_tags1.bits.NOT_LIVING
&& !unit->curse.add_tags1.bits.NO_EAT && !unit->curse.add_tags1.bits.NO_EAT
&& !unit->curse.add_tags1.bits.NO_DRINK && !unit->curse.add_tags1.bits.NO_DRINK
&& unit->curse.add_tags2.bits.NO_AGING ) && unit->curse.add_tags2.bits.NO_AGING )
cursetype = "werebeast"; cursetype = "werebeast";
@ -199,7 +199,7 @@ command_result cursecheck (color_ostream &out, vector <string> & parameters)
if(parameters[i] == "verbose") if(parameters[i] == "verbose")
{ {
// verbose makes no sense without enabling details // verbose makes no sense without enabling details
giveDetails = true; giveDetails = true;
verbose = true; verbose = true;
} }
} }
@ -234,7 +234,7 @@ command_result cursecheck (color_ostream &out, vector <string> & parameters)
cursecount++; cursecount++;
string cursetype = determineCurse(unit); string cursetype = determineCurse(unit);
if(giveNick) if(giveNick)
{ {
setUnitNickname(unit, cursetype); //"CURSED"); setUnitNickname(unit, cursetype); //"CURSED");
@ -266,12 +266,12 @@ command_result cursecheck (color_ostream &out, vector <string> & parameters)
{ {
missing = true; missing = true;
} }
out.print("born in %d, cursed in %d to be a %s. (%s%s%s)\n", out.print("born in %d, cursed in %d to be a %s. (%s%s%s)\n",
unit->relations.birth_year, unit->relations.birth_year,
unit->relations.curse_year, unit->relations.curse_year,
cursetype.c_str(), cursetype.c_str(),
// technically most cursed creatures are undead, // technically most cursed creatures are undead,
// therefore output 'active' if they are not completely dead // therefore output 'active' if they are not completely dead
unit->flags1.bits.dead ? "deceased" : "active", unit->flags1.bits.dead ? "deceased" : "active",
unit->flags3.bits.ghostly ? "-ghostly" : "", unit->flags3.bits.ghostly ? "-ghostly" : "",
@ -298,6 +298,6 @@ command_result cursecheck (color_ostream &out, vector <string> & parameters)
out.print("Number of cursed creatures on map: %d \n", cursecount); out.print("Number of cursed creatures on map: %d \n", cursecount);
else else
out.print("Number of cursed creatures on tile: %d \n", cursecount); out.print("Number of cursed creatures on tile: %d \n", cursecount);
return CR_OK; return CR_OK;
} }

File diff suppressed because it is too large Load Diff

@ -91,7 +91,7 @@ command_result writeFlag (color_ostream &out, vector <string> & parameters)
case '7': case '7':
value = parameters[0][0] - '0'; value = parameters[0][0] - '0';
break; break;
default: default:
out.print("Invalid value specified\n"); out.print("Invalid value specified\n");
return CR_FAILURE; return CR_FAILURE;

@ -70,7 +70,7 @@ command_result eventExample(color_ostream& out, vector<string>& parameters) {
} }
} }
*/ */
EventManager::EventHandler initiateHandler(jobInitiated, 1); EventManager::EventHandler initiateHandler(jobInitiated, 1);
EventManager::EventHandler completeHandler(jobCompleted, 0); EventManager::EventHandler completeHandler(jobCompleted, 0);
EventManager::EventHandler timeHandler(timePassed, 1); EventManager::EventHandler timeHandler(timePassed, 1);
@ -82,7 +82,7 @@ command_result eventExample(color_ostream& out, vector<string>& parameters) {
EventManager::EventHandler invasionHandler(invasion, 1000); EventManager::EventHandler invasionHandler(invasion, 1000);
EventManager::EventHandler unitAttackHandler(unitAttack, 1); EventManager::EventHandler unitAttackHandler(unitAttack, 1);
EventManager::unregisterAll(plugin_self); EventManager::unregisterAll(plugin_self);
EventManager::registerListener(EventManager::EventType::JOB_INITIATED, initiateHandler, plugin_self); EventManager::registerListener(EventManager::EventType::JOB_INITIATED, initiateHandler, plugin_self);
EventManager::registerListener(EventManager::EventType::JOB_COMPLETED, completeHandler, plugin_self); EventManager::registerListener(EventManager::EventType::JOB_COMPLETED, completeHandler, plugin_self);
EventManager::registerListener(EventManager::EventType::UNIT_DEATH, deathHandler, plugin_self); EventManager::registerListener(EventManager::EventType::UNIT_DEATH, deathHandler, plugin_self);
@ -105,7 +105,7 @@ command_result eventExample(color_ostream& out, vector<string>& parameters) {
timeHandler.freq = t; timeHandler.freq = t;
EventManager::unregister(EventManager::EventType::TICK, timeHandler, plugin_self); EventManager::unregister(EventManager::EventType::TICK, timeHandler, plugin_self);
EventManager::unregister(EventManager::EventType::TICK, timeHandler, plugin_self); EventManager::unregister(EventManager::EventType::TICK, timeHandler, plugin_self);
out.print("Events registered.\n"); out.print("Events registered.\n");
return CR_OK; return CR_OK;
} }
@ -159,7 +159,7 @@ void construction(color_ostream& out, void* ptr) {
out.print(" construction destroyed\n"); out.print(" construction destroyed\n");
else else
out.print(" construction created\n"); out.print(" construction created\n");
} }
void syndrome(color_ostream& out, void* ptr) { void syndrome(color_ostream& out, void* ptr) {

@ -65,12 +65,12 @@ public:
t_itemflags &f = itm->origin->flags; t_itemflags &f = itm->origin->flags;
return (f.unk1 || f.unk2 || f.unk3 || f.unk4 || return (f.unk1 || f.unk2 || f.unk3 || f.unk4 ||
f.unk6 || f.unk7 || f.unk6 || f.unk7 ||
f.unk10 || f.unk11); f.unk10 || f.unk11);
} }
virtual void postPrint(DFHack::dfh_item *itm) virtual void postPrint(DFHack::dfh_item *itm)
{ {
std::vector<std::string> flags; std::vector<std::string> flags;

@ -1,189 +1,189 @@
#include "Core.h" #include "Core.h"
#include "Console.h" #include "Console.h"
#include "PluginManager.h" #include "PluginManager.h"
#include "MemAccess.h" #include "MemAccess.h"
#include "MiscUtils.h" #include "MiscUtils.h"
#include <tinythread.h> //not sure if correct #include <tinythread.h> //not sure if correct
#include <string> #include <string>
#include <vector> #include <vector>
#include <sstream> #include <sstream>
using std::vector; using std::vector;
using std::string; using std::string;
using namespace DFHack; using namespace DFHack;
uint64_t timeLast=0; uint64_t timeLast=0;
static tthread::mutex* mymutex=0; static tthread::mutex* mymutex=0;
DFHACK_PLUGIN_IS_ENABLED(is_enabled); DFHACK_PLUGIN_IS_ENABLED(is_enabled);
struct memory_data struct memory_data
{ {
void * addr; void * addr;
size_t len; size_t len;
size_t refresh; size_t refresh;
int state; int state;
uint8_t *buf,*lbuf; uint8_t *buf,*lbuf;
vector<t_memrange> ranges; vector<t_memrange> ranges;
}memdata; }memdata;
enum HEXVIEW_STATES enum HEXVIEW_STATES
{ {
STATE_OFF,STATE_ON STATE_OFF,STATE_ON
}; };
command_result memview (color_ostream &out, vector <string> & parameters); command_result memview (color_ostream &out, vector <string> & parameters);
DFHACK_PLUGIN("memview"); DFHACK_PLUGIN("memview");
DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand("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;
mymutex=new tthread::mutex; mymutex=new tthread::mutex;
return CR_OK; return CR_OK;
} }
size_t convert(const std::string& p,bool ishex=false) size_t convert(const std::string& p,bool ishex=false)
{ {
size_t ret; size_t ret;
std::stringstream conv; std::stringstream conv;
if(ishex) if(ishex)
conv<<std::hex; conv<<std::hex;
conv<<p; conv<<p;
conv>>ret; conv>>ret;
return ret; return ret;
} }
bool isAddr(uint32_t *trg,vector<t_memrange> & ranges) bool isAddr(uint32_t *trg,vector<t_memrange> & ranges)
{ {
if(trg[0]%4==0) if(trg[0]%4==0)
for(size_t i=0;i<ranges.size();i++) for(size_t i=0;i<ranges.size();i++)
if(ranges[i].isInRange((void *)trg[0])) if(ranges[i].isInRange((void *)trg[0]))
return true; return true;
return false; return false;
} }
void outputHex(uint8_t *buf,uint8_t *lbuf,size_t len,size_t start,color_ostream &con,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)
{ {
const size_t page_size=16; const size_t page_size=16;
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++)
{ {
if(j%4==0) if(j%4==0)
{ {
con.reset_color(); con.reset_color();
if(isAddr((uint32_t *)(buf+j+i),ranges)) if(isAddr((uint32_t *)(buf+j+i),ranges))
con.color(COLOR_LIGHTRED); //coloring in the middle does not work con.color(COLOR_LIGHTRED); //coloring in the middle does not work
//TODO make something better? //TODO make something better?
} }
if(lbuf[j+i]!=buf[j+i]) if(lbuf[j+i]!=buf[j+i])
con.print("*%02X",buf[j+i]); //if modfied show a star con.print("*%02X",buf[j+i]); //if modfied show a star
else else
con.print(" %02X",buf[j+i]); con.print(" %02X",buf[j+i]);
} }
con.reset_color(); con.reset_color();
con.print(" | "); con.print(" | ");
for(size_t j=0;(j<page_size) && (i+j<len);j++) for(size_t j=0;(j<page_size) && (i+j<len);j++)
if((buf[j+i]>31)&&(buf[j+i]<128)) //only printable ascii if((buf[j+i]>31)&&(buf[j+i]<128)) //only printable ascii
con.print("%c",buf[j+i]); con.print("%c",buf[j+i]);
else else
con.print("."); con.print(".");
//con.print("\n"); //con.print("\n");
} }
con.print("\n"); con.print("\n");
} }
void Deinit() void Deinit()
{ {
if(memdata.state==STATE_ON) if(memdata.state==STATE_ON)
{ {
is_enabled = false; is_enabled = false;
memdata.state=STATE_OFF; memdata.state=STATE_OFF;
delete [] memdata.buf; delete [] memdata.buf;
delete [] memdata.lbuf; delete [] memdata.lbuf;
} }
} }
DFhackCExport command_result plugin_onupdate (color_ostream &out) DFhackCExport command_result plugin_onupdate (color_ostream &out)
{ {
mymutex->lock(); mymutex->lock();
if(memdata.state==STATE_OFF) if(memdata.state==STATE_OFF)
{ {
mymutex->unlock(); mymutex->unlock();
return CR_OK; return CR_OK;
} }
//Console &con=out; //Console &con=out;
uint64_t time2 = GetTimeMs64(); uint64_t time2 = GetTimeMs64();
uint64_t delta = time2-timeLast; uint64_t delta = time2-timeLast;
if(memdata.refresh!=0) if(memdata.refresh!=0)
if(delta<memdata.refresh) if(delta<memdata.refresh)
{ {
mymutex->unlock(); mymutex->unlock();
return CR_OK; return CR_OK;
} }
timeLast = time2; timeLast = time2;
Core::getInstance().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,out,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();
mymutex->unlock(); mymutex->unlock();
return CR_OK; return CR_OK;
} }
command_result memview (color_ostream &out, vector <string> & parameters) command_result memview (color_ostream &out, vector <string> & parameters)
{ {
mymutex->lock(); mymutex->lock();
Core::getInstance().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)
{ {
Deinit(); Deinit();
memdata.state=STATE_OFF; memdata.state=STATE_OFF;
is_enabled = false; is_enabled = false;
mymutex->unlock(); mymutex->unlock();
return CR_OK; return CR_OK;
} }
else else
{ {
Deinit(); Deinit();
bool isValid=false; bool isValid=false;
for(size_t i=0;i<memdata.ranges.size();i++) for(size_t i=0;i<memdata.ranges.size();i++)
if(memdata.ranges[i].isInRange(memdata.addr)) if(memdata.ranges[i].isInRange(memdata.addr))
isValid=true; isValid=true;
if(!isValid) if(!isValid)
{ {
out.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;
} }
is_enabled = true; is_enabled = true;
memdata.state=STATE_ON; memdata.state=STATE_ON;
} }
if(parameters.size()>1) if(parameters.size()>1)
memdata.len=convert(parameters[1]); memdata.len=convert(parameters[1]);
else else
memdata.len=20*16; memdata.len=20*16;
if(parameters.size()>2) if(parameters.size()>2)
memdata.refresh=convert(parameters[2]); memdata.refresh=convert(parameters[2]);
else else
memdata.refresh=0; memdata.refresh=0;
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];
Core::getInstance().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 (color_ostream &out) DFhackCExport command_result plugin_shutdown (color_ostream &out)
{ {
mymutex->lock(); mymutex->lock();
Deinit(); Deinit();
delete mymutex; delete mymutex;
mymutex->unlock(); mymutex->unlock();
return CR_OK; return CR_OK;
} }

@ -527,7 +527,7 @@ command_result df_tiles (Core * c, vector <string> & parameters)
} }
else else
{ {
cout << "flow bit 1 = " << bflags.bits.liquid_1 << endl; cout << "flow bit 1 = " << bflags.bits.liquid_1 << endl;
cout << "flow bit 2 = " << bflags.bits.liquid_2 << endl; cout << "flow bit 2 = " << bflags.bits.liquid_2 << endl;
} }
biter ++; biter ++;

@ -156,7 +156,7 @@ command_result df_vectors (color_ostream &con, vector <string> & parameters)
vectorsUsage(con); vectorsUsage(con);
return CR_FAILURE; return CR_FAILURE;
} }
if (!hexOrDec(parameters[1], bytes)) if (!hexOrDec(parameters[1], bytes))
{ {
vectorsUsage(con); vectorsUsage(con);
@ -273,7 +273,7 @@ command_result df_clearvec (color_ostream &con, vector <string> & parameters)
vectorsUsage(con); vectorsUsage(con);
return CR_FAILURE; return CR_FAILURE;
} }
if (!hexOrDec(parameters[1], bytes)) if (!hexOrDec(parameters[1], bytes))
{ {
vectorsUsage(con); vectorsUsage(con);

@ -1 +1 @@
Subproject commit a80abe848e4886a210e7a5123192e9221dc85810 Subproject commit 5b167d2ba89b877d80e0609feae8771aeaef356d

@ -1156,7 +1156,7 @@ command_result diglx (color_ostream &out, vector <string> & parameters)
return digl(out,lol); return digl(out,lol);
} }
// TODO: // TODO:
// digl and digv share the longish floodfill code and only use different conditions // digl and digv share the longish floodfill code and only use different conditions
// to check if a tile should be marked for digging or not. // to check if a tile should be marked for digging or not.
// to make the plugin a bit smaller and cleaner a main execute method would be nice // to make the plugin a bit smaller and cleaner a main execute method would be nice
@ -1377,7 +1377,7 @@ command_result digtype (color_ostream &out, vector <string> & parameters)
out.printerr("Too many parameters.\n"); out.printerr("Too many parameters.\n");
return CR_FAILURE; return CR_FAILURE;
} }
uint32_t targetDigType; uint32_t targetDigType;
if ( parameters.size() == 1 ) if ( parameters.size() == 1 )
{ {
@ -1406,13 +1406,13 @@ command_result digtype (color_ostream &out, vector <string> & parameters)
{ {
targetDigType = -1; targetDigType = -1;
} }
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
out.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
return CR_FAILURE; return CR_FAILURE;
} }
int32_t cx, cy, cz; int32_t cx, cy, cz;
uint32_t xMax,yMax,zMax; uint32_t xMax,yMax,zMax;
Maps::getSize(xMax,yMax,zMax); Maps::getSize(xMax,yMax,zMax);
@ -1436,7 +1436,7 @@ command_result digtype (color_ostream &out, vector <string> & parameters)
return CR_FAILURE; return CR_FAILURE;
} }
out.print("(%d,%d,%d) tiletype: %d, veinmat: %d, designation: 0x%x ... DIGGING!\n", cx,cy,cz, tt, veinmat, baseDes.whole); out.print("(%d,%d,%d) tiletype: %d, veinmat: %d, designation: 0x%x ... DIGGING!\n", cx,cy,cz, tt, veinmat, baseDes.whole);
if ( targetDigType != -1 ) if ( targetDigType != -1 )
{ {
baseDes.bits.dig = (tile_dig_designation::tile_dig_designation)targetDigType; baseDes.bits.dig = (tile_dig_designation::tile_dig_designation)targetDigType;
@ -1448,7 +1448,7 @@ command_result digtype (color_ostream &out, vector <string> & parameters)
baseDes.bits.dig = tile_dig_designation::Default; baseDes.bits.dig = tile_dig_designation::Default;
} }
} }
for( uint32_t z = 0; z < zMax; z++ ) for( uint32_t z = 0; z < zMax; z++ )
{ {
for( uint32_t x = 1; x < tileXMax-1; x++ ) for( uint32_t x = 1; x < tileXMax-1; x++ )
@ -1462,7 +1462,7 @@ command_result digtype (color_ostream &out, vector <string> & parameters)
tt = mCache->tiletypeAt(current); tt = mCache->tiletypeAt(current);
if (!DFHack::isWallTerrain(tt)) if (!DFHack::isWallTerrain(tt))
continue; continue;
//designate it for digging //designate it for digging
df::tile_designation des = mCache->designationAt(current); df::tile_designation des = mCache->designationAt(current);
if ( !mCache->testCoord(current) ) if ( !mCache->testCoord(current) )
@ -1471,14 +1471,14 @@ command_result digtype (color_ostream &out, vector <string> & parameters)
delete mCache; delete mCache;
return CR_FAILURE; return CR_FAILURE;
} }
df::tile_designation designation = mCache->designationAt(current); df::tile_designation designation = mCache->designationAt(current);
designation.bits.dig = baseDes.bits.dig; designation.bits.dig = baseDes.bits.dig;
mCache->setDesignationAt(current, designation); mCache->setDesignationAt(current, designation);
} }
} }
} }
mCache->WriteAll(); mCache->WriteAll();
delete mCache; delete mCache;
return CR_OK; return CR_OK;

@ -38,7 +38,7 @@ set<string> autodigMaterials;
DFhackCExport command_result plugin_enable(color_ostream& out, bool enable) { DFhackCExport command_result plugin_enable(color_ostream& out, bool enable) {
if (enabled == enable) if (enabled == enable)
return CR_OK; return CR_OK;
enabled = enable; enabled = enable;
if ( enabled ) { if ( enabled ) {
EventManager::registerListener(EventManager::EventType::JOB_COMPLETED, digHandler, plugin_self); EventManager::registerListener(EventManager::EventType::JOB_COMPLETED, digHandler, plugin_self);
@ -79,31 +79,31 @@ void onDig(color_ostream& out, void* ptr) {
df::job* job = (df::job*)ptr; df::job* job = (df::job*)ptr;
if ( job->completion_timer > 0 ) if ( job->completion_timer > 0 )
return; return;
if ( job->job_type != df::enums::job_type::Dig && if ( job->job_type != df::enums::job_type::Dig &&
job->job_type != df::enums::job_type::CarveUpwardStaircase && job->job_type != df::enums::job_type::CarveUpwardStaircase &&
job->job_type != df::enums::job_type::CarveDownwardStaircase && job->job_type != df::enums::job_type::CarveDownwardStaircase &&
job->job_type != df::enums::job_type::CarveUpDownStaircase && job->job_type != df::enums::job_type::CarveUpDownStaircase &&
job->job_type != df::enums::job_type::CarveRamp && job->job_type != df::enums::job_type::CarveRamp &&
job->job_type != df::enums::job_type::DigChannel ) job->job_type != df::enums::job_type::DigChannel )
return; return;
set<df::coord> jobLocations; set<df::coord> jobLocations;
for ( df::job_list_link* link = &world->job_list; link != NULL; link = link->next ) { for ( df::job_list_link* link = &world->job_list; link != NULL; link = link->next ) {
if ( link->item == NULL ) if ( link->item == NULL )
continue; continue;
if ( link->item->job_type != df::enums::job_type::Dig && if ( link->item->job_type != df::enums::job_type::Dig &&
link->item->job_type != df::enums::job_type::CarveUpwardStaircase && link->item->job_type != df::enums::job_type::CarveUpwardStaircase &&
link->item->job_type != df::enums::job_type::CarveDownwardStaircase && link->item->job_type != df::enums::job_type::CarveDownwardStaircase &&
link->item->job_type != df::enums::job_type::CarveUpDownStaircase && link->item->job_type != df::enums::job_type::CarveUpDownStaircase &&
link->item->job_type != df::enums::job_type::CarveRamp && link->item->job_type != df::enums::job_type::CarveRamp &&
link->item->job_type != df::enums::job_type::DigChannel ) link->item->job_type != df::enums::job_type::DigChannel )
continue; continue;
jobLocations.insert(link->item->pos); jobLocations.insert(link->item->pos);
} }
MapExtras::MapCache cache; MapExtras::MapCache cache;
df::coord pos = job->pos; df::coord pos = job->pos;
for ( int16_t a = -1; a <= 1; a++ ) { for ( int16_t a = -1; a <= 1; a++ ) {
@ -118,23 +118,23 @@ void maybeExplore(color_ostream& out, MapExtras::MapCache& cache, df::coord pt,
if ( !Maps::isValidTilePos(pt) ) { if ( !Maps::isValidTilePos(pt) ) {
return; return;
} }
df::map_block* block = Maps::getTileBlock(pt); df::map_block* block = Maps::getTileBlock(pt);
if (!block) if (!block)
return; return;
if ( block->designation[pt.x&0xF][pt.y&0xF].bits.hidden ) if ( block->designation[pt.x&0xF][pt.y&0xF].bits.hidden )
return; return;
df::tiletype type = block->tiletype[pt.x&0xF][pt.y&0xF]; df::tiletype type = block->tiletype[pt.x&0xF][pt.y&0xF];
if ( ENUM_ATTR(tiletype, material, type) != df::enums::tiletype_material::MINERAL ) if ( ENUM_ATTR(tiletype, material, type) != df::enums::tiletype_material::MINERAL )
return; return;
if ( ENUM_ATTR(tiletype, shape, type) != df::enums::tiletype_shape::WALL ) if ( ENUM_ATTR(tiletype, shape, type) != df::enums::tiletype_shape::WALL )
return; return;
if ( block->designation[pt.x&0xF][pt.y&0xF].bits.dig != df::enums::tile_dig_designation::No ) if ( block->designation[pt.x&0xF][pt.y&0xF].bits.dig != df::enums::tile_dig_designation::No )
return; return;
uint32_t xMax,yMax,zMax; uint32_t xMax,yMax,zMax;
Maps::getSize(xMax,yMax,zMax); Maps::getSize(xMax,yMax,zMax);
if ( pt.x == 0 || pt.y == 0 || pt.x+1 == xMax*16 || pt.y+1 == yMax*16 ) if ( pt.x == 0 || pt.y == 0 || pt.x+1 == xMax*16 || pt.y+1 == yMax*16 )
@ -142,7 +142,7 @@ void maybeExplore(color_ostream& out, MapExtras::MapCache& cache, df::coord pt,
if ( jobLocations.find(pt) != jobLocations.end() ) { if ( jobLocations.find(pt) != jobLocations.end() ) {
return; return;
} }
int16_t mat = cache.veinMaterialAt(pt); int16_t mat = cache.veinMaterialAt(pt);
if ( mat == -1 ) if ( mat == -1 )
return; return;
@ -152,7 +152,7 @@ void maybeExplore(color_ostream& out, MapExtras::MapCache& cache, df::coord pt,
return; return;
} }
} }
block->designation[pt.x&0xF][pt.y&0xF].bits.dig = df::enums::tile_dig_designation::Default; block->designation[pt.x&0xF][pt.y&0xF].bits.dig = df::enums::tile_dig_designation::Default;
block->flags.bits.designated = true; block->flags.bits.designated = true;
// *process_dig = true; // *process_dig = true;
@ -174,12 +174,12 @@ command_result digFlood (color_ostream &out, std::vector <std::string> & paramet
adding = true; adding = true;
continue; continue;
} }
if ( parameters[a] == "CLEAR" ) { if ( parameters[a] == "CLEAR" ) {
autodigMaterials.clear(); autodigMaterials.clear();
continue; continue;
} }
if ( parameters[a] == "digAll0" ) { if ( parameters[a] == "digAll0" ) {
digAll = false; digAll = false;
continue; continue;
@ -188,7 +188,7 @@ command_result digFlood (color_ostream &out, std::vector <std::string> & paramet
digAll = true; digAll = true;
continue; continue;
} }
for ( size_t b = 0; b < world->raws.inorganics.size(); b++ ) { for ( size_t b = 0; b < world->raws.inorganics.size(); b++ ) {
df::inorganic_raw* inorganic = world->raws.inorganics[b]; df::inorganic_raw* inorganic = world->raws.inorganics[b];
if ( parameters[a] == inorganic->id ) { if ( parameters[a] == inorganic->id ) {
@ -199,16 +199,16 @@ command_result digFlood (color_ostream &out, std::vector <std::string> & paramet
goto loop; goto loop;
} }
} }
out.print("Could not find material \"%s\".\n", parameters[a].c_str()); out.print("Could not find material \"%s\".\n", parameters[a].c_str());
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
loop: continue; loop: continue;
} }
autodigMaterials.insert(toAdd.begin(), toAdd.end()); autodigMaterials.insert(toAdd.begin(), toAdd.end());
for ( auto a = toRemove.begin(); a != toRemove.end(); a++ ) for ( auto a = toRemove.begin(); a != toRemove.end(); a++ )
autodigMaterials.erase(*a); autodigMaterials.erase(*a);
return CR_OK; return CR_OK;
} }

@ -53,7 +53,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
if ( !firstInvader ) { if ( !firstInvader ) {
return -1; return -1;
} }
//do whatever you need to do at the first important edge //do whatever you need to do at the first important edge
df::coord pt1 = firstImportantEdge.p1; df::coord pt1 = firstImportantEdge.p1;
df::coord pt2 = firstImportantEdge.p2; df::coord pt2 = firstImportantEdge.p2;
@ -63,14 +63,14 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
pt2 = temp; pt2 = temp;
} }
//out.print("first important edge: (%d,%d,%d) -> (%d,%d,%d)\n", pt1.x,pt1.y,pt1.z, pt2.x,pt2.y,pt2.z); //out.print("first important edge: (%d,%d,%d) -> (%d,%d,%d)\n", pt1.x,pt1.y,pt1.z, pt2.x,pt2.y,pt2.z);
int32_t jobId = -1; int32_t jobId = -1;
df::map_block* block1 = Maps::getTileBlock(pt1); df::map_block* block1 = Maps::getTileBlock(pt1);
df::map_block* block2 = Maps::getTileBlock(pt2); df::map_block* block2 = Maps::getTileBlock(pt2);
bool passable1 = block1->walkable[pt1.x&0xF][pt1.y&0xF]; bool passable1 = block1->walkable[pt1.x&0xF][pt1.y&0xF];
bool passable2 = block2->walkable[pt2.x&0xF][pt2.y&0xF]; bool passable2 = block2->walkable[pt2.x&0xF][pt2.y&0xF];
df::coord location; df::coord location;
df::building* building = Buildings::findAtTile(pt2); df::building* building = Buildings::findAtTile(pt2);
df::coord buildingPos = pt2; df::coord buildingPos = pt2;
@ -202,7 +202,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
Job::linkIntoWorld(job); Job::linkIntoWorld(job);
jobId = job->id; jobId = job->id;
job->completion_timer = abilities.jobDelay[CostDimension::Dig]; job->completion_timer = abilities.jobDelay[CostDimension::Dig];
//TODO: test if he already has a pick //TODO: test if he already has a pick
bool hasPick = false; bool hasPick = false;
for ( size_t a = 0; a < firstInvader->inventory.size(); a++ ) { for ( size_t a = 0; a < firstInvader->inventory.size(); a++ ) {
@ -219,10 +219,10 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
hasPick = true; hasPick = true;
break; break;
} }
if ( hasPick ) if ( hasPick )
return firstInvader->id; return firstInvader->id;
//create and give a pick //create and give a pick
//based on createitem.cpp //based on createitem.cpp
df::reaction_product_itemst *prod = NULL; df::reaction_product_itemst *prod = NULL;
@ -240,7 +240,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
out.print("%s, %d: no valid item.\n", __FILE__, __LINE__); out.print("%s, %d: no valid item.\n", __FILE__, __LINE__);
return -1; return -1;
} }
DFHack::MaterialInfo material; DFHack::MaterialInfo material;
if ( !material.find("OBSIDIAN") ) { if ( !material.find("OBSIDIAN") ) {
out.print("%s, %d: no water.\n", __FILE__, __LINE__); out.print("%s, %d: no water.\n", __FILE__, __LINE__);
@ -251,20 +251,20 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
prod->probability = 100; prod->probability = 100;
prod->count = 1; prod->count = 1;
prod->product_dimension = 1; prod->product_dimension = 1;
vector<df::item*> out_items; vector<df::item*> out_items;
vector<df::reaction_reagent*> in_reag; vector<df::reaction_reagent*> in_reag;
vector<df::item*> in_items; vector<df::item*> in_items;
prod->produce(firstInvader, &out_items, &in_reag, &in_items, 1, df::job_skill::NONE, prod->produce(firstInvader, &out_items, &in_reag, &in_items, 1, df::job_skill::NONE,
df::historical_entity::find(firstInvader->civ_id), df::historical_entity::find(firstInvader->civ_id),
df::world_site::find(df::global::ui->site_id)); df::world_site::find(df::global::ui->site_id));
if ( out_items.size() != 1 ) { if ( out_items.size() != 1 ) {
out.print("%s, %d: wrong size: %d.\n", __FILE__, __LINE__, out_items.size()); out.print("%s, %d: wrong size: %d.\n", __FILE__, __LINE__, out_items.size());
return -1; return -1;
} }
out_items[0]->moveToGround(firstInvader->pos.x, firstInvader->pos.y, firstInvader->pos.z); out_items[0]->moveToGround(firstInvader->pos.x, firstInvader->pos.y, firstInvader->pos.z);
#if 0 #if 0
//check for existing item there //check for existing item there
for ( size_t a = 0; a < firstInvader->inventory.size(); a++ ) { for ( size_t a = 0; a < firstInvader->inventory.size(); a++ ) {
@ -276,7 +276,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
} }
#endif #endif
Items::moveToInventory(cache, out_items[0], firstInvader, df::unit_inventory_item::T_mode::Weapon, firstInvader->body.weapon_bp); Items::moveToInventory(cache, out_items[0], firstInvader, df::unit_inventory_item::T_mode::Weapon, firstInvader->body.weapon_bp);
delete prod; delete prod;
} }
} }

@ -141,7 +141,7 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
" diggingInvaders edgesPerTick n\n makes the pathfinding algorithm work on at most n edges per tick. Set to 0 or lower to make it unlimited." " diggingInvaders edgesPerTick n\n makes the pathfinding algorithm work on at most n edges per tick. Set to 0 or lower to make it unlimited."
// " diggingInvaders\n Makes invaders try to dig now.\n" // " diggingInvaders\n Makes invaders try to dig now.\n"
)); ));
//*df::global::debug_showambush = true; //*df::global::debug_showambush = true;
return CR_OK; return CR_OK;
} }
@ -154,7 +154,7 @@ DFhackCExport command_result plugin_shutdown ( color_ostream &out )
DFhackCExport command_result plugin_enable(color_ostream& out, bool enable) { DFhackCExport command_result plugin_enable(color_ostream& out, bool enable) {
if ( enabled == enable ) if ( enabled == enable )
return CR_OK; return CR_OK;
enabled = enable; enabled = enable;
EventManager::unregisterAll(plugin_self); EventManager::unregisterAll(plugin_self);
clearDijkstra(); clearDijkstra();
@ -166,7 +166,7 @@ DFhackCExport command_result plugin_enable(color_ostream& out, bool enable) {
EventManager::registerListener(EventManager::EventType::INVASION, handler, plugin_self); EventManager::registerListener(EventManager::EventType::INVASION, handler, plugin_self);
findAndAssignInvasionJob(out, (void*)0); findAndAssignInvasionJob(out, (void*)0);
} }
return CR_OK; return CR_OK;
} }
@ -196,9 +196,9 @@ class PointComp {
public: public:
unordered_map<df::coord, cost_t, PointHash> *pointCost; unordered_map<df::coord, cost_t, PointHash> *pointCost;
PointComp(unordered_map<df::coord, cost_t, PointHash> *p): pointCost(p) { PointComp(unordered_map<df::coord, cost_t, PointHash> *p): pointCost(p) {
} }
int32_t operator()(df::coord p1, df::coord p2) { int32_t operator()(df::coord p1, df::coord p2) {
if ( p1 == p2 ) return 0; if ( p1 == p2 ) return 0;
auto i1 = pointCost->find(p1); auto i1 = pointCost->find(p1);
@ -246,11 +246,11 @@ command_result diggingInvadersCommand(color_ostream& out, std::vector<std::strin
digAbilities.erase(race); digAbilities.erase(race);
} }
a++; a++;
} else if ( parameters[a] == "setCost" || parameters[a] == "setDelay" ) { } else if ( parameters[a] == "setCost" || parameters[a] == "setDelay" ) {
if ( a+3 >= parameters.size() ) if ( a+3 >= parameters.size() )
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
string raceString = parameters[a+1]; string raceString = parameters[a+1];
if ( digAbilities.find(raceString) == digAbilities.end() ) { if ( digAbilities.find(raceString) == digAbilities.end() ) {
DigAbilities bob; DigAbilities bob;
@ -258,7 +258,7 @@ command_result diggingInvadersCommand(color_ostream& out, std::vector<std::strin
digAbilities[raceString] = bob; digAbilities[raceString] = bob;
} }
DigAbilities& abilities = digAbilities[raceString]; DigAbilities& abilities = digAbilities[raceString];
string costStr = parameters[a+2]; string costStr = parameters[a+2];
int32_t costDim = -1; int32_t costDim = -1;
if ( costStr == "walk" ) { if ( costStr == "walk" ) {
@ -276,7 +276,7 @@ command_result diggingInvadersCommand(color_ostream& out, std::vector<std::strin
} else { } else {
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
cost_t value; cost_t value;
stringstream asdf(parameters[a+3]); stringstream asdf(parameters[a+3]);
asdf >> value; asdf >> value;
@ -291,15 +291,15 @@ command_result diggingInvadersCommand(color_ostream& out, std::vector<std::strin
} else if ( parameters[a] == "edgeCost" ) { } else if ( parameters[a] == "edgeCost" ) {
if ( a+1 >= parameters.size() ) if ( a+1 >= parameters.size() )
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
string raceString = parameters[a+1]; string raceString = parameters[a+1];
if ( digAbilities.find(raceString) == digAbilities.end() ) { if ( digAbilities.find(raceString) == digAbilities.end() ) {
out.print("Race %s does not have dig abilities assigned.\n", raceString.c_str()); out.print("Race %s does not have dig abilities assigned.\n", raceString.c_str());
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
DigAbilities& abilities = digAbilities[raceString]; DigAbilities& abilities = digAbilities[raceString];
df::coord bob = Gui::getCursorPos(); df::coord bob = Gui::getCursorPos();
out.print("(%d,%d,%d), (%d,%d,%d): cost = %lld\n", lastDebugEdgeCostPoint.x, lastDebugEdgeCostPoint.y, lastDebugEdgeCostPoint.z, bob.x, bob.y, bob.z, getEdgeCost(out, lastDebugEdgeCostPoint, bob, abilities)); out.print("(%d,%d,%d), (%d,%d,%d): cost = %lld\n", lastDebugEdgeCostPoint.x, lastDebugEdgeCostPoint.y, lastDebugEdgeCostPoint.z, bob.x, bob.y, bob.z, getEdgeCost(out, lastDebugEdgeCostPoint, bob, abilities));
lastDebugEdgeCostPoint = bob; lastDebugEdgeCostPoint = bob;
@ -325,7 +325,7 @@ command_result diggingInvadersCommand(color_ostream& out, std::vector<std::strin
} }
activeDigging = enabled; activeDigging = enabled;
out.print("diggingInvaders: enabled = %d, activeDigging = %d, edgesPerTick = %d\n", enabled, activeDigging, edgesPerTick); out.print("diggingInvaders: enabled = %d, activeDigging = %d, edgesPerTick = %d\n", enabled, activeDigging, edgesPerTick);
return CR_OK; return CR_OK;
} }
@ -366,14 +366,14 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
CoreSuspender suspend; CoreSuspender suspend;
//returns the worker id of the job created //used to //returns the worker id of the job created //used to
//out.print("%s, %d: %d\n", __FILE__, __LINE__, (int32_t)tickTime); //out.print("%s, %d: %d\n", __FILE__, __LINE__, (int32_t)tickTime);
if ( !enabled || !activeDigging ) { if ( !enabled || !activeDigging ) {
clearDijkstra(); clearDijkstra();
return; return;
} }
EventManager::unregister(EventManager::EventType::TICK, findJobTickHandler, plugin_self); EventManager::unregister(EventManager::EventType::TICK, findJobTickHandler, plugin_self);
EventManager::registerTick(findJobTickHandler, 1, plugin_self); EventManager::registerTick(findJobTickHandler, 1, plugin_self);
if ( fringe.empty() ) { if ( fringe.empty() ) {
df::unit* lastDigger = df::unit::find(lastInvasionDigger); df::unit* lastDigger = df::unit::find(lastInvasionDigger);
if ( lastDigger && lastDigger->job.current_job && lastDigger->job.current_job->id == lastInvasionJob ) { if ( lastDigger && lastDigger->job.current_job && lastDigger->job.current_job->id == lastInvasionJob ) {
@ -381,7 +381,7 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
} }
//out.print("%s,%d: lastDigger = %d, last job = %d, last digger's job = %d\n", __FILE__, __LINE__, lastInvasionDigger, lastInvasionJob, !lastDigger ? -1 : (!lastDigger->job.current_job ? -1 : lastDigger->job.current_job->id)); //out.print("%s,%d: lastDigger = %d, last job = %d, last digger's job = %d\n", __FILE__, __LINE__, lastInvasionDigger, lastInvasionJob, !lastDigger ? -1 : (!lastDigger->job.current_job ? -1 : lastDigger->job.current_job->id));
lastInvasionDigger = lastInvasionJob = -1; lastInvasionDigger = lastInvasionJob = -1;
clearDijkstra(); clearDijkstra();
unordered_set<uint16_t> invaderConnectivity; unordered_set<uint16_t> invaderConnectivity;
unordered_set<uint16_t> localConnectivity; unordered_set<uint16_t> localConnectivity;
@ -446,13 +446,13 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
return; return;
} }
} }
df::unit* firstInvader = df::unit::find(invaders[0]); df::unit* firstInvader = df::unit::find(invaders[0]);
if ( firstInvader == NULL ) { if ( firstInvader == NULL ) {
fringe.clear(); fringe.clear();
return; return;
} }
df::creature_raw* creature_raw = df::creature_raw::find(firstInvader->race); df::creature_raw* creature_raw = df::creature_raw::find(firstInvader->race);
if ( creature_raw == NULL || digAbilities.find(creature_raw->creature_id) == digAbilities.end() ) { if ( creature_raw == NULL || digAbilities.find(creature_raw->creature_id) == digAbilities.end() ) {
//inappropriate digger: no dig abilities //inappropriate digger: no dig abilities
@ -464,13 +464,13 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
//out << firstInvader->id << endl; //out << firstInvader->id << endl;
//out << firstInvader->pos.x << ", " << firstInvader->pos.y << ", " << firstInvader->pos.z << endl; //out << firstInvader->pos.x << ", " << firstInvader->pos.y << ", " << firstInvader->pos.z << endl;
//out << __LINE__ << endl; //out << __LINE__ << endl;
uint32_t xMax, yMax, zMax; uint32_t xMax, yMax, zMax;
Maps::getSize(xMax,yMax,zMax); Maps::getSize(xMax,yMax,zMax);
xMax *= 16; xMax *= 16;
yMax *= 16; yMax *= 16;
MapExtras::MapCache cache; MapExtras::MapCache cache;
clock_t t0 = clock(); clock_t t0 = clock();
clock_t totalEdgeTime = 0; clock_t totalEdgeTime = 0;
int32_t edgesExpanded = 0; int32_t edgesExpanded = 0;
@ -486,7 +486,7 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
break; break;
} }
closedSet.insert(pt); closedSet.insert(pt);
if ( localPts.find(pt) != localPts.end() ) { if ( localPts.find(pt) != localPts.end() ) {
localPtsFound++; localPtsFound++;
if ( true || localPtsFound >= localPts.size() ) { if ( true || localPtsFound >= localPts.size() ) {
@ -537,7 +537,7 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
unordered_set<df::coord, PointHash> requiresZNeg; unordered_set<df::coord, PointHash> requiresZNeg;
unordered_set<df::coord, PointHash> requiresZPos; unordered_set<df::coord, PointHash> requiresZPos;
//find important edges //find important edges
Edge firstImportantEdge(df::coord(), df::coord(), -1); Edge firstImportantEdge(df::coord(), df::coord(), -1);
//df::coord closest; //df::coord closest;
@ -551,7 +551,7 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
continue; continue;
//closest = pt; //closest = pt;
//closestCostEstimate = costMap[closest]; //closestCostEstimate = costMap[closest];
//if ( workNeeded[pt] == 0 ) //if ( workNeeded[pt] == 0 )
// continue; // continue;
while ( parentMap.find(pt) != parentMap.end() ) { while ( parentMap.find(pt) != parentMap.end() ) {
//out.print("(%d,%d,%d)\n", pt.x, pt.y, pt.z); //out.print("(%d,%d,%d)\n", pt.x, pt.y, pt.z);
@ -563,7 +563,7 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
} }
//closestCostActual += cost; //closestCostActual += cost;
if ( Maps::canStepBetween(parent, pt) ) { if ( Maps::canStepBetween(parent, pt) ) {
} else { } else {
if ( pt.x == parent.x && pt.y == parent.y ) { if ( pt.x == parent.x && pt.y == parent.y ) {
if ( pt.z < parent.z ) { if ( pt.z < parent.z ) {
@ -586,14 +586,14 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
} }
if ( firstImportantEdge.p1 == df::coord() ) if ( firstImportantEdge.p1 == df::coord() )
return; return;
/* /*
if ( closestCostActual != closestCostEstimate ) { if ( closestCostActual != closestCostEstimate ) {
out.print("%s,%d: closest = (%d,%d,%d), estimate = %lld != actual = %lld\n", __FILE__, __LINE__, closest.x,closest.y,closest.z, closestCostEstimate, closestCostActual); out.print("%s,%d: closest = (%d,%d,%d), estimate = %lld != actual = %lld\n", __FILE__, __LINE__, closest.x,closest.y,closest.z, closestCostEstimate, closestCostActual);
return; return;
} }
*/ */
assignJob(out, firstImportantEdge, parentMap, costMap, invaders, requiresZNeg, requiresZPos, cache, abilities); assignJob(out, firstImportantEdge, parentMap, costMap, invaders, requiresZNeg, requiresZPos, cache, abilities);
lastInvasionDigger = firstInvader->id; lastInvasionDigger = firstInvader->id;
lastInvasionJob = firstInvader->job.current_job ? firstInvader->job.current_job->id : -1; lastInvasionJob = firstInvader->job.current_job ? firstInvader->job.current_job->id : -1;
@ -605,7 +605,7 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
if ( invaderJobs.find(job->id) == invaderJobs.end() ) { if ( invaderJobs.find(job->id) == invaderJobs.end() ) {
continue; continue;
} }
//cancel it //cancel it
job->flags.bits.item_lost = 1; job->flags.bits.item_lost = 1;
out.print("%s,%d: cancelling job %d.\n", __FILE__,__LINE__, job->id); out.print("%s,%d: cancelling job %d.\n", __FILE__,__LINE__, job->id);

@ -57,34 +57,34 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie
cost_t cost = abilities.costWeight[CostDimension::Walk]; cost_t cost = abilities.costWeight[CostDimension::Walk];
if ( cost < 0 ) if ( cost < 0 )
return -1; return -1;
if ( Maps::getTileBlock(pt1) == NULL || Maps::getTileBlock(pt2) == NULL ) if ( Maps::getTileBlock(pt1) == NULL || Maps::getTileBlock(pt2) == NULL )
return -1; return -1;
df::tiletype* type2 = Maps::getTileType(pt2); df::tiletype* type2 = Maps::getTileType(pt2);
df::tiletype_shape shape2 = ENUM_ATTR(tiletype, shape, *type2); df::tiletype_shape shape2 = ENUM_ATTR(tiletype, shape, *type2);
if ( Maps::getTileBlock(pt1)->designation[pt1.x&0xF][pt1.y&0xF].bits.flow_size >= 4 ) if ( Maps::getTileBlock(pt1)->designation[pt1.x&0xF][pt1.y&0xF].bits.flow_size >= 4 )
return -1; return -1;
if ( Maps::getTileBlock(pt2)->designation[pt2.x&0xF][pt2.y&0xF].bits.flow_size >= 4 ) if ( Maps::getTileBlock(pt2)->designation[pt2.x&0xF][pt2.y&0xF].bits.flow_size >= 4 )
return -1; return -1;
if ( shape2 == df::enums::tiletype_shape::EMPTY ) { if ( shape2 == df::enums::tiletype_shape::EMPTY ) {
return -1; return -1;
} }
if ( shape2 == df::enums::tiletype_shape::BRANCH || if ( shape2 == df::enums::tiletype_shape::BRANCH ||
shape2 == df::enums::tiletype_shape::TRUNK_BRANCH || shape2 == df::enums::tiletype_shape::TRUNK_BRANCH ||
shape2 == df::enums::tiletype_shape::TWIG ) shape2 == df::enums::tiletype_shape::TWIG )
return -1; return -1;
/* /*
if () { if () {
df::map_block* temp = Maps::getTileBlock(df::coord(pt1.x,pt1.y,pt1.z-1)); df::map_block* temp = Maps::getTileBlock(df::coord(pt1.x,pt1.y,pt1.z-1));
if ( temp && temp->designation[pt1.x&0xF][pt1.y&0xF] if ( temp && temp->designation[pt1.x&0xF][pt1.y&0xF]
} }
*/ */
if ( Maps::canStepBetween(pt1, pt2) ) { if ( Maps::canStepBetween(pt1, pt2) ) {
return cost; return cost;
} }
@ -93,11 +93,11 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie
if ( building2 ) { if ( building2 ) {
if ( abilities.costWeight[CostDimension::DestroyBuilding] < 0 ) if ( abilities.costWeight[CostDimension::DestroyBuilding] < 0 )
return -1; return -1;
cost += abilities.costWeight[CostDimension::DestroyBuilding]; cost += abilities.costWeight[CostDimension::DestroyBuilding];
if ( dx*dx + dy*dy > 1 ) if ( dx*dx + dy*dy > 1 )
return -1; return -1;
} }
bool construction2 = ENUM_ATTR(tiletype, material, *type2) == df::enums::tiletype_material::CONSTRUCTION; bool construction2 = ENUM_ATTR(tiletype, material, *type2) == df::enums::tiletype_material::CONSTRUCTION;
if ( construction2 ) { if ( construction2 ) {
//smooth or not? //smooth or not?
@ -113,7 +113,7 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie
cost += abilities.costWeight[CostDimension::DestroyRoughConstruction]; cost += abilities.costWeight[CostDimension::DestroyRoughConstruction];
} }
} }
if ( dz == 0 ) { if ( dz == 0 ) {
if ( !building2 && !construction2 ) { if ( !building2 && !construction2 ) {
//it has to be a wall //it has to be a wall
@ -143,7 +143,7 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie
} }
cost += abilities.costWeight[CostDimension::Dig]; cost += abilities.costWeight[CostDimension::Dig];
} }
bool walkable_high1 = shape1 == df::tiletype_shape::STAIR_UP || shape1 == df::tiletype_shape::STAIR_UPDOWN; bool walkable_high1 = shape1 == df::tiletype_shape::STAIR_UP || shape1 == df::tiletype_shape::STAIR_UPDOWN;
if ( !walkable_high1 ) { if ( !walkable_high1 ) {
if ( shape1 != df::enums::tiletype_shape::WALL ) { if ( shape1 != df::enums::tiletype_shape::WALL ) {
@ -154,7 +154,7 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie
} }
cost += abilities.costWeight[CostDimension::Dig]; cost += abilities.costWeight[CostDimension::Dig];
} }
if ( building2 ) { if ( building2 ) {
//moving up through an open bridge or a usable hatch is fine. other buildings are not //moving up through an open bridge or a usable hatch is fine. other buildings are not
bool unforbiddenHatch = false; bool unforbiddenHatch = false;
@ -188,7 +188,7 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie
if ( !unforbiddenHatch && !inactiveBridge ) if ( !unforbiddenHatch && !inactiveBridge )
return -1; return -1;
} }
/*bool forbidden = false; /*bool forbidden = false;
if ( building2 && building2->getType() == df::building_type::Hatch ) { if ( building2 && building2->getType() == df::building_type::Hatch ) {
df::building_hatchst* hatch = (df::building_hatchst*)building2; df::building_hatchst* hatch = (df::building_hatchst*)building2;
@ -202,7 +202,7 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie
if ( !walkable_high2 ) { if ( !walkable_high2 ) {
if ( building2 || construction2 ) if ( building2 || construction2 )
return -1; return -1;
if ( shape2 != df::enums::tiletype_shape::WALL ) if ( shape2 != df::enums::tiletype_shape::WALL )
return -1; return -1;
if ( abilities.costWeight[CostDimension::Dig] < 0 ) { if ( abilities.costWeight[CostDimension::Dig] < 0 ) {
@ -240,14 +240,14 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie
if ( bridge->direction == df::building_bridgest::T_direction::Down && pt1.y == bridge->y2 ) if ( bridge->direction == df::building_bridgest::T_direction::Down && pt1.y == bridge->y2 )
return -1; return -1;
} }
bool forbidden = false; bool forbidden = false;
if ( building1 && building1->getType() == df::building_type::Hatch ) { if ( building1 && building1->getType() == df::building_type::Hatch ) {
df::building_hatchst* hatch = (df::building_hatchst*)building1; df::building_hatchst* hatch = (df::building_hatchst*)building1;
if ( hatch->door_flags.bits.forbidden || hatch->door_flags.bits.closed && hatch->door_flags.bits.operated_by_mechanisms ) if ( hatch->door_flags.bits.forbidden || hatch->door_flags.bits.closed && hatch->door_flags.bits.operated_by_mechanisms )
forbidden = true; forbidden = true;
} }
//you can deconstruct a hatch from the side //you can deconstruct a hatch from the side
if ( building1 && forbidden /*&& building1->getType() == df::building_type::Hatch*/ ) { if ( building1 && forbidden /*&& building1->getType() == df::building_type::Hatch*/ ) {
/* /*
@ -300,7 +300,7 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie
if ( minCost == -1 ) if ( minCost == -1 )
return -1; return -1;
cost += minCost; cost += minCost;
*/ */
//note: assignJob is not ready for this level of sophistication, so don't allow it //note: assignJob is not ready for this level of sophistication, so don't allow it
return -1; return -1;
@ -312,7 +312,7 @@ cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilitie
return -1; return -1;
} }
} }
return cost; return cost;
} }
@ -329,7 +329,7 @@ cost_t getEdgeCostOld(color_ostream& out, df::coord pt1, df::coord pt2) {
return cost; return cost;
return 100 + cost; return 100 + cost;
} }
Maps::ensureTileBlock(pt1); Maps::ensureTileBlock(pt1);
Maps::ensureTileBlock(pt2); Maps::ensureTileBlock(pt2);
df::tiletype* type1 = Maps::getTileType(pt1); df::tiletype* type1 = Maps::getTileType(pt1);
@ -404,7 +404,7 @@ cost_t getEdgeCostOld(color_ostream& out, df::coord pt1, df::coord pt2) {
if ( shape2 == df::enums::tiletype_shape::RAMP_TOP ) { if ( shape2 == df::enums::tiletype_shape::RAMP_TOP ) {
return -1; return -1;
} }
//it has to be a wall //it has to be a wall
if ( shape2 != df::enums::tiletype_shape::WALL ) { if ( shape2 != df::enums::tiletype_shape::WALL ) {
out << "shape = " << (int32_t)shape2 << endl; out << "shape = " << (int32_t)shape2 << endl;
@ -427,15 +427,15 @@ cost_t getEdgeCostOld(color_ostream& out, df::coord pt1, df::coord pt2) {
cost += costWeight[CostDimension::Dig]; cost += costWeight[CostDimension::Dig];
return cost; return cost;
} }
//descending //descending
if ( passable_high2 ) if ( passable_high2 )
return cost; return cost;
if ( building2 || construction2 ) { if ( building2 || construction2 ) {
return -1; return -1;
} }
//must be a wall? //must be a wall?
if ( shape2 != df::enums::tiletype_shape::WALL ) { if ( shape2 != df::enums::tiletype_shape::WALL ) {
out.print("%s, line %n: WTF?\n", __FILE__, __LINE__); out.print("%s, line %n: WTF?\n", __FILE__, __LINE__);
@ -445,7 +445,7 @@ cost_t getEdgeCostOld(color_ostream& out, df::coord pt1, df::coord pt2) {
cost += costWeight[CostDimension::Dig]; cost += costWeight[CostDimension::Dig];
return cost; return cost;
} }
//moving diagonally //moving diagonally
return -1; return -1;
} }
@ -455,7 +455,7 @@ vector<Edge>* getEdgeSet(color_ostream &out, df::coord point, MapExtras::MapCach
//vector<Edge>* result = new vector<Edge>(26); //vector<Edge>* result = new vector<Edge>(26);
vector<Edge>* result = new vector<Edge>(); vector<Edge>* result = new vector<Edge>();
result->reserve(26); result->reserve(26);
//size_t count = 0; //size_t count = 0;
for ( int32_t dx = -1; dx <= 1; dx++ ) { for ( int32_t dx = -1; dx <= 1; dx++ ) {
for ( int32_t dy = -1; dy <= 1; dy++ ) { for ( int32_t dy = -1; dy <= 1; dy++ ) {

@ -56,7 +56,7 @@ public:
cost = -1; cost = -1;
} }
Edge(const Edge& e): p1(e.p1), p2(e.p2), cost(e.cost) { Edge(const Edge& e): p1(e.p1), p2(e.p2), cost(e.cost) {
} }
Edge(df::coord p1In, df::coord p2In, cost_t costIn): cost(costIn) { Edge(df::coord p1In, df::coord p2In, cost_t costIn): cost(costIn) {
if ( p2In < p1In ) { if ( p2In < p1In ) {

@ -103,7 +103,7 @@ static void printAttributes(color_ostream &con, df::unit* cre, ostream& out) {
static void printTraits(color_ostream &con, df::unit* cre, ostream& out) static void printTraits(color_ostream &con, df::unit* cre, ostream& out)
{ {
out << " <Traits>" << endl; out << " <Traits>" << endl;
df::unit_soul * s = cre->status.current_soul; df::unit_soul * s = cre->status.current_soul;
if (s) if (s)
@ -120,7 +120,7 @@ static void printTraits(color_ostream &con, df::unit* cre, ostream& out)
} }
*/ */
out << "</Trait>" << endl; out << "</Trait>" << endl;
} }
} }
out << " </Traits>" << endl; out << " </Traits>" << endl;
@ -189,7 +189,7 @@ static void export_dwarf(color_ostream &con, df::unit* cre, ostream& out) {
info += Translation::TranslateName(&cre->name, false); info += Translation::TranslateName(&cre->name, false);
info[0] = toupper(info[0]); info[0] = toupper(info[0]);
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);
@ -225,7 +225,7 @@ command_result export_dwarves (color_ostream &con, std::vector <std::string> & p
uint32_t civ = ui->civ_id; uint32_t civ = ui->civ_id;
outf << "<?xml version='1.0' encoding='ibm850'?>" << endl << "<Creatures>" << endl; outf << "<?xml version='1.0' encoding='ibm850'?>" << endl << "<Creatures>" << endl;
for (int i = 0; i < world->units.all.size(); ++i) for (int i = 0; i < world->units.all.size(); ++i)
{ {
df::unit* cre = world->units.all[i]; df::unit* cre = world->units.all[i];

@ -1720,8 +1720,8 @@ struct dwarf_monitor_hook : public df::viewscreen_dwarfmodest
ostringstream date_str; ostringstream date_str;
auto month = World::ReadCurrentMonth() + 1; auto month = World::ReadCurrentMonth() + 1;
auto day = World::ReadCurrentDay(); auto day = World::ReadCurrentDay();
date_str << "Date:" << World::ReadCurrentYear() << "-" << date_str << "Date:" << World::ReadCurrentYear() << "-" <<
((month < 10) ? "0" : "") << month << "-" << ((month < 10) ? "0" : "") << month << "-" <<
((day < 10) ? "0" : "") << day; ((day < 10) ? "0" : "") << day;
OutputString(COLOR_GREY, x, y, date_str.str()); OutputString(COLOR_GREY, x, y, date_str.str());

@ -463,7 +463,7 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan
break; break;
case SC_WORLD_UNLOADED: case SC_WORLD_UNLOADED:
world_specific_hooks(out,false); world_specific_hooks(out,false);
break; break;
default: default:
break; break;

@ -247,6 +247,6 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <Plug
" * 0 - Disable dwarf teleportation (default)\n" " * 0 - Disable dwarf teleportation (default)\n"
" * 1 - Make dwarves teleport to their destinations instantly.\n" " * 1 - Make dwarves teleport to their destinations instantly.\n"
)); ));
return CR_OK; return CR_OK;
} }

@ -71,14 +71,14 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <Plug
" L: Low Traffic\n" " L: Low Traffic\n"
" R: Restricted Traffic\n" " R: Restricted Traffic\n"
)); ));
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"restrictliquids","Restrict on every visible square with liquid", "restrictliquids","Restrict on every visible square with liquid",
restrictLiquid, false, "" restrictLiquid, false, ""
)); ));
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"restrictice","Restrict traffic on squares above visible ice", "restrictice","Restrict traffic on squares above visible ice",
restrictIce, false, "" restrictIce, false, ""
)); ));
return CR_OK; return CR_OK;
} }
@ -285,7 +285,7 @@ command_result restrictLiquid(color_ostream &out, std::vector<std::string> & par
command_result restrictIce(color_ostream &out, std::vector<std::string> & params) command_result restrictIce(color_ostream &out, std::vector<std::string> & params)
{ {
return setAllMatching(out, restrictIceProc); return setAllMatching(out, restrictIceProc);
} }
//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.
@ -383,29 +383,29 @@ void allRestricted(DFCoord coord, MapExtras::MapCache &map)
//Restrict traffic if tile is visible and liquid is present. //Restrict traffic if tile is visible and liquid is present.
void restrictLiquidProc(DFCoord coord, MapExtras::MapCache &map) void restrictLiquidProc(DFCoord coord, MapExtras::MapCache &map)
{ {
df::tile_designation des = map.designationAt(coord); df::tile_designation des = map.designationAt(coord);
if ((des.bits.hidden == 0) && (des.bits.flow_size != 0)) if ((des.bits.hidden == 0) && (des.bits.flow_size != 0))
{ {
des.bits.traffic = tile_traffic::Restricted; des.bits.traffic = tile_traffic::Restricted;
map.setDesignationAt(coord, des); map.setDesignationAt(coord, des);
} }
} }
//Restrict traffice if tile is above visible ice wall. //Restrict traffice if tile is above visible ice wall.
void restrictIceProc(DFCoord coord, MapExtras::MapCache &map) void restrictIceProc(DFCoord coord, MapExtras::MapCache &map)
{ {
//There is no ice below the bottom of the map. //There is no ice below the bottom of the map.
if (coord.z == 0) if (coord.z == 0)
return; return;
DFCoord tile_below = DFCoord(coord.x, coord.y, coord.z - 1); DFCoord tile_below = DFCoord(coord.x, coord.y, coord.z - 1);
df::tiletype tt = map.tiletypeAt(tile_below); df::tiletype tt = map.tiletypeAt(tile_below);
df::tile_designation des = map.designationAt(tile_below); df::tile_designation des = map.designationAt(tile_below);
if ((des.bits.hidden == 0) && (tileMaterial(tt) == tiletype_material::FROZEN_LIQUID)) if ((des.bits.hidden == 0) && (tileMaterial(tt) == tiletype_material::FROZEN_LIQUID))
{ {
des = map.designationAt(coord); des = map.designationAt(coord);
des.bits.traffic = tile_traffic::Restricted; des.bits.traffic = tile_traffic::Restricted;
map.setDesignationAt(coord, des); map.setDesignationAt(coord, des);
} }
} }

@ -46,7 +46,7 @@ command_result df_fixdiplomats (color_ostream &out, vector<string> &parameters)
for (int j = 0; j < ent->positions.own.size(); j++) for (int j = 0; j < ent->positions.own.size(); j++)
{ {
pos = ent->positions.own[j]; pos = ent->positions.own[j];
if (pos->responsibilities[entity_position_responsibility::MAKE_INTRODUCTIONS] && if (pos->responsibilities[entity_position_responsibility::MAKE_INTRODUCTIONS] &&
pos->responsibilities[entity_position_responsibility::MAKE_PEACE_AGREEMENTS] && pos->responsibilities[entity_position_responsibility::MAKE_PEACE_AGREEMENTS] &&
pos->responsibilities[entity_position_responsibility::MAKE_TOPIC_AGREEMENTS]) pos->responsibilities[entity_position_responsibility::MAKE_TOPIC_AGREEMENTS])
{ {

@ -126,7 +126,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out )
Gui::setCursorCoords(c_x - (prevX-x), c_y - (prevY-y), z); Gui::setCursorCoords(c_x - (prevX-x), c_y - (prevY-y), z);
//Save this round's stuff for next time so we can monitor for changes made by the user //Save this round's stuff for next time so we can monitor for changes made by the user
prevX = x; prevX = x;
prevY = y; prevY = y;
prevZ = z; prevZ = z;
prevMenuWidth = menu_width; prevMenuWidth = menu_width;

@ -9,30 +9,30 @@ DFHACK_PLUGIN("fortplan");
command_result fortplan(color_ostream &out, vector<string> & params); command_result fortplan(color_ostream &out, vector<string> & params);
struct BuildingInfo { struct BuildingInfo {
std::string code; std::string code;
df::building_type type; df::building_type type;
df::furnace_type furnaceType; df::furnace_type furnaceType;
df::workshop_type workshopType; df::workshop_type workshopType;
df::trap_type trapType; df::trap_type trapType;
std::string name; std::string name;
bool variableSize; bool variableSize;
int defaultHeight; int defaultHeight;
int defaultWidth; int defaultWidth;
bool hasCustomOptions; bool hasCustomOptions;
BuildingInfo(std::string theCode, df::building_type theType, std::string theName, int height, int width) { BuildingInfo(std::string theCode, df::building_type theType, std::string theName, int height, int width) {
code = theCode; code = theCode;
type = theType; type = theType;
name = theName; name = theName;
variableSize = false; variableSize = false;
defaultHeight = height; defaultHeight = height;
defaultWidth = width; defaultWidth = width;
hasCustomOptions = false; hasCustomOptions = false;
} }
bool allocate() { bool allocate() {
return planner.allocatePlannedBuilding(type); return planner.allocatePlannedBuilding(type);
} }
}; };
class MatchesCode class MatchesCode
@ -54,34 +54,34 @@ DFhackCExport command_result plugin_init ( color_ostream &out, vector <PluginCom
commands.push_back(PluginCommand("fortplan","Lay out buildings in your fortress based on a Quickfort-style CSV input file.",fortplan,false, commands.push_back(PluginCommand("fortplan","Lay out buildings in your fortress based on a Quickfort-style CSV input file.",fortplan,false,
"Lay out buildings in your fortress based on a Quickfort-style CSV input file.\n" "Lay out buildings in your fortress based on a Quickfort-style CSV input file.\n"
"Usage: fortplan [filename]\n")); "Usage: fortplan [filename]\n"));
buildings.push_back(BuildingInfo("c",df::building_type::Chair,"Chair",1,1)); buildings.push_back(BuildingInfo("c",df::building_type::Chair,"Chair",1,1));
buildings.push_back(BuildingInfo("b",df::building_type::Bed,"Bed",1,1)); buildings.push_back(BuildingInfo("b",df::building_type::Bed,"Bed",1,1));
buildings.push_back(BuildingInfo("t",df::building_type::Table,"Table",1,1)); buildings.push_back(BuildingInfo("t",df::building_type::Table,"Table",1,1));
buildings.push_back(BuildingInfo("n",df::building_type::Coffin,"Coffin",1,1)); buildings.push_back(BuildingInfo("n",df::building_type::Coffin,"Coffin",1,1));
buildings.push_back(BuildingInfo("d",df::building_type::Door,"Door",1,1)); buildings.push_back(BuildingInfo("d",df::building_type::Door,"Door",1,1));
buildings.push_back(BuildingInfo("x",df::building_type::Floodgate,"Floodgate",1,1)); buildings.push_back(BuildingInfo("x",df::building_type::Floodgate,"Floodgate",1,1));
buildings.push_back(BuildingInfo("h",df::building_type::Box,"Box",1,1)); buildings.push_back(BuildingInfo("h",df::building_type::Box,"Box",1,1));
buildings.push_back(BuildingInfo("r",df::building_type::Weaponrack,"Weapon Rack",1,1)); buildings.push_back(BuildingInfo("r",df::building_type::Weaponrack,"Weapon Rack",1,1));
buildings.push_back(BuildingInfo("a",df::building_type::Armorstand,"Armor Stand",1,1)); buildings.push_back(BuildingInfo("a",df::building_type::Armorstand,"Armor Stand",1,1));
buildings.push_back(BuildingInfo("f",df::building_type::Cabinet,"Cabinet",1,1)); buildings.push_back(BuildingInfo("f",df::building_type::Cabinet,"Cabinet",1,1));
buildings.push_back(BuildingInfo("s",df::building_type::Statue,"Statue",1,1)); buildings.push_back(BuildingInfo("s",df::building_type::Statue,"Statue",1,1));
buildings.push_back(BuildingInfo("y",df::building_type::WindowGlass,"Glass Window",1,1)); buildings.push_back(BuildingInfo("y",df::building_type::WindowGlass,"Glass Window",1,1));
buildings.push_back(BuildingInfo("m",df::building_type::AnimalTrap,"Animal Trap",1,1)); buildings.push_back(BuildingInfo("m",df::building_type::AnimalTrap,"Animal Trap",1,1));
buildings.push_back(BuildingInfo("v",df::building_type::Chain,"Chain",1,1)); buildings.push_back(BuildingInfo("v",df::building_type::Chain,"Chain",1,1));
buildings.push_back(BuildingInfo("j",df::building_type::Cage,"Cage",1,1)); buildings.push_back(BuildingInfo("j",df::building_type::Cage,"Cage",1,1));
buildings.push_back(BuildingInfo("H",df::building_type::Hatch,"Floor Hatch",1,1)); buildings.push_back(BuildingInfo("H",df::building_type::Hatch,"Floor Hatch",1,1));
buildings.push_back(BuildingInfo("W",df::building_type::GrateWall,"Wall Grate",1,1)); buildings.push_back(BuildingInfo("W",df::building_type::GrateWall,"Wall Grate",1,1));
buildings.push_back(BuildingInfo("G",df::building_type::GrateFloor,"Floor Grate",1,1)); buildings.push_back(BuildingInfo("G",df::building_type::GrateFloor,"Floor Grate",1,1));
buildings.push_back(BuildingInfo("B",df::building_type::BarsVertical,"Vertical Bars",1,1)); buildings.push_back(BuildingInfo("B",df::building_type::BarsVertical,"Vertical Bars",1,1));
buildings.push_back(BuildingInfo("~b",df::building_type::BarsFloor,"Floor Bars",1,1)); buildings.push_back(BuildingInfo("~b",df::building_type::BarsFloor,"Floor Bars",1,1));
buildings.push_back(BuildingInfo("R",df::building_type::TractionBench,"Traction Bench",1,1)); buildings.push_back(BuildingInfo("R",df::building_type::TractionBench,"Traction Bench",1,1));
buildings.push_back(BuildingInfo("~s",df::building_type::Slab,"Slab",1,1)); buildings.push_back(BuildingInfo("~s",df::building_type::Slab,"Slab",1,1));
buildings.push_back(BuildingInfo("N",df::building_type::NestBox,"Nest Box",1,1)); buildings.push_back(BuildingInfo("N",df::building_type::NestBox,"Nest Box",1,1));
buildings.push_back(BuildingInfo("~h",df::building_type::Hive,"Hive",1,1)); buildings.push_back(BuildingInfo("~h",df::building_type::Hive,"Hive",1,1));
planner.initialize(); planner.initialize();
return CR_OK; return CR_OK;
} }
@ -116,260 +116,260 @@ DFhackCExport command_result plugin_enable(color_ostream &out, bool enable)
} }
std::vector<std::vector<std::string>> tokenizeFile(std::string filename) { std::vector<std::vector<std::string>> tokenizeFile(std::string filename) {
std::ifstream infile(filename.c_str()); std::ifstream infile(filename.c_str());
std::vector<std::vector<std::string>> fileTokens(128, std::vector<std::string>(128)); std::vector<std::vector<std::string>> fileTokens(128, std::vector<std::string>(128));
std::vector<std::vector<std::string>>::size_type x, y; std::vector<std::vector<std::string>>::size_type x, y;
if (!infile.good()) { if (!infile.good()) {
throw -1; throw -1;
} }
std::string line; std::string line;
y = 0; y = 0;
while (std::getline(infile, line)) { while (std::getline(infile, line)) {
x = 0; x = 0;
if (strcmp(line.substr(0,1).c_str(),"#")==0) { if (strcmp(line.substr(0,1).c_str(),"#")==0) {
fileTokens[y++][0] = line; fileTokens[y++][0] = line;
continue; continue;
} }
int start = 0; int start = 0;
auto nextInd = line.find(','); auto nextInd = line.find(',');
std::string curCell = line.substr(start,nextInd-start); std::string curCell = line.substr(start,nextInd-start);
do { do {
fileTokens[y][x] = curCell; fileTokens[y][x] = curCell;
start = nextInd+1; start = nextInd+1;
nextInd = line.find(',',start); nextInd = line.find(',',start);
curCell = line.substr(start,nextInd-start); curCell = line.substr(start,nextInd-start);
x++; x++;
} while (nextInd != line.npos); } while (nextInd != line.npos);
y++; y++;
} }
return fileTokens; return fileTokens;
} }
command_result fortplan(color_ostream &out, vector<string> & params) { command_result fortplan(color_ostream &out, vector<string> & params) {
auto & con = out; auto & con = out;
std::vector<std::vector<std::string>> layout(128, std::vector<std::string>(128)); std::vector<std::vector<std::string>> layout(128, std::vector<std::string>(128));
if (params.size()) { if (params.size()) {
coord32_t cursor; coord32_t cursor;
coord32_t userCursor; coord32_t userCursor;
coord32_t startCursor; coord32_t startCursor;
if (!DFHack::Gui::getCursorCoords(cursor.x, cursor.y, cursor.z)) { if (!DFHack::Gui::getCursorCoords(cursor.x, cursor.y, cursor.z)) {
con.print("You must have an active in-game cursor.\n"); con.print("You must have an active in-game cursor.\n");
return CR_FAILURE; return CR_FAILURE;
} }
DFHack::Gui::getCursorCoords(startCursor.x, startCursor.y, startCursor.z); DFHack::Gui::getCursorCoords(startCursor.x, startCursor.y, startCursor.z);
userCursor = startCursor; userCursor = startCursor;
std::string cwd = Filesystem::getcwd(); std::string cwd = Filesystem::getcwd();
std::string filename = cwd+"/"+params[0]; std::string filename = cwd+"/"+params[0];
con.print("Loading file '%s'...\n",filename.c_str()); con.print("Loading file '%s'...\n",filename.c_str());
try { try {
layout = tokenizeFile(filename); layout = tokenizeFile(filename);
} catch (int e) { } catch (int e) {
con.print("Could not open the file.\n"); con.print("Could not open the file.\n");
return CR_FAILURE; return CR_FAILURE;
} }
if (!is_enabled) { if (!is_enabled) {
plugin_enable(out, true); plugin_enable(out, true);
} }
con.print("Loaded.\n"); con.print("Loaded.\n");
std::vector<std::vector<std::string>>::size_type x, y; std::vector<std::vector<std::string>>::size_type x, y;
bool started = false; bool started = false;
for (y = 0; y < layout.size(); y++) { for (y = 0; y < layout.size(); y++) {
x = 0; x = 0;
auto hashBuild = layout[y][x].find("#build"); auto hashBuild = layout[y][x].find("#build");
if (hashBuild != layout[y][x].npos) { if (hashBuild != layout[y][x].npos) {
auto startLoc = layout[y][x].find("start("); auto startLoc = layout[y][x].find("start(");
if (startLoc != layout[y][x].npos) { if (startLoc != layout[y][x].npos) {
startLoc += 6; startLoc += 6;
auto nextDelimiter = layout[y][x].find(";",startLoc); auto nextDelimiter = layout[y][x].find(";",startLoc);
std::string startXStr = layout[y][x].substr(startLoc,nextDelimiter-startLoc); std::string startXStr = layout[y][x].substr(startLoc,nextDelimiter-startLoc);
int startXOffset = std::stoi(startXStr); int startXOffset = std::stoi(startXStr);
startLoc = nextDelimiter+1; startLoc = nextDelimiter+1;
nextDelimiter = layout[y][x].find(";",startLoc); nextDelimiter = layout[y][x].find(";",startLoc);
std::string startYStr = layout[y][x].substr(startLoc,nextDelimiter-startLoc); std::string startYStr = layout[y][x].substr(startLoc,nextDelimiter-startLoc);
int startYOffset = std::stoi(startYStr); int startYOffset = std::stoi(startYStr);
startCursor.x -= startXOffset; startCursor.x -= startXOffset;
startCursor.y -= startYOffset; startCursor.y -= startYOffset;
DFHack::Gui::setCursorCoords(startCursor.x,startCursor.y,startCursor.z); DFHack::Gui::setCursorCoords(startCursor.x,startCursor.y,startCursor.z);
started = true; started = true;
auto startEnd = layout[y][x].find(")",nextDelimiter); auto startEnd = layout[y][x].find(")",nextDelimiter);
con.print("Starting at (%d,%d,%d) which is described as: %s\n",startCursor.x,startCursor.y,startCursor.z,layout[y][x].substr(nextDelimiter+1,startEnd-nextDelimiter).c_str()); con.print("Starting at (%d,%d,%d) which is described as: %s\n",startCursor.x,startCursor.y,startCursor.z,layout[y][x].substr(nextDelimiter+1,startEnd-nextDelimiter).c_str());
std::string desc = layout[y][x].substr(startEnd+1); std::string desc = layout[y][x].substr(startEnd+1);
if (desc.size()>0) { if (desc.size()>0) {
con.print("Description of this plan: %s\n",desc.c_str()); con.print("Description of this plan: %s\n",desc.c_str());
} }
continue; continue;
} else { } else {
con.print("No start location found for this block\n"); con.print("No start location found for this block\n");
} }
} else if (!started) { } else if (!started) {
con.print("Not a build file: %s\n",layout[y][x].c_str()); con.print("Not a build file: %s\n",layout[y][x].c_str());
break; break;
} }
for (x = 0; x < layout[y].size(); x++) { for (x = 0; x < layout[y].size(); x++) {
if (strcmp(layout[y][x].substr(0,1).c_str(),"#")==0) { if (strcmp(layout[y][x].substr(0,1).c_str(),"#")==0) {
continue; continue;
} }
if (strcmp(layout[y][x].c_str(),"`")!=0) { if (strcmp(layout[y][x].c_str(),"`")!=0) {
auto dataIndex = layout[y][x].find("("); auto dataIndex = layout[y][x].find("(");
std::string curCode; std::string curCode;
std::vector<std::string> curData; std::vector<std::string> curData;
if (dataIndex != layout[y][x].npos) { if (dataIndex != layout[y][x].npos) {
curCode = layout[y][x].substr(0,dataIndex); curCode = layout[y][x].substr(0,dataIndex);
int dataStart = dataIndex+1; int dataStart = dataIndex+1;
auto nextDataStart = layout[y][x].find(",",dataStart); auto nextDataStart = layout[y][x].find(",",dataStart);
while (nextDataStart!=layout[y][x].npos) { while (nextDataStart!=layout[y][x].npos) {
std::string nextData = layout[y][x].substr(dataStart,nextDataStart); std::string nextData = layout[y][x].substr(dataStart,nextDataStart);
if (strcmp(nextData.substr(nextData.size()-1,1).c_str(),")")==0) { if (strcmp(nextData.substr(nextData.size()-1,1).c_str(),")")==0) {
nextData = nextData.substr(0,nextData.size()-1); nextData = nextData.substr(0,nextData.size()-1);
} }
curData.push_back(nextData); curData.push_back(nextData);
dataStart = nextDataStart+1; dataStart = nextDataStart+1;
nextDataStart = layout[y][x].find(",",dataStart); nextDataStart = layout[y][x].find(",",dataStart);
} }
} else { } else {
curCode = layout[y][x]; curCode = layout[y][x];
} }
//con.print("Found a cell with '%s' in it (layout[y][x] %d:%d-%d)\n",layout[y][x].c_str(),lineNum,start,nextInd); //con.print("Found a cell with '%s' in it (layout[y][x] %d:%d-%d)\n",layout[y][x].c_str(),lineNum,start,nextInd);
auto buildingIndex = std::find_if(buildings.begin(), buildings.end(), MatchesCode(curCode.c_str())); auto buildingIndex = std::find_if(buildings.begin(), buildings.end(), MatchesCode(curCode.c_str()));
// = std::find(validInstructions.begin(), validInstructions.end(), layout[y][x]); // = std::find(validInstructions.begin(), validInstructions.end(), layout[y][x]);
if(buildingIndex == buildings.end()) { if(buildingIndex == buildings.end()) {
//con.print("That is not a valid code.\n"); //con.print("That is not a valid code.\n");
} else { } else {
//con.print("I can build that!\n"); //con.print("I can build that!\n");
BuildingInfo buildingInfo = *buildingIndex; BuildingInfo buildingInfo = *buildingIndex;
if (buildingInfo.variableSize || buildingInfo.defaultHeight > 1 || buildingInfo.defaultWidth > 1) { if (buildingInfo.variableSize || buildingInfo.defaultHeight > 1 || buildingInfo.defaultWidth > 1) {
//con.print("Found a building at (%d,%d) called %s, which has a size %dx%d or variable size\n",x,y,buildingInfo.name.c_str(),buildingInfo.defaultWidth, buildingInfo.defaultHeight); //con.print("Found a building at (%d,%d) called %s, which has a size %dx%d or variable size\n",x,y,buildingInfo.name.c_str(),buildingInfo.defaultWidth, buildingInfo.defaultHeight);
// TODO: Make this function smarter, able to determine the exact shape // TODO: Make this function smarter, able to determine the exact shape
// and location of the building // and location of the building
// For now, we just assume that we are always looking at the top left // For now, we just assume that we are always looking at the top left
// corner of where it is located in the input file // corner of where it is located in the input file
coord32_t buildingSize; coord32_t buildingSize;
if (!buildingInfo.variableSize) { if (!buildingInfo.variableSize) {
bool single = true; bool single = true;
bool block = true; bool block = true;
std::vector<std::vector<std::string>>::size_type checkX, checkY; std::vector<std::vector<std::string>>::size_type checkX, checkY;
int yOffset = ((buildingInfo.defaultHeight-1)/2); int yOffset = ((buildingInfo.defaultHeight-1)/2);
int xOffset = ((buildingInfo.defaultWidth-1)/2); int xOffset = ((buildingInfo.defaultWidth-1)/2);
//con.print(" - Checking to see if it's a single, with %d<=x<%d and %d<=y<%d...\n",x-xOffset,x+xOffset,y-yOffset,y+yOffset); //con.print(" - Checking to see if it's a single, with %d<=x<%d and %d<=y<%d...\n",x-xOffset,x+xOffset,y-yOffset,y+yOffset);
// First, check to see if this is in the center of an empty square of its default size // First, check to see if this is in the center of an empty square of its default size
for (checkY = y-yOffset; checkY <= (y+yOffset); checkY++) { for (checkY = y-yOffset; checkY <= (y+yOffset); checkY++) {
for (checkX = x-xOffset; checkX <= (x+xOffset); checkX++) { for (checkX = x-xOffset; checkX <= (x+xOffset); checkX++) {
if (checkX==x && checkY==y) { if (checkX==x && checkY==y) {
continue; continue;
} }
auto checkDataIndex = layout[checkY][checkX].find("("); auto checkDataIndex = layout[checkY][checkX].find("(");
std::string checkCode; std::string checkCode;
if (checkDataIndex != layout[checkY][checkX].npos) { if (checkDataIndex != layout[checkY][checkX].npos) {
checkCode = layout[checkY][checkX].substr(0,checkDataIndex); checkCode = layout[checkY][checkX].substr(0,checkDataIndex);
} else { } else {
checkCode = layout[checkY][checkX]; checkCode = layout[checkY][checkX];
} }
con.print(" - Code at (%d,%d) is '%s': ",checkX,checkY,checkCode.c_str()); con.print(" - Code at (%d,%d) is '%s': ",checkX,checkY,checkCode.c_str());
auto checkIndex = std::find_if(buildings.begin(), buildings.end(), MatchesCode(checkCode.c_str())); auto checkIndex = std::find_if(buildings.begin(), buildings.end(), MatchesCode(checkCode.c_str()));
//if (checkIndex == buildings.end()) { //if (checkIndex == buildings.end()) {
// con.print("this is not a valid code, so we keep going.\n"); // con.print("this is not a valid code, so we keep going.\n");
// continue; // continue;
//} //}
//if (curCode.compare(layout[checkY][checkX]) != 0) { //if (curCode.compare(layout[checkY][checkX]) != 0) {
if (checkIndex != buildings.end()) { if (checkIndex != buildings.end()) {
//con.print("this is a building, so we break.\n"); //con.print("this is a building, so we break.\n");
single = false; single = false;
break; break;
} else { } else {
//con.print("this is not a building, so we keep going.\n"); //con.print("this is not a building, so we keep going.\n");
} }
} }
if (!single) { if (!single) {
//con.print("Not a single. Moving forward.\n"); //con.print("Not a single. Moving forward.\n");
break; break;
} }
} }
if (!single) { if (!single) {
// If that's not the case, check to see if this is the top-left corner of // If that's not the case, check to see if this is the top-left corner of
// a square of its default size // a square of its default size
//con.print(" - It's not single; checking to see if it's a block...\n"); //con.print(" - It's not single; checking to see if it's a block...\n");
for (checkY = y; checkY < (y+buildingInfo.defaultHeight); checkY++) { for (checkY = y; checkY < (y+buildingInfo.defaultHeight); checkY++) {
for (checkX = x; checkX < (x+buildingInfo.defaultWidth); checkX++) { for (checkX = x; checkX < (x+buildingInfo.defaultWidth); checkX++) {
if (checkX==x && checkY==y) { if (checkX==x && checkY==y) {
continue; continue;
} }
auto checkDataIndex = layout[checkY][checkX].find("("); auto checkDataIndex = layout[checkY][checkX].find("(");
std::string checkCode; std::string checkCode;
if (checkDataIndex != layout[checkY][checkX].npos) { if (checkDataIndex != layout[checkY][checkX].npos) {
checkCode = layout[checkY][checkX].substr(0,checkDataIndex); checkCode = layout[checkY][checkX].substr(0,checkDataIndex);
} else { } else {
checkCode = layout[checkY][checkX]; checkCode = layout[checkY][checkX];
} }
//con.print(" - Code at (%d,%d) is '%s': ",checkX,checkY,checkCode.c_str()); //con.print(" - Code at (%d,%d) is '%s': ",checkX,checkY,checkCode.c_str());
if (curCode.compare(checkCode) != 0) { if (curCode.compare(checkCode) != 0) {
//con.print("this is not the same as '%s', so we break.\n",curCode.c_str()); //con.print("this is not the same as '%s', so we break.\n",curCode.c_str());
block = false; block = false;
break; break;
} else { } else {
//con.print("this is the same as '%s', so we erase it and move on.\n",curCode.c_str()); //con.print("this is the same as '%s', so we erase it and move on.\n",curCode.c_str());
layout[checkY][checkX] = "``"; layout[checkY][checkX] = "``";
} }
} }
if (!block) { if (!block) {
//con.print("Not a block. Moving forward.\n"); //con.print("Not a block. Moving forward.\n");
break; break;
} }
} }
} }
if (single) { if (single) {
//con.print("Placing a building with code '%s' centered at (%d,%d) and default size %dx%d.\n",curCode.c_str(),x,y,buildingInfo.defaultWidth,buildingInfo.defaultHeight); //con.print("Placing a building with code '%s' centered at (%d,%d) and default size %dx%d.\n",curCode.c_str(),x,y,buildingInfo.defaultWidth,buildingInfo.defaultHeight);
coord32_t offsetCursor = cursor; coord32_t offsetCursor = cursor;
offsetCursor.x -= xOffset; offsetCursor.x -= xOffset;
offsetCursor.y -= yOffset; offsetCursor.y -= yOffset;
DFHack::Gui::setCursorCoords(offsetCursor.x, offsetCursor.y, offsetCursor.z); DFHack::Gui::setCursorCoords(offsetCursor.x, offsetCursor.y, offsetCursor.z);
if (!buildingInfo.allocate()) { if (!buildingInfo.allocate()) {
con.print("*** There was an error placing building with code '%s' centered at (%d,%d).\n",curCode.c_str(),x,y); con.print("*** There was an error placing building with code '%s' centered at (%d,%d).\n",curCode.c_str(),x,y);
} }
DFHack::Gui::setCursorCoords(cursor.x, cursor.y, cursor.z); DFHack::Gui::setCursorCoords(cursor.x, cursor.y, cursor.z);
} else if (block) { } else if (block) {
//con.print("Placing a building with code '%s' with corner at (%d,%d) and default size %dx%d.\n",curCode.c_str(),x,y,buildingInfo.defaultWidth,buildingInfo.defaultHeight); //con.print("Placing a building with code '%s' with corner at (%d,%d) and default size %dx%d.\n",curCode.c_str(),x,y,buildingInfo.defaultWidth,buildingInfo.defaultHeight);
if (!buildingInfo.allocate()) { if (!buildingInfo.allocate()) {
con.print("*** There was an error placing building with code '%s' with corner at (%d,%d).\n",curCode.c_str(),x,y); con.print("*** There was an error placing building with code '%s' with corner at (%d,%d).\n",curCode.c_str(),x,y);
} }
} else { } else {
con.print("*** Found a code '%s' at (%d,%d) for a building with default size %dx%d with an invalid size designation.\n",curCode.c_str(),x,y,buildingInfo.defaultWidth,buildingInfo.defaultHeight); con.print("*** Found a code '%s' at (%d,%d) for a building with default size %dx%d with an invalid size designation.\n",curCode.c_str(),x,y,buildingInfo.defaultWidth,buildingInfo.defaultHeight);
} }
} else { } else {
//buildingSize = findBuildingExtent(layout, x, y, -1, -1, out); //buildingSize = findBuildingExtent(layout, x, y, -1, -1, out);
//con.print(" - The building has variable size %dx%d\n",buildingSize.x, buildingSize.y); //con.print(" - The building has variable size %dx%d\n",buildingSize.x, buildingSize.y);
//con.print(" - The building has a variable size, which is not yet handled.\n"); //con.print(" - The building has a variable size, which is not yet handled.\n");
} }
} else { } else {
//con.print("Building a(n) %s.\n",buildingInfo.name.c_str()); //con.print("Building a(n) %s.\n",buildingInfo.name.c_str());
if (!buildingInfo.allocate()) { if (!buildingInfo.allocate()) {
con.print("*** There was an error placing the %s at (%d,%d).\n",buildingInfo.name.c_str(),x,y); con.print("*** There was an error placing the %s at (%d,%d).\n",buildingInfo.name.c_str(),x,y);
} }
} }
} }
} }
cursor.x++; cursor.x++;
DFHack::Gui::setCursorCoords(cursor.x, cursor.y, cursor.z); DFHack::Gui::setCursorCoords(cursor.x, cursor.y, cursor.z);
} }
cursor.y++; cursor.y++;
cursor.x = startCursor.x; cursor.x = startCursor.x;
} }
DFHack::Gui::setCursorCoords(userCursor.x, userCursor.y, userCursor.z); DFHack::Gui::setCursorCoords(userCursor.x, userCursor.y, userCursor.z);
con.print("Done with file.\n"); con.print("Done with file.\n");
} else { } else {
con.print("You must supply a filename to read.\n"); con.print("You must supply a filename to read.\n");
} }
return CR_OK; return CR_OK;
} }

@ -108,7 +108,7 @@ static bool close_hotkeys_screen()
return false; return false;
Screen::dismiss(Core::getTopViewscreen()); Screen::dismiss(Core::getTopViewscreen());
for_each_(sorted_keys, [] (const string &sym) for_each_(sorted_keys, [] (const string &sym)
{ Core::getInstance().ClearKeyBindings(sym + "@dfhack/viewscreen_hotkeys"); }); { Core::getInstance().ClearKeyBindings(sym + "@dfhack/viewscreen_hotkeys"); });
sorted_keys.clear(); sorted_keys.clear();
return true; return true;
@ -147,7 +147,7 @@ public:
hotkeys_column.clear(); hotkeys_column.clear();
int max_key_length = 0; int max_key_length = 0;
for_each_(sorted_keys, [&] (const string &sym) for_each_(sorted_keys, [&] (const string &sym)
{ if (sym.length() > max_key_length) { max_key_length = sym.length(); } }); { if (sym.length() > max_key_length) { max_key_length = sym.length(); } });
int padding = max_key_length + 2; int padding = max_key_length + 2;
@ -200,7 +200,7 @@ public:
x += 3; x += 3;
OutputHotkeyString(x, y, "Invoke", "Enter or Hotkey"); OutputHotkeyString(x, y, "Invoke", "Enter or Hotkey");
x += 3; x += 3;
OutputToggleString(x, y, "Show Usage", "u", show_usage); OutputToggleString(x, y, "Show Usage", "u", show_usage);
@ -255,7 +255,7 @@ public:
} }
} }
virtual std::string getFocusString() virtual std::string getFocusString()
{ {
return "viewscreen_hotkeys"; return "viewscreen_hotkeys";
} }

@ -31,9 +31,9 @@ command_result infiniteSky (color_ostream &out, std::vector <std::string> & para
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{ {
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"infiniteSky", "infiniteSky",
"Creates new sky levels on request, or as you construct up.", "Creates new sky levels on request, or as you construct up.",
infiniteSky, false, infiniteSky, false,
"Usage:\n" "Usage:\n"
" infiniteSky\n" " infiniteSky\n"
" creates one more z-level\n" " creates one more z-level\n"
@ -88,7 +88,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out )
if ( mode.g_mode != df::enums::game_mode::DWARF ) if ( mode.g_mode != df::enums::game_mode::DWARF )
return CR_OK; return CR_OK;
} }
if ( world->constructions.size() == constructionSize ) if ( world->constructions.size() == constructionSize )
return CR_OK; return CR_OK;
int32_t zNow = world->map.z_count_block; int32_t zNow = world->map.z_count_block;
@ -101,7 +101,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out )
///break; ///break;
} }
constructionSize = world->constructions.size(); constructionSize = world->constructions.size();
return CR_OK; return CR_OK;
} }
@ -152,7 +152,7 @@ void doInfiniteSky(color_ostream& out, int32_t howMany) {
delete[] world->map_extras.z_level_flags; delete[] world->map_extras.z_level_flags;
world->map_extras.z_level_flags = flags; world->map_extras.z_level_flags = flags;
} }
} }
DFhackCExport command_result plugin_enable(color_ostream &out, bool enable) DFhackCExport command_result plugin_enable(color_ostream &out, bool enable)

@ -1 +1 @@
Subproject commit 07750ad7f7ce7c2506e5198ffb80ca50a73e9c4e Subproject commit 85dcde97197bdde1c1e97ccb536f2cc4cab6818f

@ -130,39 +130,39 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out )
// CoreSuspender suspend; // CoreSuspender suspend;
// // Actually do something here. Yay. // // Actually do something here. Yay.
// out.print("Doing a test...\n"); // out.print("Doing a test...\n");
// MapExtras::MapCache MC; // MapExtras::MapCache MC;
// EmbarkTile test_tile; // EmbarkTile test_tile;
// if(!gather_embark_tile(0,0, &test_tile, &MC)) // if(!gather_embark_tile(0,0, &test_tile, &MC))
// return CR_FAILURE; // return CR_FAILURE;
// //test-write the file to check it. // //test-write the file to check it.
// std::ofstream output_file("tile.p", std::ios_base::binary); // std::ofstream output_file("tile.p", std::ios_base::binary);
// output_file << test_tile.SerializeAsString(); // output_file << test_tile.SerializeAsString();
// output_file.close(); // output_file.close();
// //
// //load it again to verify. // //load it again to verify.
// std::ifstream input_file("tile.p", std::ios_base::binary); // std::ifstream input_file("tile.p", std::ios_base::binary);
// std::string input_string( (std::istreambuf_iterator<char>(input_file) ), // std::string input_string( (std::istreambuf_iterator<char>(input_file) ),
// (std::istreambuf_iterator<char>() ) ); // (std::istreambuf_iterator<char>() ) );
// EmbarkTile verify_tile; // EmbarkTile verify_tile;
// verify_tile.ParseFromString(input_string); // verify_tile.ParseFromString(input_string);
// //write contents to text file. // //write contents to text file.
// std::ofstream debug_text("tile.txt", std::ios_base::trunc); // std::ofstream debug_text("tile.txt", std::ios_base::trunc);
// debug_text << "world coords:" << verify_tile.world_x()<< "," << verify_tile.world_y()<< "," << verify_tile.world_z() << std::endl; // debug_text << "world coords:" << verify_tile.world_x()<< "," << verify_tile.world_y()<< "," << verify_tile.world_z() << std::endl;
// for(int i = 0; i < verify_tile.tile_layer_size(); i++) { // for(int i = 0; i < verify_tile.tile_layer_size(); i++) {
// debug_text << "layer: " << i << std::endl; // debug_text << "layer: " << i << std::endl;
// for(int j = 0; j < 48; j++) { // for(int j = 0; j < 48; j++) {
// debug_text << " "; // debug_text << " ";
// for(int k = 0; k < 48; k++) { // for(int k = 0; k < 48; k++) {
// debug_text << verify_tile.tile_layer(i).mat_type_table(j*48+k) << ","; // debug_text << verify_tile.tile_layer(i).mat_type_table(j*48+k) << ",";
// } // }
// debug_text << " "; // debug_text << " ";
// for(int k = 0; k < 48; k++) { // for(int k = 0; k < 48; k++) {
// debug_text << std::setw(3) << verify_tile.tile_layer(i).mat_subtype_table(j*48+k) << ","; // debug_text << std::setw(3) << verify_tile.tile_layer(i).mat_subtype_table(j*48+k) << ",";
// } // }
// debug_text << std::endl; // debug_text << std::endl;
// } // }
// debug_text << std::endl; // debug_text << std::endl;
// } // }
// // Give control back to DF. // // Give control back to DF.
// return CR_OK; // return CR_OK;
//} //}
@ -197,12 +197,12 @@ static command_result GetEmbarkInfo(color_ostream &stream, const MapRequest *in,
out->set_available(false); out->set_available(false);
return CR_OK; return CR_OK;
} }
if (in->has_save_folder()) { //If no save folder is given, it means we don't care. if (in->has_save_folder()) { //If no save folder is given, it means we don't care.
if (!(in->save_folder() == world->cur_savegame.save_dir || in->save_folder() == "ANY")) { //isoworld has a different map loaded, don't bother trying to load tiles for it, we don't have them. if (!(in->save_folder() == world->cur_savegame.save_dir || in->save_folder() == "ANY")) { //isoworld has a different map loaded, don't bother trying to load tiles for it, we don't have them.
out->set_available(false); out->set_available(false);
return CR_OK; return CR_OK;
} }
} }
out->set_available(true); out->set_available(true);
out->set_current_year(*cur_year); out->set_current_year(*cur_year);
out->set_current_season(*cur_season); out->set_current_season(*cur_season);
@ -219,8 +219,8 @@ int coord_to_index_48(int x, int y) {
bool gather_embark_tile(int EmbX, int EmbY, EmbarkTile * tile, MapExtras::MapCache * MP) { bool gather_embark_tile(int EmbX, int EmbY, EmbarkTile * tile, MapExtras::MapCache * MP) {
tile->set_is_valid(false); tile->set_is_valid(false);
tile->set_world_x(world->map.region_x + (EmbX/3)); tile->set_world_x(world->map.region_x + (EmbX/3));
tile->set_world_y(world->map.region_y + (EmbY/3)); tile->set_world_y(world->map.region_y + (EmbY/3));
tile->set_world_z(world->map.region_z + 1); //adding one because floors get shifted one downwards. tile->set_world_z(world->map.region_z + 1); //adding one because floors get shifted one downwards.
tile->set_current_year(*cur_year); tile->set_current_year(*cur_year);
tile->set_current_season(*cur_season); tile->set_current_season(*cur_season);
@ -245,7 +245,7 @@ bool gather_embark_tile_layer(int EmbX, int EmbY, int EmbZ, EmbarkTileLayer * ti
int num_valid_blocks = 0; int num_valid_blocks = 0;
for(int yy = 0; yy < 3; yy++) { for(int yy = 0; yy < 3; yy++) {
for(int xx = 0; xx < 3; xx++) { for(int xx = 0; xx < 3; xx++) {
DFCoord current_coord, upper_coord; DFCoord current_coord, upper_coord;
current_coord.x = EmbX+xx; current_coord.x = EmbX+xx;
current_coord.y = EmbY+yy; current_coord.y = EmbY+yy;
current_coord.z = EmbZ; current_coord.z = EmbZ;
@ -283,7 +283,7 @@ bool gather_embark_tile_layer(int EmbX, int EmbY, int EmbZ, EmbarkTileLayer * ti
num_valid_blocks++; num_valid_blocks++;
} }
else if(designation.bits.flow_size && (tileShapeBasic(tileShape(upper_tile)) != tiletype_shape_basic::Floor)) { //Contains either water or lava. else if(designation.bits.flow_size && (tileShapeBasic(tileShape(upper_tile)) != tiletype_shape_basic::Floor)) { //Contains either water or lava.
tile->set_mat_type_table(array_index, BasicMaterial::LIQUID); tile->set_mat_type_table(array_index, BasicMaterial::LIQUID);
if(designation.bits.liquid_type) //Magma if(designation.bits.liquid_type) //Magma
tile->set_mat_subtype_table(array_index, LiquidType::MAGMA); tile->set_mat_subtype_table(array_index, LiquidType::MAGMA);
else //water else //water
@ -291,29 +291,29 @@ bool gather_embark_tile_layer(int EmbX, int EmbY, int EmbZ, EmbarkTileLayer * ti
num_valid_blocks++; num_valid_blocks++;
} }
else if(((tileShapeBasic(tileShape(tile_type)) != tiletype_shape_basic::Open) || else if(((tileShapeBasic(tileShape(tile_type)) != tiletype_shape_basic::Open) ||
(tileShapeBasic(tileShape(upper_tile)) == tiletype_shape_basic::Floor)) && (tileShapeBasic(tileShape(upper_tile)) == tiletype_shape_basic::Floor)) &&
((tileShapeBasic(tileShape(tile_type)) != tiletype_shape_basic::Floor) || ((tileShapeBasic(tileShape(tile_type)) != tiletype_shape_basic::Floor) ||
(tileShapeBasic(tileShape(upper_tile)) == tiletype_shape_basic::Floor))) { //if the upper tile is a floor, we don't skip, otherwise we do. (tileShapeBasic(tileShape(upper_tile)) == tiletype_shape_basic::Floor))) { //if the upper tile is a floor, we don't skip, otherwise we do.
if(actual_mat.mat_type == builtin_mats::INORGANIC) { //inorganic if(actual_mat.mat_type == builtin_mats::INORGANIC) { //inorganic
tile->set_mat_type_table(array_index, BasicMaterial::INORGANIC); tile->set_mat_type_table(array_index, BasicMaterial::INORGANIC);
tile->set_mat_subtype_table(array_index, actual_mat.mat_index); tile->set_mat_subtype_table(array_index, actual_mat.mat_index);
} }
else if(actual_mat.mat_type == 419) { //Growing plants else if(actual_mat.mat_type == 419) { //Growing plants
tile->set_mat_type_table(array_index, BasicMaterial::PLANT); tile->set_mat_type_table(array_index, BasicMaterial::PLANT);
tile->set_mat_subtype_table(array_index, actual_mat.mat_index); tile->set_mat_subtype_table(array_index, actual_mat.mat_index);
} }
else if(actual_mat.mat_type >= 420) { //Wooden constructions. Different from growing plants. else if(actual_mat.mat_type >= 420) { //Wooden constructions. Different from growing plants.
tile->set_mat_type_table(array_index, BasicMaterial::WOOD); tile->set_mat_type_table(array_index, BasicMaterial::WOOD);
tile->set_mat_subtype_table(array_index, actual_mat.mat_index); tile->set_mat_subtype_table(array_index, actual_mat.mat_index);
} }
else { //Unknown and unsupported stuff. Will just be drawn as grey. else { //Unknown and unsupported stuff. Will just be drawn as grey.
tile->set_mat_type_table(array_index, BasicMaterial::OTHER); tile->set_mat_type_table(array_index, BasicMaterial::OTHER);
tile->set_mat_subtype_table(array_index, actual_mat.mat_type); tile->set_mat_subtype_table(array_index, actual_mat.mat_type);
} }
num_valid_blocks++; num_valid_blocks++;
} }
else { else {
tile->set_mat_type_table(array_index, BasicMaterial::AIR); tile->set_mat_type_table(array_index, BasicMaterial::AIR);
} }
} }
} }
@ -344,12 +344,12 @@ static command_result GetRawNames(color_ostream &stream, const MapRequest *in, R
out->set_available(false); out->set_available(false);
return CR_OK; return CR_OK;
} }
if (in->has_save_folder()) { //If no save folder is given, it means we don't care. if (in->has_save_folder()) { //If no save folder is given, it means we don't care.
if (!(in->save_folder() == world->cur_savegame.save_dir || in->save_folder() == "ANY")) { //isoworld has a different map loaded, don't bother trying to load tiles for it, we don't have them. if (!(in->save_folder() == world->cur_savegame.save_dir || in->save_folder() == "ANY")) { //isoworld has a different map loaded, don't bother trying to load tiles for it, we don't have them.
out->set_available(false); out->set_available(false);
return CR_OK; return CR_OK;
} }
} }
out->set_available(true); out->set_available(true);
for(int i = 0; i < world->raws.inorganics.size(); i++){ for(int i = 0; i < world->raws.inorganics.size(); i++){
out->add_inorganic(world->raws.inorganics[i]->id); out->add_inorganic(world->raws.inorganics[i]->id);

@ -611,7 +611,7 @@ command_result df_liquids_execute(color_ostream &out, OperationMode &cur_mode, d
case M_KEEP: case M_KEEP:
{ {
auto bflags = (*biter)->BlockFlags(); auto bflags = (*biter)->BlockFlags();
out << "flow bit 1 = " << bflags.bits.update_liquid << endl; out << "flow bit 1 = " << bflags.bits.update_liquid << endl;
out << "flow bit 2 = " << bflags.bits.update_liquid_twice << endl; out << "flow bit 2 = " << bflags.bits.update_liquid_twice << endl;
} }
} }

@ -1,24 +1,24 @@
local _ENV = mkmodule('plugins.building-hacks') local _ENV = mkmodule('plugins.building-hacks')
--[[ --[[
from native: from native:
addBuilding(custom type,impassible fix (bool), consumed power, produced power, list of connection points, addBuilding(custom type,impassible fix (bool), consumed power, produced power, list of connection points,
update skip(0/nil to disable),table of frames,frame to tick ratio (-1 for machine control)) update skip(0/nil to disable),table of frames,frame to tick ratio (-1 for machine control))
from here: from here:
registerBuilding{ registerBuilding{
name -- custom workshop id e.g. SOAPMAKER << required! name -- custom workshop id e.g. SOAPMAKER << required!
fix_impassible -- make impassible tiles impassible to liquids too fix_impassible -- make impassible tiles impassible to liquids too
consume -- how much machine power is needed to work consume -- how much machine power is needed to work
produce -- how much machine power is produced produce -- how much machine power is produced
gears -- a table or {x=?,y=?} of connection points for machines gears -- a table or {x=?,y=?} of connection points for machines
action -- a table of number (how much ticks to skip) and a function which gets called on shop update action -- a table of number (how much ticks to skip) and a function which gets called on shop update
animate -- a table of animate -- a table of
frames -- a table of frames -- a table of
tables of 4 numbers (tile,fore,back,bright) OR tables of 4 numbers (tile,fore,back,bright) OR
empty table (tile not modified) OR empty table (tile not modified) OR
{x=<number> y=<number> + 4 numbers like in first case} -- this generates full frame even, usefull for animations that change little (1-2 tiles) {x=<number> y=<number> + 4 numbers like in first case} -- this generates full frame even, usefull for animations that change little (1-2 tiles)
frameLenght -- how many ticks does one frame take OR frameLenght -- how many ticks does one frame take OR
isMechanical -- a bool that says to try to match to mechanical system (i.e. how gears are turning) isMechanical -- a bool that says to try to match to mechanical system (i.e. how gears are turning)
} }
]] ]]
_registeredStuff={} _registeredStuff={}
local function unregall(state) local function unregall(state)
@ -29,23 +29,23 @@ local function unregall(state)
end end
end end
local function onUpdateLocal(workshop) local function onUpdateLocal(workshop)
local f=_registeredStuff[workshop:getCustomType()] local f=_registeredStuff[workshop:getCustomType()]
if f then if f then
f(workshop) f(workshop)
end end
end end
local function findCustomWorkshop(name) local function findCustomWorkshop(name)
local raws=df.global.world.raws.buildings.all local raws=df.global.world.raws.buildings.all
for k,v in ipairs(raws) do for k,v in ipairs(raws) do
if v.code==name then if v.code==name then
return v return v
end end
end end
end end
local function registerUpdateAction(shopId,callback) local function registerUpdateAction(shopId,callback)
_registeredStuff[shopId]=callback _registeredStuff[shopId]=callback
onUpdateAction._library=onUpdateLocal onUpdateAction._library=onUpdateLocal
dfhack.onStateChange.building_hacks=unregall dfhack.onStateChange.building_hacks=unregall
end end
local function generateFrame(tiles,w,h) local function generateFrame(tiles,w,h)
local mTiles={} local mTiles={}
@ -66,7 +66,7 @@ local function generateFrame(tiles,w,h)
return ret return ret
end end
local function processFrames(shop_def,frames) local function processFrames(shop_def,frames)
local w,h=shop_def.dim_x,shop_def.dim_y local w,h=shop_def.dim_x,shop_def.dim_y
for frame_id,frame in ipairs(frames) do for frame_id,frame in ipairs(frames) do
if frame[1].x~=nil then if frame[1].x~=nil then
frames[frame_id]=generateFrame(frame,w,h) frames[frame_id]=generateFrame(frame,w,h)
@ -75,35 +75,35 @@ local function processFrames(shop_def,frames)
return frames return frames
end end
function registerBuilding(args) function registerBuilding(args)
local shop_def=findCustomWorkshop(args.name) local shop_def=findCustomWorkshop(args.name)
local shop_id=shop_def.id local shop_id=shop_def.id
local fix_impassible local fix_impassible
if args.fix_impassible then if args.fix_impassible then
fix_impassible=1 fix_impassible=1
else else
fix_impassible=0 fix_impassible=0
end end
local consume=args.consume or 0 local consume=args.consume or 0
local produce=args.produce or 0 local produce=args.produce or 0
local gears=args.gears or {} local gears=args.gears or {}
local action=args.action --could be nil local action=args.action --could be nil
local updateSkip=0 local updateSkip=0
if action~=nil then if action~=nil then
updateSkip=action[1] updateSkip=action[1]
registerUpdateAction(shop_id,action[2]) registerUpdateAction(shop_id,action[2])
end end
local animate=args.animate local animate=args.animate
local frameLength=1 local frameLength=1
local frames local frames
if animate~=nil then if animate~=nil then
frameLength=animate.frameLength frameLength=animate.frameLength
if animate.isMechanical then if animate.isMechanical then
frameLength=-1 frameLength=-1
end end
frames=processFrames(shop_def,animate.frames) frames=processFrames(shop_def,animate.frames)
end end
local roomSubset=args.canBeRoomSubset or -1 local roomSubset=args.canBeRoomSubset or -1
addBuilding(shop_id,fix_impassible,consume,produce,gears,updateSkip,frames,frameLength,roomSubset) addBuilding(shop_id,fix_impassible,consume,produce,gears,updateSkip,frames,frameLength,roomSubset)
end end
return _ENV return _ENV

@ -54,7 +54,7 @@ function BinaryPatch:apply()
if not self:test() then if not self:test() then
error(string.format("pre-data for binary patch does not match expected")) error(string.format("pre-data for binary patch does not match expected"))
end end
local post_buf=df.new('uint8_t',#self.pre_data) local post_buf=df.new('uint8_t',#self.pre_data)
for k,v in ipairs(self.pre_data) do for k,v in ipairs(self.pre_data) do
if self.data[k]==nil then if self.data[k]==nil then
@ -83,7 +83,7 @@ function BinaryPatch:remove(delete)
error("can't remove BinaryPatch, not applied.") error("can't remove BinaryPatch, not applied.")
end end
local arr=ms.CheckedArray.new('uint8_t',self.address,self.address+#self.pre_data) local arr=ms.CheckedArray.new('uint8_t',self.address,self.address+#self.pre_data)
local post_buf=df.new('uint8_t',#self.pre_data) local post_buf=df.new('uint8_t',#self.pre_data)
for k,v in pairs(self.pre_data) do for k,v in pairs(self.pre_data) do
post_buf[k-1]=v post_buf[k-1]=v
@ -112,7 +112,7 @@ plugins=plugins or {}
BinaryPlugin=defclass(BinaryPlugin) BinaryPlugin=defclass(BinaryPlugin)
BinaryPlugin.ATTRS {filename=DEFAULT_NIL,reloc_table={},name=DEFAULT_NIL} BinaryPlugin.ATTRS {filename=DEFAULT_NIL,reloc_table={},name=DEFAULT_NIL}
function BinaryPlugin:init(args) function BinaryPlugin:init(args)
end end
function BinaryPlugin:postinit(args) function BinaryPlugin:postinit(args)
if self.name==nil then error("Not a valid plugin name!") end if self.name==nil then error("Not a valid plugin name!") end
@ -211,26 +211,26 @@ function SimpleMenu:init(args)
self.items={} self.items={}
end end
function SimpleMenu:add(name,entry,hints) function SimpleMenu:add(name,entry,hints)
table.insert(self.items,{entry,name,hints}) table.insert(self.items,{entry,name,hints})
end end
function SimpleMenu:display() function SimpleMenu:display()
print("Select choice (q exits):") print("Select choice (q exits):")
for p,c in pairs(self.items) do for p,c in pairs(self.items) do
print(string.format("%3d).%s",p,c[2])) print(string.format("%3d).%s",p,c[2]))
end end
local ans local ans
repeat repeat
local r local r
r=dfhack.lineedit() r=dfhack.lineedit()
if r==nil then return end if r==nil then return end
if r=='q' then return end if r=='q' then return end
ans=tonumber(r) ans=tonumber(r)
if ans==nil or not(ans<=#self.items and ans>0) then if ans==nil or not(ans<=#self.items and ans>0) then
print("Invalid choice.") print("Invalid choice.")
end end
until ans~=nil and (ans<=#self.items and ans>0) until ans~=nil and (ans<=#self.items and ans>0)
if type(self.items[ans][1])=="function" then if type(self.items[ans][1])=="function" then
self.items[ans][1]() self.items[ans][1]()
else else

@ -3,99 +3,99 @@ local dfu=require("plugins.dfusion")
local tools=require("plugins.dfusion.tools") local tools=require("plugins.dfusion.tools")
menu=dfu.SimpleMenu() menu=dfu.SimpleMenu()
function Reincarnate(trg_unit,swap_soul) --only for adventurer i guess function Reincarnate(trg_unit,swap_soul) --only for adventurer i guess
if swap_soul==nil then if swap_soul==nil then
swap_soul=true swap_soul=true
end end
local adv=trg_unit or df.global.world.units.active[0] local adv=trg_unit or df.global.world.units.active[0]
if adv.flags1.dead==false then if adv.flags1.dead==false then
qerror("You are not dead (yet)!") qerror("You are not dead (yet)!")
end end
local hist_fig=dfhack.units.getNemesis(adv).figure local hist_fig=dfhack.units.getNemesis(adv).figure
if hist_fig==nil then if hist_fig==nil then
qerror("No historical figure for adventurer...") qerror("No historical figure for adventurer...")
end end
local events=df.global.world.history.events local events=df.global.world.history.events
local trg_hist_fig local trg_hist_fig
for i=#events-1,0,-1 do -- reverse search because almost always it will be last entry for i=#events-1,0,-1 do -- reverse search because almost always it will be last entry
if df.history_event_hist_figure_diedst:is_instance(events[i]) then if df.history_event_hist_figure_diedst:is_instance(events[i]) then
--print("is instance:"..i) --print("is instance:"..i)
if events[i].victim_hf==hist_fig.id then if events[i].victim_hf==hist_fig.id then
--print("Is same id:"..i) --print("Is same id:"..i)
trg_hist_fig=events[i].slayer_hf trg_hist_fig=events[i].slayer_hf
if trg_hist_fig then if trg_hist_fig then
trg_hist_fig=df.historical_figure.find(trg_hist_fig) trg_hist_fig=df.historical_figure.find(trg_hist_fig)
end end
break break
end end
end end
end end
if trg_hist_fig ==nil then if trg_hist_fig ==nil then
qerror("Slayer not found") qerror("Slayer not found")
end end
local trg_unit=trg_hist_fig.unit_id local trg_unit=trg_hist_fig.unit_id
if trg_unit==nil then if trg_unit==nil then
qerror("Unit id not found!") qerror("Unit id not found!")
end end
local trg_unit_final=df.unit.find(trg_unit) local trg_unit_final=df.unit.find(trg_unit)
change_adv(trg_unit_final) change_adv(trg_unit_final)
if swap_soul then --actually add a soul... if swap_soul then --actually add a soul...
t_soul=adv.status.current_soul t_soul=adv.status.current_soul
adv.status.current_soul=df.NULL adv.status.current_soul=df.NULL
adv.status.souls:resize(0) adv.status.souls:resize(0)
trg_unit_final.status.current_soul=t_soul trg_unit_final.status.current_soul=t_soul
trg_unit_final.status.souls:insert(#trg_unit_final.status.souls,t_soul) trg_unit_final.status.souls:insert(#trg_unit_final.status.souls,t_soul)
end end
end end
menu:add("Reincarnate",Reincarnate,{{df.unit,"optional"}})-- bool, optional menu:add("Reincarnate",Reincarnate,{{df.unit,"optional"}})-- bool, optional
function change_adv(unit,nemesis) function change_adv(unit,nemesis)
if nemesis==nil then if nemesis==nil then
nemesis=true --default value is nemesis switch too. nemesis=true --default value is nemesis switch too.
end end
if unit==nil then if unit==nil then
unit=dfhack.gui.getSelectedUnit()--getCreatureAtPointer() unit=dfhack.gui.getSelectedUnit()--getCreatureAtPointer()
end end
if unit==nil then if unit==nil then
error("Invalid unit!") error("Invalid unit!")
end end
local other=df.global.world.units.active local other=df.global.world.units.active
local unit_indx local unit_indx
for k,v in pairs(other) do for k,v in pairs(other) do
if v==unit then if v==unit then
unit_indx=k unit_indx=k
break break
end end
end end
if unit_indx==nil then if unit_indx==nil then
error("Unit not found in array?!") --should not happen error("Unit not found in array?!") --should not happen
end end
other[unit_indx]=other[0] other[unit_indx]=other[0]
other[0]=unit other[0]=unit
if nemesis then --basicly copied from advtools plugin... if nemesis then --basicly copied from advtools plugin...
local nem=dfhack.units.getNemesis(unit) local nem=dfhack.units.getNemesis(unit)
local other_nem=dfhack.units.getNemesis(other[unit_indx]) local other_nem=dfhack.units.getNemesis(other[unit_indx])
if other_nem then if other_nem then
other_nem.flags[0]=false other_nem.flags[0]=false
other_nem.flags[1]=true other_nem.flags[1]=true
end end
if nem then if nem then
nem.flags[0]=true nem.flags[0]=true
nem.flags[2]=true nem.flags[2]=true
for k,v in pairs(df.global.world.nemesis.all) do for k,v in pairs(df.global.world.nemesis.all) do
if v.id==nem.id then if v.id==nem.id then
df.global.ui_advmode.player_id=k df.global.ui_advmode.player_id=k
end end
end end
else else
qerror("Current unit does not have nemesis record, further working not guaranteed") qerror("Current unit does not have nemesis record, further working not guaranteed")
end end
end end
end end
menu:add("Change adventurer",change_adv) menu:add("Change adventurer",change_adv)
function log_pos() function log_pos()
local adv=df.global.world.units.active[0] local adv=df.global.world.units.active[0]
local wmap=df.global.world.map local wmap=df.global.world.map
local sub_pos={x=adv.pos.x,y=adv.pos.y,z=adv.pos.z} local sub_pos={x=adv.pos.x,y=adv.pos.y,z=adv.pos.z}
local region_pos={x=wmap.region_x,y=wmap.region_y,z=wmap.region_z} local region_pos={x=wmap.region_x,y=wmap.region_y,z=wmap.region_z}

@ -14,7 +14,7 @@ if myos=="windows" then
error("caste and race count must be less then "..MAX_RACES) error("caste and race count must be less then "..MAX_RACES)
end end
local n_to_id=require("plugins.dfusion.tools").build_race_names() local n_to_id=require("plugins.dfusion.tools").build_race_names()
local ids={} local ids={}
for k,v in pairs(races) do for k,v in pairs(races) do
local race=v[1] or v local race=v[1] or v
@ -30,7 +30,7 @@ if myos=="windows" then
if race_caste_data~=nil then if race_caste_data~=nil then
self:parseRaces(race_caste_data) self:parseRaces(race_caste_data)
end end
if stoff==nil then if stoff==nil then
error("address for start_dwarf_count not found!") error("address for start_dwarf_count not found!")
end end
@ -41,8 +41,8 @@ if myos=="windows" then
for k,v in ipairs(tmp_table) do for k,v in ipairs(tmp_table) do
table.insert(needle,v) table.insert(needle,v)
end end
local mem=ms.get_code_segment() local mem=ms.get_code_segment()
print(mem.uint8_t:addr2idx(stoff)) print(mem.uint8_t:addr2idx(stoff))
print(mem.uint8_t:find(needle,mem.uint8_t:addr2idx(stoff))) print(mem.uint8_t:find(needle,mem.uint8_t:addr2idx(stoff)))
local _,trg_offset=mem.uint8_t:find(needle,mem.uint8_t:addr2idx(stoff),nil)--maybe endoff=stoff+bignumber local _,trg_offset=mem.uint8_t:find(needle,mem.uint8_t:addr2idx(stoff),nil)--maybe endoff=stoff+bignumber
@ -58,31 +58,31 @@ if myos=="windows" then
if caste_offset==nil or caste_offset-stoff>1000 then if caste_offset==nil or caste_offset-stoff>1000 then
error("Caste change code not found or found too far!") error("Caste change code not found or found too far!")
end end
self.disable_castes=self.disable_castes or dfu.BinaryPatch{pre_data={0x83,0xc8,0xff},data={0x90,0x90,0x90},address=caste_offset,name="custom_embark_caste_disable"} self.disable_castes=self.disable_castes or dfu.BinaryPatch{pre_data={0x83,0xc8,0xff},data={0x90,0x90,0x90},address=caste_offset,name="custom_embark_caste_disable"}
self.disable_castes:apply() self.disable_castes:apply()
self:setEmbarkParty(self.race_caste_data) self:setEmbarkParty(self.race_caste_data)
local caste_array=self:get_or_alloc("caste_array","uint16_t",MAX_RACES) local caste_array=self:get_or_alloc("caste_array","uint16_t",MAX_RACES)
local race_array=self:get_or_alloc("race_array","uint16_t",MAX_RACES) local race_array=self:get_or_alloc("race_array","uint16_t",MAX_RACES)
local race_array_off,caste_array_off local race_array_off,caste_array_off
local _ local _
_,race_array_off=df.sizeof(race_array) _,race_array_off=df.sizeof(race_array)
_,caste_array_off=df.sizeof(caste_array) _,caste_array_off=df.sizeof(caste_array)
self:set_marker_dword("race",caste_array_off) --hehe... mixed them up i guess... self:set_marker_dword("race",caste_array_off) --hehe... mixed them up i guess...
self:set_marker_dword("caste",race_array_off) self:set_marker_dword("caste",race_array_off)
self:move_to_df() self:move_to_df()
self.call_patch:apply() self.call_patch:apply()
self.installed=true self.installed=true
end end
function CustomEmbark:setEmbarkParty(racesAndCastes) function CustomEmbark:setEmbarkParty(racesAndCastes)
local stoff=dfhack.internal.getAddress('start_dwarf_count') local stoff=dfhack.internal.getAddress('start_dwarf_count')
if self.dwarfcount== nil then if self.dwarfcount== nil then
self.dwarfcount=dfu.BinaryPatch{pre_data=dfu.dwordToTable(7),data=dfu.dwordToTable(#self.race_caste_data),address=stoff,name="custom_embark_embarkcount"} self.dwarfcount=dfu.BinaryPatch{pre_data=dfu.dwordToTable(7),data=dfu.dwordToTable(#self.race_caste_data),address=stoff,name="custom_embark_embarkcount"}
self.dwarfcount:apply() self.dwarfcount:apply()
@ -91,7 +91,7 @@ if myos=="windows" then
end end
local caste_array=self:get_or_alloc("caste_array","uint16_t",MAX_RACES) local caste_array=self:get_or_alloc("caste_array","uint16_t",MAX_RACES)
local race_array=self:get_or_alloc("race_array","uint16_t",MAX_RACES) local race_array=self:get_or_alloc("race_array","uint16_t",MAX_RACES)
for k,v in ipairs(self.race_caste_data) do for k,v in ipairs(self.race_caste_data) do
caste_array[k-1]=v[2] or -1 caste_array[k-1]=v[2] or -1
race_array[k-1]=v[1] race_array[k-1]=v[1]

@ -13,7 +13,7 @@ function FriendshipRainbow:findall_needles(codesg,needle) -- todo move to memsca
local cidx,caddr=codesg.uint8_t:find(needle) local cidx,caddr=codesg.uint8_t:find(needle)
local ret={} local ret={}
while cidx~=nil do while cidx~=nil do
table.insert(ret,{cidx,caddr}) table.insert(ret,{cidx,caddr})
cidx,caddr=codesg.uint8_t:find(needle,cidx+1) cidx,caddr=codesg.uint8_t:find(needle,cidx+1)
end end
return ret return ret
@ -23,10 +23,10 @@ function FriendshipRainbow:find_one(codesg,needle,crace)
return self:findall_needles(codesg,needle) return self:findall_needles(codesg,needle)
end end
function FriendshipRainbow:find_all() function FriendshipRainbow:find_all()
local code=ms.get_code_segment() local code=ms.get_code_segment()
local locations={} local locations={}
local _,crace=df.sizeof(df.global.ui:_field("race_id")) local _,crace=df.sizeof(df.global.ui:_field("race_id"))
dfu.concatTables(locations,self:find_one(code,{0x66,0xa1},crace)) --mov ax,[ptr] dfu.concatTables(locations,self:find_one(code,{0x66,0xa1},crace)) --mov ax,[ptr]
dfu.concatTables(locations,self:find_one(code,{0xa1},crace)) --mov ax,[ptr] dfu.concatTables(locations,self:find_one(code,{0xa1},crace)) --mov ax,[ptr]
local registers= local registers=
@ -40,11 +40,11 @@ function FriendshipRainbow:find_all()
--0x2d, --ebp not used? --0x2d, --ebp not used?
} }
for k,reg in ipairs(registers) do for k,reg in ipairs(registers) do
dfu.concatTables(locations,self:find_one(code,{0x0f,0xbf,reg},crace)) --movsx reg,[ptr] dfu.concatTables(locations,self:find_one(code,{0x0f,0xbf,reg},crace)) --movsx reg,[ptr]
dfu.concatTables(locations,self:find_one(code,{0x66,0x8b,reg},crace)) --mov reg,[ptr] dfu.concatTables(locations,self:find_one(code,{0x66,0x8b,reg},crace)) --mov reg,[ptr]
end end
return self:filter_locations(code,locations) return self:filter_locations(code,locations)
end end
function FriendshipRainbow:filter_locations(codesg,locations) function FriendshipRainbow:filter_locations(codesg,locations)
@ -57,7 +57,7 @@ function FriendshipRainbow:filter_locations(codesg,locations)
0xb8,0xbb,0xb9,0xba,0xbe,0xbf} 0xb8,0xbb,0xb9,0xba,0xbe,0xbf}
for _,entry in ipairs(locations) do for _,entry in ipairs(locations) do
for _,r in ipairs(registers) do for _,r in ipairs(registers) do
local idx,addr=codesg.uint8_t:find({0x39,r,0x8c,0x00,0x00,0x00}, local idx,addr=codesg.uint8_t:find({0x39,r,0x8c,0x00,0x00,0x00},
codesg.uint8_t:addr2idx(entry[2]),codesg.uint8_t:addr2idx(entry[2])+MAX_CODE_DIST) codesg.uint8_t:addr2idx(entry[2]),codesg.uint8_t:addr2idx(entry[2])+MAX_CODE_DIST)
if addr then if addr then
@ -90,7 +90,7 @@ function FriendshipRainbow:set_races(arr)
local n_to_id=require("plugins.dfusion.tools").build_race_names() local n_to_id=require("plugins.dfusion.tools").build_race_names()
local ids={} local ids={}
for k,v in ipairs(self.race_data) do -- to check if all races are valid. for k,v in ipairs(self.race_data) do -- to check if all races are valid.
ids[k]=n_to_id[v] ids[k]=n_to_id[v]
end end
for k,v in ipairs(ids) do for k,v in ipairs(ids) do
arr[k-1]=ids[k] arr[k-1]=ids[k]

@ -19,205 +19,205 @@ function build_race_names()
return RaceNames return RaceNames
end end
end end
function setrace(name) function setrace(name)
local RaceTable=build_race_names() local RaceTable=build_race_names()
print("Your current race is:"..df.global.world.raws.creatures.all[df.global.ui.race_id].creature_id) print("Your current race is:"..df.global.world.raws.creatures.all[df.global.ui.race_id].creature_id)
local id local id
if name == nil then if name == nil then
print("Type new race's token name in full caps (q to quit):") print("Type new race's token name in full caps (q to quit):")
repeat repeat
local entry=dfhack.lineedit() local entry=dfhack.lineedit()
if entry=="q" then if entry=="q" then
return return
end end
id=RaceTable[entry] id=RaceTable[entry]
until id~=nil until id~=nil
else else
id=RaceTable[name] id=RaceTable[name]
if id==nil then if id==nil then
error("Name not found!") error("Name not found!")
end end
end end
df.global.ui.race_id=id df.global.ui.race_id=id
end end
menu:add("Set current race",setrace) menu:add("Set current race",setrace)
function GiveSentience(names) function GiveSentience(names)
local RaceTable=build_race_names() --slow.If loaded don't load again local RaceTable=build_race_names() --slow.If loaded don't load again
local id,ids local id,ids
if names ==nil then if names ==nil then
ids={} ids={}
print("Type race's token name in full caps to give sentience to:") print("Type race's token name in full caps to give sentience to:")
repeat repeat
id=dfhack.lineedit() id=dfhack.lineedit()
id=RaceTable[entry] id=RaceTable[entry]
if id~=nil then if id~=nil then
table.insert(ids,id) table.insert(ids,id)
end end
until id==nil until id==nil
else
ids={}
for _,name in pairs(names) do
id=RaceTable[name]
table.insert(ids,id)
end
end
for _,id in pairs(ids) do
local races=df.global.world.raws.creatures.all
local castes=races[id].caste else
print(string.format("Caste count:%i",#castes)) ids={}
for i =0,#castes-1 do for _,name in pairs(names) do
id=RaceTable[name]
print("Caste name:"..castes[i].caste_id.."...") table.insert(ids,id)
end
local flags=castes[i].flags end
--print(string.format("%x",flagoffset)) for _,id in pairs(ids) do
if flags.CAN_SPEAK then local races=df.global.world.raws.creatures.all
print("\tis sentient.")
else local castes=races[id].caste
print("\tnon sentient. Allocating IQ...") print(string.format("Caste count:%i",#castes))
flags.CAN_SPEAK=true for i =0,#castes-1 do
end
end print("Caste name:"..castes[i].caste_id.."...")
end
local flags=castes[i].flags
--print(string.format("%x",flagoffset))
if flags.CAN_SPEAK then
print("\tis sentient.")
else
print("\tnon sentient. Allocating IQ...")
flags.CAN_SPEAK=true
end
end
end
end end
menu:add("Give Sentience",GiveSentience) menu:add("Give Sentience",GiveSentience)
function MakeFollow(unit,trgunit) function MakeFollow(unit,trgunit)
if unit == nil then if unit == nil then
unit=dfhack.gui.getSelectedUnit() unit=dfhack.gui.getSelectedUnit()
end end
if unit== nil then if unit== nil then
error("Invalid creature") error("Invalid creature")
end end
if trgunit==nil then if trgunit==nil then
trgunit=df.global.world.units.active[0] trgunit=df.global.world.units.active[0]
end end
unit.relations.group_leader_id=trgunit.id unit.relations.group_leader_id=trgunit.id
local u_nem=dfhack.units.getNemesis(unit) local u_nem=dfhack.units.getNemesis(unit)
local t_nem=dfhack.units.getNemesis(trgunit) local t_nem=dfhack.units.getNemesis(trgunit)
if u_nem then if u_nem then
u_nem.group_leader_id=t_nem.id u_nem.group_leader_id=t_nem.id
end end
if t_nem and u_nem then if t_nem and u_nem then
t_nem.companions:insert(#t_nem.companions,u_nem.id) t_nem.companions:insert(#t_nem.companions,u_nem.id)
end end
end end
menu:add("Make creature follow",MakeFollow) menu:add("Make creature follow",MakeFollow)
function project(unit,trg) --TODO add to menu? function project(unit,trg) --TODO add to menu?
if unit==nil then if unit==nil then
unit=getCreatureAtPointer() unit=getCreatureAtPointer()
end end
if unit==nil then if unit==nil then
error("Failed to project unit. Unit not selected/valid") error("Failed to project unit. Unit not selected/valid")
end end
-- todo: add projectile to world, point to unit, add flag to unit, add gen-ref to projectile. -- todo: add projectile to world, point to unit, add flag to unit, add gen-ref to projectile.
local p=df.proj_unitst:new() local p=df.proj_unitst:new()
local startpos={x=unit.pos.x,y=unit.pos.y,z=unit.pos.z} local startpos={x=unit.pos.x,y=unit.pos.y,z=unit.pos.z}
p.origin_pos=startpos p.origin_pos=startpos
p.target_pos=trg p.target_pos=trg
p.cur_pos=startpos p.cur_pos=startpos
p.prev_pos=startpos p.prev_pos=startpos
p.unit=unit p.unit=unit
--- wtf stuff --- wtf stuff
p.unk14=100 p.unk14=100
p.unk16=-1 p.unk16=-1
p.unk23=-1 p.unk23=-1
p.fall_delay=5 p.fall_delay=5
p.fall_counter=5 p.fall_counter=5
p.collided=true p.collided=true
-- end wtf -- end wtf
local citem=df.global.world.proj_list local citem=df.global.world.proj_list
local maxid=1 local maxid=1
local newlink=df.proj_list_link:new() local newlink=df.proj_list_link:new()
newlink.item=p newlink.item=p
while citem.item~= nil do while citem.item~= nil do
if citem.item.id>maxid then maxid=citem.item.id end if citem.item.id>maxid then maxid=citem.item.id end
if citem.next ~= nil then if citem.next ~= nil then
citem=citem.next citem=citem.next
else else
break break
end end
end end
p.id=maxid+1 p.id=maxid+1
newlink.prev=citem newlink.prev=citem
citem.next=newlink citem.next=newlink
local proj_ref=df.general_ref_projectile:new() local proj_ref=df.general_ref_projectile:new()
proj_ref.projectile_id=p.id proj_ref.projectile_id=p.id
unit.general_refs:insert(#unit.general_refs,proj_ref) unit.general_refs:insert(#unit.general_refs,proj_ref)
unit.flags1.projectile=true unit.flags1.projectile=true
end end
function empregnate(unit) function empregnate(unit)
if unit==nil then if unit==nil then
unit=dfhack.gui.getSelectedUnit() unit=dfhack.gui.getSelectedUnit()
end end
if unit==nil then if unit==nil then
error("Failed to empregnate. Unit not selected/valid") error("Failed to empregnate. Unit not selected/valid")
end end
if unit.curse then if unit.curse then
unit.curse.add_tags2.STERILE=false unit.curse.add_tags2.STERILE=false
end end
local genes = unit.appearance.genes local genes = unit.appearance.genes
if unit.relations.pregnancy_genes == nil then if unit.relations.pregnancy_genes == nil then
print("creating preg ptr.") print("creating preg ptr.")
if false then if false then
print(string.format("%x %x",df.sizeof(unit.relations:_field("pregnancy_genes")))) print(string.format("%x %x",df.sizeof(unit.relations:_field("pregnancy_genes"))))
return return
end end
unit.relations.pregnancy_genes = { new = true, assign = genes } unit.relations.pregnancy_genes = { new = true, assign = genes }
end end
local ngenes = unit.relations.pregnancy_genes local ngenes = unit.relations.pregnancy_genes
if #ngenes.appearance ~= #genes.appearance or #ngenes.colors ~= #genes.colors then if #ngenes.appearance ~= #genes.appearance or #ngenes.colors ~= #genes.colors then
print("Array sizes incorrect, fixing.") print("Array sizes incorrect, fixing.")
ngenes:assign(genes); ngenes:assign(genes);
end end
print("Setting preg timer.") print("Setting preg timer.")
unit.relations.pregnancy_timer=10 unit.relations.pregnancy_timer=10
unit.relations.pregnancy_caste=1 unit.relations.pregnancy_caste=1
end end
menu:add("Empregnate",empregnate) menu:add("Empregnate",empregnate)
function healunit(unit) function healunit(unit)
if unit==nil then if unit==nil then
unit=dfhack.gui.getSelectedUnit() unit=dfhack.gui.getSelectedUnit()
end end
if unit==nil then
error("Failed to Heal unit. Unit not selected/valid")
end
if unit==nil then
error("Failed to Heal unit. Unit not selected/valid")
end
unit.body.wounds:resize(0) -- memory leak here :/ unit.body.wounds:resize(0) -- memory leak here :/
unit.body.blood_count=unit.body.blood_max unit.body.blood_count=unit.body.blood_max
--set flags for standing and grasping... --set flags for standing and grasping...
unit.status2.limbs_stand_max=4 unit.status2.limbs_stand_max=4
unit.status2.limbs_stand_count=4 unit.status2.limbs_stand_count=4
unit.status2.limbs_grasp_max=4 unit.status2.limbs_grasp_max=4
unit.status2.limbs_grasp_count=4 unit.status2.limbs_grasp_count=4
--should also set temperatures, and flags for breath etc... --should also set temperatures, and flags for breath etc...
unit.flags1.dead=false unit.flags1.dead=false
unit.flags2.calculated_bodyparts=false unit.flags2.calculated_bodyparts=false
unit.flags2.calculated_nerves=false unit.flags2.calculated_nerves=false
unit.flags2.circulatory_spray=false unit.flags2.circulatory_spray=false
unit.flags2.vision_good=true unit.flags2.vision_good=true
unit.flags2.vision_damaged=false unit.flags2.vision_damaged=false
unit.flags2.vision_missing=false unit.flags2.vision_missing=false
unit.counters.winded=0 unit.counters.winded=0
unit.counters.unconscious=0 unit.counters.unconscious=0
for k,v in pairs(unit.body.components) do for k,v in pairs(unit.body.components) do
for kk,vv in pairs(v) do for kk,vv in pairs(v) do
if k == 'body_part_status' then v[kk].whole = 0 else v[kk] = 0 end if k == 'body_part_status' then v[kk].whole = 0 else v[kk] = 0 end
end end
end end
end end
menu:add("Heal unit",healunit) menu:add("Heal unit",healunit)
function powerup(unit,labor_rating,military_rating,skills) function powerup(unit,labor_rating,military_rating,skills)
if unit==nil then if unit==nil then
unit=dfhack.gui.getSelectedUnit() unit=dfhack.gui.getSelectedUnit()
end end
if unit==nil then if unit==nil then
error("Failed to power up unit. Unit not selected/valid") error("Failed to power up unit. Unit not selected/valid")
end end
if unit.status.current_soul== nil then if unit.status.current_soul== nil then
error("Failed to power up unit. Unit has no soul") error("Failed to power up unit. Unit has no soul")
end end
@ -237,7 +237,7 @@ function powerup(unit,labor_rating,military_rating,skills)
end end
utils.insert_or_update(unit.status.current_soul.skills, { new = true, id = sv, rating = new_rating, experience = (new_rating * 500) + (new_rating * (new_rating - 1)) * 50}, 'id') utils.insert_or_update(unit.status.current_soul.skills, { new = true, id = sv, rating = new_rating, experience = (new_rating * 500) + (new_rating * (new_rating - 1)) * 50}, 'id')
end end
end end
menu:add("Power up",powerup) menu:add("Power up",powerup)
return _ENV return _ENV

@ -1,7 +1,7 @@
local _ENV = mkmodule('plugins.eventful') local _ENV = mkmodule('plugins.eventful')
--[[ --[[
--]] --]]
local function getShopName(btype,bsubtype,bcustom) local function getShopName(btype,bsubtype,bcustom)
local typenames_shop={[df.workshop_type.Carpenters]="CARPENTERS",[df.workshop_type.Farmers]="FARMERS", local typenames_shop={[df.workshop_type.Carpenters]="CARPENTERS",[df.workshop_type.Farmers]="FARMERS",
@ -22,13 +22,13 @@ local function getShopName(btype,bsubtype,bcustom)
[df.furnace_type.MagmaGlassFurnace]="MAGMA_GLASS_FURNACE",[df.furnace_type.MagmaKiln]="MAGMA_KILN", [df.furnace_type.MagmaGlassFurnace]="MAGMA_GLASS_FURNACE",[df.furnace_type.MagmaKiln]="MAGMA_KILN",
[df.furnace_type.Kiln]="KILN"} [df.furnace_type.Kiln]="KILN"}
if btype==df.building_type.Workshop then if btype==df.building_type.Workshop then
if typenames_shop[bsubtype]~=nil then if typenames_shop[bsubtype]~=nil then
return typenames_shop[bsubtype] return typenames_shop[bsubtype]
else else
return df.building_def_workshopst.find(bcustom).code return df.building_def_workshopst.find(bcustom).code
end end
elseif btype==df.building_type.Furnace then elseif btype==df.building_type.Furnace then
if typenames_furnace[bsubtype]~=nil then if typenames_furnace[bsubtype]~=nil then
return typenames_furnace[bsubtype] return typenames_furnace[bsubtype]
else else
return df.building_def_furnacest.find(bcustom).code return df.building_def_furnacest.find(bcustom).code

@ -62,7 +62,7 @@ function list_orders()
print("Stockpile #"..num, name, trigger) print("Stockpile #"..num, name, trigger)
listed = true listed = true
end end
if not listed then if not listed then
print("No manager jobs have been set for your stockpiles.") print("No manager jobs have been set for your stockpiles.")
print("Use j in a stockpile menu to create one...") print("Use j in a stockpile menu to create one...")
@ -79,7 +79,7 @@ function start_bookkeeping()
result[reaction_id] = amount result[reaction_id] = amount
end end
end end
jobs_to_create = result jobs_to_create = result
end end
@ -89,7 +89,7 @@ function finish_bookkeeping()
for reaction, amount in pairs(jobs_to_create) do for reaction, amount in pairs(jobs_to_create) do
create_orders(reaction_list[reaction].order, amount) create_orders(reaction_list[reaction].order, amount)
end end
jobs_to_create = {} jobs_to_create = {}
end end
@ -98,7 +98,7 @@ function stockpile_settings(sp)
if not order then if not order then
return "No job selected", "" return "No job selected", ""
end end
return order.entry.value, trigger_name(order) return order.entry.value, trigger_name(order)
end end
@ -138,7 +138,7 @@ function collect_orders()
end end
end end
end end
return result return result
end end
@ -158,12 +158,12 @@ function reaction_entry(job_type, values, name)
mat_type = -1, mat_type = -1,
mat_index = -1, mat_index = -1,
} }
if values then if values then
-- Override default attributes. -- Override default attributes.
order:assign(values) order:assign(values)
end end
return { return {
name = name or df.job_type.attrs[job_type].caption, name = name or df.job_type.attrs[job_type].caption,
order = order, order = order,
@ -175,20 +175,20 @@ function resource_reactions(reactions, job_type, mat_info, keys, items, options)
for key, value in pairs(mat_info.management) do for key, value in pairs(mat_info.management) do
values[key] = value values[key] = value
end end
for _, itemid in ipairs(keys) do for _, itemid in ipairs(keys) do
local itemdef = items[itemid] local itemdef = items[itemid]
local start = options.verb or mat_info.verb or "Make" local start = options.verb or mat_info.verb or "Make"
if options.adjective then if options.adjective then
start = start.." "..itemdef.adjective start = start.." "..itemdef.adjective
end end
if (not options.permissible) or options.permissible(itemdef) then if (not options.permissible) or options.permissible(itemdef) then
local item_name = " "..itemdef[options.name_field or "name"] local item_name = " "..itemdef[options.name_field or "name"]
if options.capitalize then if options.capitalize then
item_name = string.gsub(item_name, " .", string.upper) item_name = string.gsub(item_name, " .", string.upper)
end end
values.item_subtype = itemid values.item_subtype = itemid
table.insert(reactions, reaction_entry(job_type, values, start.." "..mat_info.adjective..item_name)) table.insert(reactions, reaction_entry(job_type, values, start.." "..mat_info.adjective..item_name))
end end
@ -202,7 +202,7 @@ function material_reactions(reactions, itemtypes, mat_info)
if row[3] then if row[3] then
line = line.." "..row[3] line = line.." "..row[3]
end end
table.insert(reactions, reaction_entry(row[1], mat_info.management, line)) table.insert(reactions, reaction_entry(row[1], mat_info.management, line))
end end
end end
@ -225,38 +225,38 @@ function collect_reactions()
-- but I currently can only find it while the job selection screen is active. -- but I currently can only find it while the job selection screen is active.
-- Even that list doesn't seem to include their names. -- Even that list doesn't seem to include their names.
local result = {} local result = {}
-- A few task types are obsolete in newer DF versions. -- A few task types are obsolete in newer DF versions.
local v34 = string.match(dfhack.getDFVersion(), "v0.34") local v34 = string.match(dfhack.getDFVersion(), "v0.34")
-- Caching the enumeration might not be important, but saves lookups. -- Caching the enumeration might not be important, but saves lookups.
local job_types = df.job_type local job_types = df.job_type
local materials = { local materials = {
rock = { rock = {
adjective = "rock", adjective = "rock",
management = {mat_type = 0}, management = {mat_type = 0},
}, },
} }
for _, name in ipairs{"wood", "cloth", "leather", "silk", "yarn", "bone", "shell", "tooth", "horn", "pearl"} do for _, name in ipairs{"wood", "cloth", "leather", "silk", "yarn", "bone", "shell", "tooth", "horn", "pearl"} do
materials[name] = { materials[name] = {
adjective = name, adjective = name,
management = {material_category = {[name] = true}}, management = {material_category = {[name] = true}},
} }
end end
materials.wood.adjective = "wooden" materials.wood.adjective = "wooden"
materials.tooth.adjective = "ivory/tooth" materials.tooth.adjective = "ivory/tooth"
materials.leather.clothing_flag = "LEATHER" materials.leather.clothing_flag = "LEATHER"
-- Collection and Entrapment -- Collection and Entrapment
table.insert(result, reaction_entry(job_types.CollectWebs)) table.insert(result, reaction_entry(job_types.CollectWebs))
table.insert(result, reaction_entry(job_types.CollectSand)) table.insert(result, reaction_entry(job_types.CollectSand))
table.insert(result, reaction_entry(job_types.CollectClay)) table.insert(result, reaction_entry(job_types.CollectClay))
table.insert(result, reaction_entry(job_types.CatchLiveLandAnimal)) table.insert(result, reaction_entry(job_types.CatchLiveLandAnimal))
table.insert(result, reaction_entry(job_types.CatchLiveFish)) table.insert(result, reaction_entry(job_types.CatchLiveFish))
-- Cutting, encrusting, and metal extraction. -- Cutting, encrusting, and metal extraction.
local rock_types = df.global.world.raws.inorganics local rock_types = df.global.world.raws.inorganics
for rock_id = #rock_types-1, 0, -1 do for rock_id = #rock_types-1, 0, -1 do
@ -267,35 +267,35 @@ function collect_reactions()
mat_type = 0, mat_type = 0,
mat_index = rock_id, mat_index = rock_id,
}, "Cut "..rock_name)) }, "Cut "..rock_name))
table.insert(result, reaction_entry(job_types.EncrustWithGems, { table.insert(result, reaction_entry(job_types.EncrustWithGems, {
mat_type = 0, mat_type = 0,
mat_index = rock_id, mat_index = rock_id,
item_category = {finished_goods = true}, item_category = {finished_goods = true},
}, "Encrust Finished Goods With "..rock_name)) }, "Encrust Finished Goods With "..rock_name))
table.insert(result, reaction_entry(job_types.EncrustWithGems, { table.insert(result, reaction_entry(job_types.EncrustWithGems, {
mat_type = 0, mat_type = 0,
mat_index = rock_id, mat_index = rock_id,
item_category = {furniture = true}, item_category = {furniture = true},
}, "Encrust Furniture With "..rock_name)) }, "Encrust Furniture With "..rock_name))
table.insert(result, reaction_entry(job_types.EncrustWithGems, { table.insert(result, reaction_entry(job_types.EncrustWithGems, {
mat_type = 0, mat_type = 0,
mat_index = rock_id, mat_index = rock_id,
item_category = {ammo = true}, item_category = {ammo = true},
}, "Encrust Ammo With "..rock_name)) }, "Encrust Ammo With "..rock_name))
end end
if #rock_types[rock_id].metal_ore.mat_index > 0 then if #rock_types[rock_id].metal_ore.mat_index > 0 then
table.insert(result, reaction_entry(job_types.SmeltOre, {mat_type = 0, mat_index = rock_id}, "Smelt "..rock_name.." Ore")) table.insert(result, reaction_entry(job_types.SmeltOre, {mat_type = 0, mat_index = rock_id}, "Smelt "..rock_name.." Ore"))
end end
if #rock_types[rock_id].thread_metal.mat_index > 0 then if #rock_types[rock_id].thread_metal.mat_index > 0 then
table.insert(result, reaction_entry(job_types.ExtractMetalStrands, {mat_type = 0, mat_index = rock_id})) table.insert(result, reaction_entry(job_types.ExtractMetalStrands, {mat_type = 0, mat_index = rock_id}))
end end
end end
-- Glass cutting and encrusting, with different job numbers. -- Glass cutting and encrusting, with different job numbers.
-- We could search the entire table, but glass is less subject to raws. -- We could search the entire table, but glass is less subject to raws.
local glass_types = df.global.world.raws.mat_table.builtin local glass_types = df.global.world.raws.mat_table.builtin
@ -309,61 +309,61 @@ function collect_reactions()
adjective = glass_name, adjective = glass_name,
management = {mat_type = glass_id}, management = {mat_type = glass_id},
}) })
table.insert(result, reaction_entry(job_types.CutGlass, {mat_type = glass_id}, "Cut "..glass_name)) table.insert(result, reaction_entry(job_types.CutGlass, {mat_type = glass_id}, "Cut "..glass_name))
table.insert(result, reaction_entry(job_types.EncrustWithGlass, { table.insert(result, reaction_entry(job_types.EncrustWithGlass, {
mat_type = glass_id, mat_type = glass_id,
item_category = {finished_goods = true}, item_category = {finished_goods = true},
}, "Encrust Finished Goods With "..glass_name)) }, "Encrust Finished Goods With "..glass_name))
table.insert(result, reaction_entry(job_types.EncrustWithGlass, { table.insert(result, reaction_entry(job_types.EncrustWithGlass, {
mat_type = glass_id, mat_type = glass_id,
item_category = {furniture = true}, item_category = {furniture = true},
}, "Encrust Furniture With "..glass_name)) }, "Encrust Furniture With "..glass_name))
table.insert(result, reaction_entry(job_types.EncrustWithGlass, { table.insert(result, reaction_entry(job_types.EncrustWithGlass, {
mat_type = glass_id, mat_type = glass_id,
item_category = {ammo = true}, item_category = {ammo = true},
}, "Encrust Ammo With "..glass_name)) }, "Encrust Ammo With "..glass_name))
end end
end end
-- Dyeing -- Dyeing
table.insert(result, reaction_entry(job_types.DyeThread)) table.insert(result, reaction_entry(job_types.DyeThread))
table.insert(result, reaction_entry(job_types.DyeCloth)) table.insert(result, reaction_entry(job_types.DyeCloth))
-- Sew Image -- Sew Image
local cloth_mats = {materials.cloth, materials.silk, materials.yarn, materials.leather} local cloth_mats = {materials.cloth, materials.silk, materials.yarn, materials.leather}
for _, material in ipairs(cloth_mats) do for _, material in ipairs(cloth_mats) do
material_reactions(result, {{job_types.SewImage, "Sew", "Image"}}, material) material_reactions(result, {{job_types.SewImage, "Sew", "Image"}}, material)
end end
for _, spec in ipairs{materials.bone, materials.shell, materials.tooth, materials.horn, materials.pearl} do for _, spec in ipairs{materials.bone, materials.shell, materials.tooth, materials.horn, materials.pearl} do
material_reactions(result, {{job_types.DecorateWith, "Decorate With"}}, spec) material_reactions(result, {{job_types.DecorateWith, "Decorate With"}}, spec)
end end
table.insert(result, reaction_entry(job_types.MakeTotem)) table.insert(result, reaction_entry(job_types.MakeTotem))
table.insert(result, reaction_entry(job_types.ButcherAnimal)) table.insert(result, reaction_entry(job_types.ButcherAnimal))
table.insert(result, reaction_entry(job_types.MillPlants)) table.insert(result, reaction_entry(job_types.MillPlants))
table.insert(result, reaction_entry(job_types.MakePotashFromLye)) table.insert(result, reaction_entry(job_types.MakePotashFromLye))
table.insert(result, reaction_entry(job_types.MakePotashFromAsh)) table.insert(result, reaction_entry(job_types.MakePotashFromAsh))
-- Kitchen -- Kitchen
table.insert(result, reaction_entry(job_types.PrepareMeal, {mat_type = 2}, "Prepare Easy Meal")) table.insert(result, reaction_entry(job_types.PrepareMeal, {mat_type = 2}, "Prepare Easy Meal"))
table.insert(result, reaction_entry(job_types.PrepareMeal, {mat_type = 3}, "Prepare Fine Meal")) table.insert(result, reaction_entry(job_types.PrepareMeal, {mat_type = 3}, "Prepare Fine Meal"))
table.insert(result, reaction_entry(job_types.PrepareMeal, {mat_type = 4}, "Prepare Lavish Meal")) table.insert(result, reaction_entry(job_types.PrepareMeal, {mat_type = 4}, "Prepare Lavish Meal"))
if v34 then if v34 then
-- Brew Drink -- Brew Drink
table.insert(result, reaction_entry(job_types.BrewDrink)) table.insert(result, reaction_entry(job_types.BrewDrink))
end end
-- Weaving -- Weaving
table.insert(result, reaction_entry(job_types.WeaveCloth, {material_category = {plant = true}}, "Weave Thread into Cloth")) table.insert(result, reaction_entry(job_types.WeaveCloth, {material_category = {plant = true}}, "Weave Thread into Cloth"))
table.insert(result, reaction_entry(job_types.WeaveCloth, {material_category = {silk = true}}, "Weave Thread into Silk")) table.insert(result, reaction_entry(job_types.WeaveCloth, {material_category = {silk = true}}, "Weave Thread into Silk"))
table.insert(result, reaction_entry(job_types.WeaveCloth, {material_category = {yarn = true}}, "Weave Yarn into Cloth")) table.insert(result, reaction_entry(job_types.WeaveCloth, {material_category = {yarn = true}}, "Weave Yarn into Cloth"))
-- Extracts, farmer's workshop, and wood burning -- Extracts, farmer's workshop, and wood burning
table.insert(result, reaction_entry(job_types.ExtractFromPlants)) table.insert(result, reaction_entry(job_types.ExtractFromPlants))
table.insert(result, reaction_entry(job_types.ExtractFromRawFish)) table.insert(result, reaction_entry(job_types.ExtractFromRawFish))
@ -382,7 +382,7 @@ function collect_reactions()
table.insert(result, reaction_entry(job_types.ProcessPlantsBarrel)) table.insert(result, reaction_entry(job_types.ProcessPlantsBarrel))
table.insert(result, reaction_entry(job_types.MakeCharcoal)) table.insert(result, reaction_entry(job_types.MakeCharcoal))
table.insert(result, reaction_entry(job_types.MakeAsh)) table.insert(result, reaction_entry(job_types.MakeAsh))
-- Reactions defined in the raws. -- Reactions defined in the raws.
-- Not all reactions are allowed to the civilization. -- Not all reactions are allowed to the civilization.
-- That includes "Make sharp rock" by default. -- That includes "Make sharp rock" by default.
@ -392,7 +392,7 @@ function collect_reactions()
local name = string.gsub(reaction.name, "^.", string.upper) local name = string.gsub(reaction.name, "^.", string.upper)
table.insert(result, reaction_entry(job_types.CustomReaction, {reaction_name = reaction.code}, name)) table.insert(result, reaction_entry(job_types.CustomReaction, {reaction_name = reaction.code}, name))
end end
-- Metal forging -- Metal forging
local itemdefs = df.global.world.raws.itemdefs local itemdefs = df.global.world.raws.itemdefs
for rock_id = 0, #rock_types - 1 do for rock_id = 0, #rock_types - 1 do
@ -403,76 +403,76 @@ function collect_reactions()
management = {mat_type = 0, mat_index = rock_id}, management = {mat_type = 0, mat_index = rock_id},
verb = "Forge", verb = "Forge",
} }
if material.flags.IS_METAL then if material.flags.IS_METAL then
table.insert(result, reaction_entry(job_types.StudWith, mat_flags.management, "Stud With "..rock_name)) table.insert(result, reaction_entry(job_types.StudWith, mat_flags.management, "Stud With "..rock_name))
if material.flags.ITEMS_WEAPON then if material.flags.ITEMS_WEAPON then
-- Todo: Are these really the right flags to check? -- Todo: Are these really the right flags to check?
resource_reactions(result, job_types.MakeWeapon, mat_flags, entity.resources.weapon_type, itemdefs.weapons, { resource_reactions(result, job_types.MakeWeapon, mat_flags, entity.resources.weapon_type, itemdefs.weapons, {
permissible = (function(itemdef) return itemdef.skill_ranged == -1 end), permissible = (function(itemdef) return itemdef.skill_ranged == -1 end),
}) })
-- Is this entirely disconnected from the entity? -- Is this entirely disconnected from the entity?
material_reactions(result, {{MakeBallistaArrowHead, "Forge", "Ballista Arrow Head"}}, mat_flags) material_reactions(result, {{MakeBallistaArrowHead, "Forge", "Ballista Arrow Head"}}, mat_flags)
resource_reactions(result, job_types.MakeTrapComponent, mat_flags, entity.resources.trapcomp_type, itemdefs.trapcomps, { resource_reactions(result, job_types.MakeTrapComponent, mat_flags, entity.resources.trapcomp_type, itemdefs.trapcomps, {
adjective = true, adjective = true,
}) })
resource_reactions(result, job_types.AssembleSiegeAmmo, mat_flags, entity.resources.siegeammo_type, itemdefs.siege_ammo, { resource_reactions(result, job_types.AssembleSiegeAmmo, mat_flags, entity.resources.siegeammo_type, itemdefs.siege_ammo, {
verb = "Assemble", verb = "Assemble",
}) })
end end
if material.flags.ITEMS_WEAPON_RANGED then if material.flags.ITEMS_WEAPON_RANGED then
resource_reactions(result, job_types.MakeWeapon, mat_flags, entity.resources.weapon_type, itemdefs.weapons, { resource_reactions(result, job_types.MakeWeapon, mat_flags, entity.resources.weapon_type, itemdefs.weapons, {
permissible = (function(itemdef) return itemdef.skill_ranged >= 0 end), permissible = (function(itemdef) return itemdef.skill_ranged >= 0 end),
}) })
end end
if material.flags.ITEMS_DIGGER then if material.flags.ITEMS_DIGGER then
-- Todo: Ranged or training digging weapons? -- Todo: Ranged or training digging weapons?
resource_reactions(result, job_types.MakeWeapon, mat_flags, entity.resources.digger_type, itemdefs.weapons, { resource_reactions(result, job_types.MakeWeapon, mat_flags, entity.resources.digger_type, itemdefs.weapons, {
}) })
end end
if material.flags.ITEMS_AMMO then if material.flags.ITEMS_AMMO then
resource_reactions(result, job_types.MakeAmmo, mat_flags, entity.resources.ammo_type, itemdefs.ammo, { resource_reactions(result, job_types.MakeAmmo, mat_flags, entity.resources.ammo_type, itemdefs.ammo, {
name_field = "name_plural", name_field = "name_plural",
}) })
end end
if material.flags.ITEMS_ANVIL then if material.flags.ITEMS_ANVIL then
material_reactions(result, {{job_types.ForgeAnvil, "Forge", "Anvil"}}, mat_flags) material_reactions(result, {{job_types.ForgeAnvil, "Forge", "Anvil"}}, mat_flags)
end end
if material.flags.ITEMS_ARMOR then if material.flags.ITEMS_ARMOR then
local metalclothing = (function(itemdef) return itemdef.props.flags.METAL end) local metalclothing = (function(itemdef) return itemdef.props.flags.METAL end)
clothing_reactions(result, mat_flags, metalclothing) clothing_reactions(result, mat_flags, metalclothing)
resource_reactions(result, job_types.MakeShield, mat_flags, entity.resources.shield_type, itemdefs.shields, { resource_reactions(result, job_types.MakeShield, mat_flags, entity.resources.shield_type, itemdefs.shields, {
}) })
end end
if material.flags.ITEMS_SOFT then if material.flags.ITEMS_SOFT then
local metalclothing = (function(itemdef) return itemdef.props.flags.SOFT and not itemdef.props.flags.METAL end) local metalclothing = (function(itemdef) return itemdef.props.flags.SOFT and not itemdef.props.flags.METAL end)
clothing_reactions(result, mat_flags, metalclothing) clothing_reactions(result, mat_flags, metalclothing)
end end
if material.flags.ITEMS_HARD then if material.flags.ITEMS_HARD then
resource_reactions(result, job_types.MakeTool, mat_flags, entity.resources.tool_type, itemdefs.tools, { resource_reactions(result, job_types.MakeTool, mat_flags, entity.resources.tool_type, itemdefs.tools, {
permissible = (function(itemdef) return itemdef.flags.HARD_MAT end), permissible = (function(itemdef) return itemdef.flags.HARD_MAT end),
capitalize = true, capitalize = true,
}) })
end end
if material.flags.ITEMS_METAL then if material.flags.ITEMS_METAL then
resource_reactions(result, job_types.MakeTool, mat_flags, entity.resources.tool_type, itemdefs.tools, { resource_reactions(result, job_types.MakeTool, mat_flags, entity.resources.tool_type, itemdefs.tools, {
permissible = (function(itemdef) return itemdef.flags.METAL_MAT end), permissible = (function(itemdef) return itemdef.flags.METAL_MAT end),
capitalize = true, capitalize = true,
}) })
end end
if material.flags.ITEMS_HARD then if material.flags.ITEMS_HARD then
material_reactions(result, { material_reactions(result, {
{job_types.ConstructDoor, "Construct", "Door"}, {job_types.ConstructDoor, "Construct", "Door"},
@ -505,7 +505,7 @@ function collect_reactions()
{job_types.MakeCrafts, "Make", "Crafts"}, {job_types.MakeCrafts, "Make", "Crafts"},
}, mat_flags) }, mat_flags)
end end
if material.flags.ITEMS_SOFT then if material.flags.ITEMS_SOFT then
material_reactions(result, { material_reactions(result, {
{job_types.MakeBackpack, "Make", "Backpack"}, {job_types.MakeBackpack, "Make", "Backpack"},
@ -516,26 +516,26 @@ function collect_reactions()
end end
end end
end end
-- Traction Bench -- Traction Bench
table.insert(result, reaction_entry(job_types.ConstructTractionBench)) table.insert(result, reaction_entry(job_types.ConstructTractionBench))
-- Non-metal weapons -- Non-metal weapons
resource_reactions(result, job_types.MakeWeapon, materials.wood, entity.resources.weapon_type, itemdefs.weapons, { resource_reactions(result, job_types.MakeWeapon, materials.wood, entity.resources.weapon_type, itemdefs.weapons, {
permissible = (function(itemdef) return itemdef.skill_ranged >= 0 end), permissible = (function(itemdef) return itemdef.skill_ranged >= 0 end),
}) })
resource_reactions(result, job_types.MakeWeapon, materials.wood, entity.resources.training_weapon_type, itemdefs.weapons, { resource_reactions(result, job_types.MakeWeapon, materials.wood, entity.resources.training_weapon_type, itemdefs.weapons, {
}) })
resource_reactions(result, job_types.MakeWeapon, materials.bone, entity.resources.weapon_type, itemdefs.weapons, { resource_reactions(result, job_types.MakeWeapon, materials.bone, entity.resources.weapon_type, itemdefs.weapons, {
permissible = (function(itemdef) return itemdef.skill_ranged >= 0 end), permissible = (function(itemdef) return itemdef.skill_ranged >= 0 end),
}) })
resource_reactions(result, job_types.MakeWeapon, materials.rock, entity.resources.weapon_type, itemdefs.weapons, { resource_reactions(result, job_types.MakeWeapon, materials.rock, entity.resources.weapon_type, itemdefs.weapons, {
permissible = (function(itemdef) return itemdef.flags.CAN_STONE end), permissible = (function(itemdef) return itemdef.flags.CAN_STONE end),
}) })
-- Wooden items -- Wooden items
-- Closely related to the ITEMS_HARD list. -- Closely related to the ITEMS_HARD list.
material_reactions(result, { material_reactions(result, {
@ -552,12 +552,12 @@ function collect_reactions()
{job_types.MakeGoblet, "Make", "Cup"}, {job_types.MakeGoblet, "Make", "Cup"},
{job_types.MakeInstrument, "Make", "Instrument"}, {job_types.MakeInstrument, "Make", "Instrument"},
}, materials.wood) }, materials.wood)
resource_reactions(result, job_types.MakeTool, materials.wood, entity.resources.tool_type, itemdefs.tools, { resource_reactions(result, job_types.MakeTool, materials.wood, entity.resources.tool_type, itemdefs.tools, {
-- permissible = (function(itemdef) return itemdef.flags.WOOD_MAT end), -- permissible = (function(itemdef) return itemdef.flags.WOOD_MAT end),
capitalize = true, capitalize = true,
}) })
material_reactions(result, { material_reactions(result, {
{job_types.MakeToy, "Make", "Toy"}, {job_types.MakeToy, "Make", "Toy"},
{job_types.ConstructBlocks, "Construct", "Blocks"}, {job_types.ConstructBlocks, "Construct", "Blocks"},
@ -570,12 +570,12 @@ function collect_reactions()
{job_types.MakeCage, "Make", "Cage"}, {job_types.MakeCage, "Make", "Cage"},
{job_types.MakePipeSection, "Make", "Pipe Section"}, {job_types.MakePipeSection, "Make", "Pipe Section"},
}, materials.wood) }, materials.wood)
resource_reactions(result, job_types.MakeTrapComponent, materials.wood, entity.resources.trapcomp_type, itemdefs.trapcomps, { resource_reactions(result, job_types.MakeTrapComponent, materials.wood, entity.resources.trapcomp_type, itemdefs.trapcomps, {
permissible = (function(itemdef) return itemdef.flags.WOOD end), permissible = (function(itemdef) return itemdef.flags.WOOD end),
adjective = true, adjective = true,
}) })
-- Rock items -- Rock items
material_reactions(result, { material_reactions(result, {
{job_types.ConstructDoor, "Construct", "Door"}, {job_types.ConstructDoor, "Construct", "Door"},
@ -591,12 +591,12 @@ function collect_reactions()
{job_types.MakeGoblet, "Make", "Mug"}, {job_types.MakeGoblet, "Make", "Mug"},
{job_types.MakeInstrument, "Make", "Instrument"}, {job_types.MakeInstrument, "Make", "Instrument"},
}, materials.rock) }, materials.rock)
resource_reactions(result, job_types.MakeTool, materials.rock, entity.resources.tool_type, itemdefs.tools, { resource_reactions(result, job_types.MakeTool, materials.rock, entity.resources.tool_type, itemdefs.tools, {
permissible = (function(itemdef) return itemdef.flags.HARD_MAT end), permissible = (function(itemdef) return itemdef.flags.HARD_MAT end),
capitalize = true, capitalize = true,
}) })
material_reactions(result, { material_reactions(result, {
{job_types.MakeToy, "Make", "Toy"}, {job_types.MakeToy, "Make", "Toy"},
{job_types.ConstructQuern, "Construct", "Quern"}, {job_types.ConstructQuern, "Construct", "Quern"},
@ -605,7 +605,7 @@ function collect_reactions()
{job_types.ConstructStatue, "Construct", "Statue"}, {job_types.ConstructStatue, "Construct", "Statue"},
{job_types.ConstructBlocks, "Construct", "Blocks"}, {job_types.ConstructBlocks, "Construct", "Blocks"},
}, materials.rock) }, materials.rock)
-- Glass items -- Glass items
for _, mat_info in ipairs(glasses) do for _, mat_info in ipairs(glasses) do
material_reactions(result, { material_reactions(result, {
@ -622,12 +622,12 @@ function collect_reactions()
{job_types.MakeGoblet, "Make", "Goblet"}, {job_types.MakeGoblet, "Make", "Goblet"},
{job_types.MakeInstrument, "Make", "Instrument"}, {job_types.MakeInstrument, "Make", "Instrument"},
}, mat_info) }, mat_info)
resource_reactions(result, job_types.MakeTool, mat_info, entity.resources.tool_type, itemdefs.tools, { resource_reactions(result, job_types.MakeTool, mat_info, entity.resources.tool_type, itemdefs.tools, {
permissible = (function(itemdef) return itemdef.flags.HARD_MAT end), permissible = (function(itemdef) return itemdef.flags.HARD_MAT end),
capitalize = true, capitalize = true,
}) })
material_reactions(result, { material_reactions(result, {
{job_types.MakeToy, "Make", "Toy"}, {job_types.MakeToy, "Make", "Toy"},
{job_types.ConstructStatue, "Construct", "Statue"}, {job_types.ConstructStatue, "Construct", "Statue"},
@ -635,44 +635,44 @@ function collect_reactions()
{job_types.MakeCage, "Make", "Terrarium"}, {job_types.MakeCage, "Make", "Terrarium"},
{job_types.MakePipeSection, "Make", "Tube"}, {job_types.MakePipeSection, "Make", "Tube"},
}, mat_info) }, mat_info)
resource_reactions(result, job_types.MakeTrapComponent, mat_info, entity.resources.trapcomp_type, itemdefs.trapcomps, { resource_reactions(result, job_types.MakeTrapComponent, mat_info, entity.resources.trapcomp_type, itemdefs.trapcomps, {
adjective = true, adjective = true,
}) })
end end
-- Bed, specified as wooden. -- Bed, specified as wooden.
table.insert(result, reaction_entry(job_types.ConstructBed, materials.wood.management)) table.insert(result, reaction_entry(job_types.ConstructBed, materials.wood.management))
-- Windows -- Windows
for _, mat_info in ipairs(glasses) do for _, mat_info in ipairs(glasses) do
material_reactions(result, { material_reactions(result, {
{job_types.MakeWindow, "Make", "Window"}, {job_types.MakeWindow, "Make", "Window"},
}, mat_info) }, mat_info)
end end
-- Rock Mechanisms -- Rock Mechanisms
table.insert(result, reaction_entry(job_types.ConstructMechanisms, materials.rock.management)) table.insert(result, reaction_entry(job_types.ConstructMechanisms, materials.rock.management))
resource_reactions(result, job_types.AssembleSiegeAmmo, materials.wood, entity.resources.siegeammo_type, itemdefs.siege_ammo, { resource_reactions(result, job_types.AssembleSiegeAmmo, materials.wood, entity.resources.siegeammo_type, itemdefs.siege_ammo, {
verb = "Assemble", verb = "Assemble",
}) })
for _, mat_info in ipairs(glasses) do for _, mat_info in ipairs(glasses) do
material_reactions(result, { material_reactions(result, {
{job_types.MakeRawGlass, "Make Raw", nil}, {job_types.MakeRawGlass, "Make Raw", nil},
}, mat_info) }, mat_info)
end end
material_reactions(result, { material_reactions(result, {
{job_types.MakeBackpack, "Make", "Backpack"}, {job_types.MakeBackpack, "Make", "Backpack"},
{job_types.MakeQuiver, "Make", "Quiver"}, {job_types.MakeQuiver, "Make", "Quiver"},
}, materials.leather) }, materials.leather)
for _, material in ipairs(cloth_mats) do for _, material in ipairs(cloth_mats) do
clothing_reactions(result, material, (function(itemdef) return itemdef.props.flags[material.clothing_flag or "SOFT"] end)) clothing_reactions(result, material, (function(itemdef) return itemdef.props.flags[material.clothing_flag or "SOFT"] end))
end end
-- Boxes, Bags, and Ropes -- Boxes, Bags, and Ropes
local boxmats = { local boxmats = {
{mats = {materials.wood}, box = "Chest"}, {mats = {materials.wood}, box = "Chest"},
@ -693,7 +693,7 @@ function collect_reactions()
end end
end end
end end
for _, mat in ipairs{ for _, mat in ipairs{
materials.wood, materials.wood,
materials.rock, materials.rock,
@ -709,28 +709,28 @@ function collect_reactions()
} do } do
material_reactions(result, {{job_types.MakeCrafts, "Make", "Crafts"}}, mat) material_reactions(result, {{job_types.MakeCrafts, "Make", "Crafts"}}, mat)
end end
-- Siege engine parts -- Siege engine parts
table.insert(result, reaction_entry(job_types.ConstructCatapultParts, materials.wood.management)) table.insert(result, reaction_entry(job_types.ConstructCatapultParts, materials.wood.management))
table.insert(result, reaction_entry(job_types.ConstructBallistaParts, materials.wood.management)) table.insert(result, reaction_entry(job_types.ConstructBallistaParts, materials.wood.management))
for _, mat in ipairs{materials.wood, materials.bone} do for _, mat in ipairs{materials.wood, materials.bone} do
resource_reactions(result, job_types.MakeAmmo, mat, entity.resources.ammo_type, itemdefs.ammo, { resource_reactions(result, job_types.MakeAmmo, mat, entity.resources.ammo_type, itemdefs.ammo, {
name_field = "name_plural", name_field = "name_plural",
}) })
end end
-- BARRED and SCALED as flag names don't quite seem to fit, here. -- BARRED and SCALED as flag names don't quite seem to fit, here.
clothing_reactions(result, materials.bone, (function(itemdef) return itemdef.props.flags.BARRED end)) clothing_reactions(result, materials.bone, (function(itemdef) return itemdef.props.flags.BARRED end))
clothing_reactions(result, materials.shell, (function(itemdef) return itemdef.props.flags.SCALED end)) clothing_reactions(result, materials.shell, (function(itemdef) return itemdef.props.flags.SCALED end))
for _, mat in ipairs{materials.wood, materials.leather} do for _, mat in ipairs{materials.wood, materials.leather} do
resource_reactions(result, job_types.MakeShield, mat, entity.resources.shield_type, itemdefs.shields, {}) resource_reactions(result, job_types.MakeShield, mat, entity.resources.shield_type, itemdefs.shields, {})
end end
-- Melt a Metal Object -- Melt a Metal Object
table.insert(result, reaction_entry(job_types.MeltMetalObject)) table.insert(result, reaction_entry(job_types.MeltMetalObject))
return result return result
end end
@ -782,7 +782,7 @@ function screen:onInput(keys)
self.search_string = self.search_string .. string.upper(char) self.search_string = self.search_string .. string.upper(char)
end end
end end
self:refilter() self:refilter()
end end
@ -799,7 +799,7 @@ function matchall(haystack, needles)
return false return false
end end
end end
return true return true
end end
@ -815,16 +815,16 @@ function splitstring(full, pattern)
elseif start > n then elseif start > n then
result[#result+1] = string.sub(full, n, start - 1) result[#result+1] = string.sub(full, n, start - 1)
end end
if stop < n then if stop < n then
-- The pattern matches an empty string. -- The pattern matches an empty string.
-- Avoid an infinite loop. -- Avoid an infinite loop.
break break
end end
n = stop + 1 n = stop + 1
end end
return result return result
end end
@ -839,18 +839,18 @@ function screen:refilter()
} }
end end
end end
if self.position < 1 then if self.position < 1 then
self.position = #filtered self.position = #filtered
elseif self.position > #filtered then elseif self.position > #filtered then
self.position = 1 self.position = 1
end end
local start = 1 local start = 1
while self.position >= start + PageSize*2 do while self.position >= start + PageSize*2 do
start = start + PageSize*2 start = start + PageSize*2
end end
local displayed = {} local displayed = {}
for n = 0, PageSize*2 - 1 do for n = 0, PageSize*2 - 1 do
local item = filtered[start + n] local item = filtered[start + n]
@ -858,7 +858,7 @@ function screen:refilter()
break break
end end
local name = item.name local name = item.name
local x = 1 local x = 1
local y = FirstRow + n local y = FirstRow + n
if n >= PageSize then if n >= PageSize then
@ -866,12 +866,12 @@ function screen:refilter()
y = y - PageSize y = y - PageSize
name = " "..name name = " "..name
end end
local color = COLOR_CYAN local color = COLOR_CYAN
if start + n == self.position then if start + n == self.position then
color = COLOR_LIGHTCYAN color = COLOR_LIGHTCYAN
end end
displayed[n + 1] = { displayed[n + 1] = {
x = x, x = x,
y = y, y = y,
@ -879,7 +879,7 @@ function screen:refilter()
color = color, color = color,
} }
end end
self.reactions = filtered self.reactions = filtered
self.displayed = displayed self.displayed = displayed
end end
@ -917,18 +917,18 @@ function orders_match(a, b)
"mat_type", "mat_type",
"mat_index", "mat_index",
} }
for _, fieldname in ipairs(fields) do for _, fieldname in ipairs(fields) do
if a[fieldname] ~= b[fieldname] then if a[fieldname] ~= b[fieldname] then
return false return false
end end
end end
local subtables = { local subtables = {
"item_category", "item_category",
"material_category", "material_category",
} }
for _, fieldname in ipairs(subtables) do for _, fieldname in ipairs(subtables) do
local aa = a[fieldname] local aa = a[fieldname]
local bb = b[fieldname] local bb = b[fieldname]
@ -938,7 +938,7 @@ function orders_match(a, b)
end end
end end
end end
return true return true
end end
@ -953,13 +953,13 @@ function order_quantity(order, quantity)
end end
end end
end end
if amount > 30 then if amount > 30 then
-- Respect the quantity limit. -- Respect the quantity limit.
-- With this many in the queue, we can wait for the next cycle. -- With this many in the queue, we can wait for the next cycle.
return 30 return 30
end end
return amount return amount
end end
@ -993,7 +993,7 @@ function countContents(container, settings)
total = total + 1 total = total + 1
end end
end end
return total return total
end end
@ -1009,7 +1009,7 @@ function check_stockpiles(verbose)
result[reaction] = (result[reaction] or 0) + amount result[reaction] = (result[reaction] or 0) + amount
end end
end end
return result return result
end end
@ -1030,7 +1030,7 @@ function check_pile(sp, verbose)
end end
end end
end end
for _, item in ipairs(dfhack.buildings.getStockpileContents(sp)) do for _, item in ipairs(dfhack.buildings.getStockpileContents(sp)) do
if item:isAssignedToThisStockpile(sp.id) then if item:isAssignedToThisStockpile(sp.id) then
-- This is a bin or barrel associated with the stockpile. -- This is a bin or barrel associated with the stockpile.
@ -1039,14 +1039,14 @@ function check_pile(sp, verbose)
filled = filled + 1 filled = filled + 1
end end
end end
if verbose then if verbose then
print("Stockpile #"..sp.stockpile_number, print("Stockpile #"..sp.stockpile_number,
string.format("%3d spaces", numspaces), string.format("%3d spaces", numspaces),
string.format("%4d items", filled), string.format("%4d items", filled),
string.format("%4d empty spaces", empty)) string.format("%4d empty spaces", empty))
end end
return filled, empty return filled, empty
end end
@ -1094,7 +1094,7 @@ function matches_stockpile(item, settings)
elseif df.item_threadst:is_instance(item) then elseif df.item_threadst:is_instance(item) then
return settings.flags.cloth return settings.flags.cloth
end end
return true return true
end end

@ -149,7 +149,7 @@ command_result mapexport (color_ostream &out, std::vector <std::string> & parame
protomap.set_z_size(z_max); protomap.set_z_size(z_max);
out << "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++)
{ {
dfproto::Material *protomaterial = protomap.add_inorganic_material(); dfproto::Material *protomaterial = protomap.add_inorganic_material();
@ -173,10 +173,10 @@ command_result mapexport (color_ostream &out, std::vector <std::string> & parame
constructionMaterials[construction->pos] = std::make_pair(construction->mat_index, construction->mat_type); constructionMaterials[construction->pos] = std::make_pair(construction->mat_index, construction->mat_type);
} }
} }
coded_output->WriteVarint32(protomap.ByteSize()); coded_output->WriteVarint32(protomap.ByteSize());
protomap.SerializeToCodedStream(coded_output); protomap.SerializeToCodedStream(coded_output);
DFHack::t_feature blockFeatureGlobal; DFHack::t_feature blockFeatureGlobal;
DFHack::t_feature blockFeatureLocal; DFHack::t_feature blockFeatureLocal;
@ -239,7 +239,7 @@ command_result mapexport (color_ostream &out, std::vector <std::string> & parame
prototile->set_tile_material(toProto(tileMaterial(type))); prototile->set_tile_material(toProto(tileMaterial(type)));
df::coord map_pos = df::coord(b_x*16+x,b_y*16+y,z); df::coord map_pos = df::coord(b_x*16+x,b_y*16+y,z);
switch (tileMaterial(type)) switch (tileMaterial(type))
{ {
case tiletype_material::SOIL: case tiletype_material::SOIL:
@ -300,7 +300,7 @@ command_result mapexport (color_ostream &out, std::vector <std::string> & parame
} }
} }
} }
coded_output->WriteVarint32(protoblock.ByteSize()); coded_output->WriteVarint32(protoblock.ByteSize());
protoblock.SerializeToCodedStream(coded_output); protoblock.SerializeToCodedStream(coded_output);
} // block x } // block x

@ -5,23 +5,23 @@ message Tile
{ {
enum TileType enum TileType
{ {
EMPTY = 0; EMPTY = 0;
FLOOR = 1; FLOOR = 1;
BOULDER = 2; BOULDER = 2;
PEBBLES = 3; PEBBLES = 3;
WALL = 4; WALL = 4;
FORTIFICATION = 5; FORTIFICATION = 5;
STAIR_UP = 6; STAIR_UP = 6;
STAIR_DOWN = 7; STAIR_DOWN = 7;
STAIR_UPDOWN = 8; STAIR_UPDOWN = 8;
RAMP = 9; RAMP = 9;
RAMP_TOP = 10; RAMP_TOP = 10;
BROOK_BED = 11; BROOK_BED = 11;
BROOK_TOP = 12; BROOK_TOP = 12;
TREE = 13; TREE = 13;
SAPLING = 14; SAPLING = 14;
SHRUB = 15; SHRUB = 15;
ENDLESS_PIT = 16; ENDLESS_PIT = 16;
} }
enum LiquidType enum LiquidType
{ {
@ -49,8 +49,8 @@ message Tile
MAGMA_TYPE = 16; MAGMA_TYPE = 16;
DRIFTWOOD = 17; DRIFTWOOD = 17;
POOL = 18; POOL = 18;
BROOK = 19; BROOK = 19;
RIVER = 20; RIVER = 20;
} }
required uint32 x = 1; required uint32 x = 1;
required uint32 y = 2; required uint32 y = 2;

@ -49,7 +49,7 @@ DFhackCExport command_result plugin_onupdate(color_ostream& out) {
} }
return CR_OK; return CR_OK;
} }
if ( !wasLoaded ) { if ( !wasLoaded ) {
wasLoaded = true; wasLoaded = true;
} }
@ -59,7 +59,7 @@ DFhackCExport command_result plugin_onupdate(color_ostream& out) {
return CR_OK; return CR_OK;
} }
count = 0; count = 0;
int32_t race_id = ui->race_id; int32_t race_id = ui->race_id;
int32_t civ_id = ui->civ_id; int32_t civ_id = ui->civ_id;
for ( size_t a = 0; a < world->units.all.size(); a++ ) { for ( size_t a = 0; a < world->units.all.size(); a++ ) {
@ -69,7 +69,7 @@ DFhackCExport command_result plugin_onupdate(color_ostream& out) {
continue; continue;
if ( unit->flags1.bits.dead ) if ( unit->flags1.bits.dead )
continue; continue;
int processedThoughtCount; int processedThoughtCount;
map<int,int>::iterator i = processedThoughtCountTable.find(unit->id); map<int,int>::iterator i = processedThoughtCountTable.find(unit->id);
if ( i == processedThoughtCountTable.end() ) { if ( i == processedThoughtCountTable.end() ) {
@ -78,13 +78,13 @@ DFhackCExport command_result plugin_onupdate(color_ostream& out) {
} else { } else {
processedThoughtCount = (*i).second; processedThoughtCount = (*i).second;
} }
if ( processedThoughtCount == unit->status.recent_events.size() ) { if ( processedThoughtCount == unit->status.recent_events.size() ) {
continue; continue;
} else if ( processedThoughtCount > unit->status.recent_events.size() ) { } else if ( processedThoughtCount > unit->status.recent_events.size() ) {
processedThoughtCount = unit->status.recent_events.size(); processedThoughtCount = unit->status.recent_events.size();
} }
//don't reprocess any old thoughts //don't reprocess any old thoughts
vector<df::unit_thought*> newThoughts; vector<df::unit_thought*> newThoughts;
for ( size_t b = processedThoughtCount; b < unit->status.recent_events.size(); b++ ) { for ( size_t b = processedThoughtCount; b < unit->status.recent_events.size(); b++ ) {
@ -120,7 +120,7 @@ DFhackCExport command_result plugin_onupdate(color_ostream& out) {
} }
processedThoughtCountTable[unit->id] = unit->status.recent_events.size(); processedThoughtCountTable[unit->id] = unit->status.recent_events.size();
} }
return CR_OK; return CR_OK;
} }
@ -159,11 +159,11 @@ command_result misery(color_ostream &out, vector<string>& parameters) {
out.printerr("misery can only be enabled in fortress mode with a fully-loaded game.\n"); out.printerr("misery can only be enabled in fortress mode with a fully-loaded game.\n");
return CR_FAILURE; return CR_FAILURE;
} }
if ( parameters.size() < 1 || parameters.size() > 2 ) { if ( parameters.size() < 1 || parameters.size() > 2 ) {
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
if ( parameters[0] == "disable" ) { if ( parameters[0] == "disable" ) {
if ( parameters.size() > 1 ) { if ( parameters.size() > 1 ) {
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
@ -197,7 +197,7 @@ command_result misery(color_ostream &out, vector<string>& parameters) {
factor = a; factor = a;
is_enabled = factor > 1; is_enabled = factor > 1;
} }
return CR_OK; return CR_OK;
} }

@ -90,7 +90,7 @@ void impregnateMany() {
else else
females[unit->race].push_back(a); females[unit->race].push_back(a);
} }
for ( auto i = females.begin(); i != females.end(); i++ ) { for ( auto i = females.begin(); i != females.end(); i++ ) {
int32_t race = i->first; int32_t race = i->first;
vector<int32_t>& femalesList = i->second; vector<int32_t>& femalesList = i->second;
@ -99,10 +99,10 @@ void impregnateMany() {
break; break;
vector<int32_t> compatibles; vector<int32_t> compatibles;
df::coord pos1 = units[femalesList[a]]->pos; df::coord pos1 = units[femalesList[a]]->pos;
if ( males.find(i->first) == males.end() ) if ( males.find(i->first) == males.end() )
continue; continue;
vector<int32_t>& malesList = males[i->first]; vector<int32_t>& malesList = males[i->first];
for ( size_t b = 0; b < malesList.size(); b++ ) { for ( size_t b = 0; b < malesList.size(); b++ ) {
df::coord pos2 = units[malesList[b]]->pos; df::coord pos2 = units[malesList[b]]->pos;
@ -111,7 +111,7 @@ void impregnateMany() {
} }
if ( compatibles.empty() ) if ( compatibles.empty() )
continue; continue;
size_t maleIndex = (size_t)(compatibles.size()*((float)rand() / (1+(float)RAND_MAX))); size_t maleIndex = (size_t)(compatibles.size()*((float)rand() / (1+(float)RAND_MAX)));
if ( impregnate(units[femalesList[a]], units[compatibles[maleIndex]]) ) if ( impregnate(units[femalesList[a]], units[compatibles[maleIndex]]) )
popcount[race]++; popcount[race]++;
@ -124,7 +124,7 @@ bool impregnate(df::unit* female, df::unit* male) {
return false; return false;
if ( female->relations.pregnancy_genes ) if ( female->relations.pregnancy_genes )
return false; return false;
df::unit_genes* preg = new df::unit_genes; df::unit_genes* preg = new df::unit_genes;
*preg = male->appearance.genes; *preg = male->appearance.genes;
female->relations.pregnancy_genes = preg; female->relations.pregnancy_genes = preg;
@ -138,7 +138,7 @@ void tickHandler(color_ostream& out, void* data) {
return; return;
CoreSuspender suspend; CoreSuspender suspend;
impregnateMany(); impregnateMany();
EventManager::unregisterAll(plugin_self); EventManager::unregisterAll(plugin_self);
EventManager::EventHandler handle(tickHandler, howOften); EventManager::EventHandler handle(tickHandler, howOften);
EventManager::registerTick(handle, howOften, plugin_self); EventManager::registerTick(handle, howOften, plugin_self);
@ -147,7 +147,7 @@ void tickHandler(color_ostream& out, void* data) {
command_result petcapRemover (color_ostream &out, std::vector <std::string> & parameters) command_result petcapRemover (color_ostream &out, std::vector <std::string> & parameters)
{ {
CoreSuspender suspend; CoreSuspender suspend;
for ( size_t a = 0; a < parameters.size(); a++ ) { for ( size_t a = 0; a < parameters.size(); a++ ) {
if ( parameters[a] == "every" ) { if ( parameters[a] == "every" ) {
if ( a+1 >= parameters.size() ) if ( a+1 >= parameters.size() )
@ -186,18 +186,18 @@ command_result petcapRemover (color_ostream &out, std::vector <std::string> & pa
out.print("%s, line %d: invalid argument: %s\n", __FILE__, __LINE__, parameters[a].c_str()); out.print("%s, line %d: invalid argument: %s\n", __FILE__, __LINE__, parameters[a].c_str());
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
if ( howOften < 0 ) { if ( howOften < 0 ) {
is_enabled = false; is_enabled = false;
return CR_OK; return CR_OK;
} }
is_enabled = true; is_enabled = true;
EventManager::unregisterAll(plugin_self); EventManager::unregisterAll(plugin_self);
EventManager::EventHandler handle(tickHandler, howOften); EventManager::EventHandler handle(tickHandler, howOften);
EventManager::registerTick(handle, howOften, plugin_self); EventManager::registerTick(handle, howOften, plugin_self);
out.print("petcapRemover: howOften = every %d ticks, popcap per species = %d, preg time = %d ticks.\n", howOften, popcap, pregtime); out.print("petcapRemover: howOften = every %d ticks, popcap per species = %d, preg time = %d ticks.\n", howOften, popcap, pregtime);
return CR_OK; return CR_OK;
} }

@ -84,7 +84,7 @@ command_result df_cprobe (color_ostream &out, vector <string> & parameters)
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)
{ {
out.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);
for(size_t j=0; j<unit->inventory.size(); j++) for(size_t j=0; j<unit->inventory.size(); j++)
{ {
df::unit_inventory_item* inv_item = unit->inventory[j]; df::unit_inventory_item* inv_item = unit->inventory[j];
@ -101,7 +101,7 @@ command_result df_cprobe (color_ostream &out, vector <string> & parameters)
out << endl; out << endl;
} }
} }
// don't leave loop, there may be more than 1 creature at the cursor position // don't leave loop, there may be more than 1 creature at the cursor position
//break; //break;
} }
@ -242,7 +242,7 @@ command_result df_probe (color_ostream &out, vector <string> & parameters)
const char* surroundings[] = { "Serene", "Mirthful", "Joyous Wilds", "Calm", "Wilderness", "Untamed Wilds", "Sinister", "Haunted", "Terrifying" }; const char* surroundings[] = { "Serene", "Mirthful", "Joyous Wilds", "Calm", "Wilderness", "Untamed Wilds", "Sinister", "Haunted", "Terrifying" };
// biome, geolayer // biome, geolayer
out << "biome: " << des.bits.biome << " (" << out << "biome: " << des.bits.biome << " (" <<
"region id=" << biome->region_id << ", " << "region id=" << biome->region_id << ", " <<
surroundings[surr] << ", " << surroundings[surr] << ", " <<
"savagery " << biome->savagery << ", " << "savagery " << biome->savagery << ", " <<
@ -345,7 +345,7 @@ command_result df_probe (color_ostream &out, vector <string> & parameters)
out << "no grow" << endl; out << "no grow" << endl;
for(size_t e=0; e<block.block_events.size(); e++) for(size_t e=0; e<block.block_events.size(); e++)
{ {
df::block_square_event * blev = block.block_events[e]; df::block_square_event * blev = block.block_events[e];
df::block_square_event_type blevtype = blev->getType(); df::block_square_event_type blevtype = blev->getType();
switch(blevtype) switch(blevtype)

@ -153,7 +153,7 @@ void printMats(color_ostream &con, MatMap &mat, std::vector<T*> &materials, bool
{ {
if(it->first >= materials.size()) if(it->first >= materials.size())
{ {
con << "Bad index: " << it->first << " out of " con << "Bad index: " << it->first << " out of "
<< materials.size() << endl; << materials.size() << endl;
continue; continue;
} }

@ -4,205 +4,205 @@ package RemoteFortressReader;
option optimize_for = LITE_RUNTIME; option optimize_for = LITE_RUNTIME;
//We use shapes, etc, because the actual tiletypes may differ between DF versions. //We use shapes, etc, because the actual tiletypes may differ between DF versions.
enum TiletypeShape enum TiletypeShape
{ {
NO_SHAPE = -1; NO_SHAPE = -1;
EMPTY = 0; EMPTY = 0;
FLOOR = 1; FLOOR = 1;
BOULDER = 2; BOULDER = 2;
PEBBLES = 3; PEBBLES = 3;
WALL = 4; WALL = 4;
FORTIFICATION = 5; FORTIFICATION = 5;
STAIR_UP = 6; STAIR_UP = 6;
STAIR_DOWN = 7; STAIR_DOWN = 7;
STAIR_UPDOWN = 8; STAIR_UPDOWN = 8;
RAMP = 9; RAMP = 9;
RAMP_TOP = 10; RAMP_TOP = 10;
BROOK_BED = 11; BROOK_BED = 11;
BROOK_TOP = 12; BROOK_TOP = 12;
TREE_SHAPE = 13; TREE_SHAPE = 13;
SAPLING = 14; SAPLING = 14;
SHRUB = 15; SHRUB = 15;
ENDLESS_PIT = 16; ENDLESS_PIT = 16;
BRANCH = 17; BRANCH = 17;
TRUNK_BRANCH = 18; TRUNK_BRANCH = 18;
TWIG = 19; TWIG = 19;
} }
enum TiletypeSpecial enum TiletypeSpecial
{ {
NO_SPECIAL = -1; NO_SPECIAL = -1;
NORMAL = 0; NORMAL = 0;
RIVER_SOURCE = 1; RIVER_SOURCE = 1;
WATERFALL = 2; WATERFALL = 2;
SMOOTH = 3; SMOOTH = 3;
FURROWED = 4; FURROWED = 4;
WET = 5; WET = 5;
DEAD = 6; DEAD = 6;
WORN_1 = 7; WORN_1 = 7;
WORN_2 = 8; WORN_2 = 8;
WORN_3 = 9; WORN_3 = 9;
TRACK = 10; TRACK = 10;
SMOOTH_DEAD = 11; SMOOTH_DEAD = 11;
}; };
enum TiletypeMaterial enum TiletypeMaterial
{ {
NO_MATERIAL = -1; NO_MATERIAL = -1;
AIR = 0; AIR = 0;
SOIL = 1; SOIL = 1;
STONE = 2; STONE = 2;
FEATURE = 3; FEATURE = 3;
LAVA_STONE = 4; LAVA_STONE = 4;
MINERAL = 5; MINERAL = 5;
FROZEN_LIQUID = 6; FROZEN_LIQUID = 6;
CONSTRUCTION = 7; CONSTRUCTION = 7;
GRASS_LIGHT = 8; GRASS_LIGHT = 8;
GRASS_DARK = 9; GRASS_DARK = 9;
GRASS_DRY = 10; GRASS_DRY = 10;
GRASS_DEAD = 11; GRASS_DEAD = 11;
PLANT = 12; PLANT = 12;
HFS = 13; HFS = 13;
CAMPFIRE = 14; CAMPFIRE = 14;
FIRE = 15; FIRE = 15;
ASHES = 16; ASHES = 16;
MAGMA = 17; MAGMA = 17;
DRIFTWOOD = 18; DRIFTWOOD = 18;
POOL = 19; POOL = 19;
BROOK = 20; BROOK = 20;
RIVER = 21; RIVER = 21;
ROOT = 22; ROOT = 22;
TREE_MATERIAL = 23; TREE_MATERIAL = 23;
MUSHROOM = 24; MUSHROOM = 24;
UNDERWORLD_GATE = 25; UNDERWORLD_GATE = 25;
} }
enum TiletypeVariant enum TiletypeVariant
{ {
NO_VARIANT = -1; NO_VARIANT = -1;
VAR_1 = 0; VAR_1 = 0;
VAR_2 = 1; VAR_2 = 1;
VAR_3 = 2; VAR_3 = 2;
VAR_4 = 3; VAR_4 = 3;
}; };
message Tiletype message Tiletype
{ {
required int32 id = 1; required int32 id = 1;
optional string name = 2; optional string name = 2;
optional string caption = 3; optional string caption = 3;
optional TiletypeShape shape = 4; optional TiletypeShape shape = 4;
optional TiletypeSpecial special = 5; optional TiletypeSpecial special = 5;
optional TiletypeMaterial material = 6; optional TiletypeMaterial material = 6;
optional TiletypeVariant variant = 7; optional TiletypeVariant variant = 7;
optional string direction = 8; optional string direction = 8;
}; };
message TiletypeList message TiletypeList
{ {
repeated Tiletype tiletype_list = 1; repeated Tiletype tiletype_list = 1;
} }
message MapBlock message MapBlock
{ {
required int32 map_x = 1; required int32 map_x = 1;
required int32 map_y = 2; required int32 map_y = 2;
required int32 map_z = 3; required int32 map_z = 3;
repeated int32 tiles = 4; repeated int32 tiles = 4;
repeated MatPair materials = 5; repeated MatPair materials = 5;
repeated MatPair layer_materials = 6; repeated MatPair layer_materials = 6;
repeated MatPair vein_materials = 7; repeated MatPair vein_materials = 7;
repeated MatPair base_materials = 8; repeated MatPair base_materials = 8;
repeated int32 magma = 9; repeated int32 magma = 9;
repeated int32 water = 10; repeated int32 water = 10;
} }
message MatPair { message MatPair {
required int32 mat_type = 1; required int32 mat_type = 1;
required int32 mat_index = 2; required int32 mat_index = 2;
} }
message ColorDefinition { message ColorDefinition {
required int32 red = 1; required int32 red = 1;
required int32 green = 2; required int32 green = 2;
required int32 blue = 3; required int32 blue = 3;
} }
message MaterialDefinition{ message MaterialDefinition{
required MatPair mat_pair = 1; required MatPair mat_pair = 1;
optional string id = 2; optional string id = 2;
optional string name = 3; optional string name = 3;
optional ColorDefinition state_color = 4; //Simplifying colors to assume room temperature. optional ColorDefinition state_color = 4; //Simplifying colors to assume room temperature.
} }
message MaterialList{ message MaterialList{
repeated MaterialDefinition material_list = 1; repeated MaterialDefinition material_list = 1;
} }
message UnitDefinition message UnitDefinition
{ {
required int32 id = 1; required int32 id = 1;
optional bool isValid = 2; optional bool isValid = 2;
optional int32 pos_x = 3; optional int32 pos_x = 3;
optional int32 pos_y = 4; optional int32 pos_y = 4;
optional int32 pos_z = 5; optional int32 pos_z = 5;
} }
message UnitList message UnitList
{ {
repeated UnitDefinition creature_list = 1; repeated UnitDefinition creature_list = 1;
} }
message BlockRequest message BlockRequest
{ {
optional int32 blocks_needed = 1; optional int32 blocks_needed = 1;
optional int32 min_x = 2; optional int32 min_x = 2;
optional int32 max_x = 3; optional int32 max_x = 3;
optional int32 min_y = 4; optional int32 min_y = 4;
optional int32 max_y = 5; optional int32 max_y = 5;
optional int32 min_z = 6; optional int32 min_z = 6;
optional int32 max_z = 7; optional int32 max_z = 7;
} }
message BlockList message BlockList
{ {
repeated MapBlock map_blocks = 1; repeated MapBlock map_blocks = 1;
optional int32 map_x = 2; optional int32 map_x = 2;
optional int32 map_y = 3; optional int32 map_y = 3;
} }
message PlantDef message PlantDef
{ {
required int32 pos_x = 1; required int32 pos_x = 1;
required int32 pos_y = 2; required int32 pos_y = 2;
required int32 pos_z = 3; required int32 pos_z = 3;
required int32 index = 4; required int32 index = 4;
} }
message PlantList message PlantList
{ {
repeated PlantDef plant_list = 1; repeated PlantDef plant_list = 1;
} }
message ViewInfo message ViewInfo
{ {
optional int32 view_pos_x = 1; optional int32 view_pos_x = 1;
optional int32 view_pos_y = 2; optional int32 view_pos_y = 2;
optional int32 view_pos_z = 3; optional int32 view_pos_z = 3;
optional int32 view_size_x = 4; optional int32 view_size_x = 4;
optional int32 view_size_y = 5; optional int32 view_size_y = 5;
optional int32 cursor_pos_x = 6; optional int32 cursor_pos_x = 6;
optional int32 cursor_pos_y = 7; optional int32 cursor_pos_y = 7;
optional int32 cursor_pos_z = 8; optional int32 cursor_pos_z = 8;
} }
message MapInfo message MapInfo
{ {
optional int32 block_size_x = 1; optional int32 block_size_x = 1;
optional int32 block_size_y = 2; optional int32 block_size_y = 2;
optional int32 block_size_z = 3; optional int32 block_size_z = 3;
optional int32 block_pos_x = 4; optional int32 block_pos_x = 4;
optional int32 block_pos_y = 5; optional int32 block_pos_y = 5;
optional int32 block_pos_z = 6; optional int32 block_pos_z = 6;
optional string world_name = 7; optional string world_name = 7;
optional string world_name_english = 8; optional string world_name_english = 8;
optional string save_name = 9; optional string save_name = 9;
} }

@ -4,73 +4,73 @@ package isoworldremote;
option optimize_for = LITE_RUNTIME; option optimize_for = LITE_RUNTIME;
enum BasicMaterial { enum BasicMaterial {
AIR = 0; AIR = 0;
OTHER = 1; OTHER = 1;
INORGANIC = 2; INORGANIC = 2;
LIQUID = 3; LIQUID = 3;
PLANT = 4; PLANT = 4;
WOOD = 5; WOOD = 5;
}; };
enum LiquidType { enum LiquidType {
ICE = 0; ICE = 0;
WATER = 1; WATER = 1;
MAGMA = 2; MAGMA = 2;
} }
enum BasicShape { enum BasicShape {
NONE = 0; NONE = 0;
OPEN = 1; OPEN = 1;
WALL = 3; WALL = 3;
FLOOR = 4; FLOOR = 4;
RAMP_UP = 5; RAMP_UP = 5;
RAMP_DOWN = 6; RAMP_DOWN = 6;
} }
message ColorDefinition { message ColorDefinition {
required int32 red = 1; required int32 red = 1;
required int32 green = 2; required int32 green = 2;
required int32 blue = 3; required int32 blue = 3;
} }
message EmbarkTileLayer { message EmbarkTileLayer {
repeated BasicMaterial mat_type_table = 4 [packed=true]; repeated BasicMaterial mat_type_table = 4 [packed=true];
repeated int32 mat_subtype_table = 5 [packed=true]; repeated int32 mat_subtype_table = 5 [packed=true];
repeated BasicShape tile_shape_table = 6 [packed=true]; repeated BasicShape tile_shape_table = 6 [packed=true];
repeated ColorDefinition tile_color_table = 7; repeated ColorDefinition tile_color_table = 7;
} }
message EmbarkTile { message EmbarkTile {
required int32 world_x = 1; required int32 world_x = 1;
required int32 world_y = 2; required int32 world_y = 2;
required sint32 world_z = 3; required sint32 world_z = 3;
repeated EmbarkTileLayer tile_layer = 4; repeated EmbarkTileLayer tile_layer = 4;
optional int32 current_year = 5; optional int32 current_year = 5;
optional int32 current_season = 6; optional int32 current_season = 6;
optional bool is_valid = 7; optional bool is_valid = 7;
} }
message TileRequest { message TileRequest {
optional int32 want_x = 1; optional int32 want_x = 1;
optional int32 want_y = 2; optional int32 want_y = 2;
} }
message MapRequest { message MapRequest {
optional string save_folder = 1; optional string save_folder = 1;
} }
message MapReply { message MapReply {
required bool available = 1; required bool available = 1;
optional int32 region_x = 2; optional int32 region_x = 2;
optional int32 region_y = 3; optional int32 region_y = 3;
optional int32 region_size_x = 4; optional int32 region_size_x = 4;
optional int32 region_size_y = 5; optional int32 region_size_y = 5;
optional int32 current_year = 6; optional int32 current_year = 6;
optional int32 current_season = 7; optional int32 current_season = 7;
} }
message RawNames { message RawNames {
required bool available = 1; required bool available = 1;
repeated string inorganic = 2; repeated string inorganic = 2;
repeated string organic = 3; repeated string organic = 3;
} }

@ -60,7 +60,7 @@ command_result df_regrass (color_ostream &out, vector <string> & parameters)
// check block for grass events before looking at 16x16 tiles // check block for grass events before looking at 16x16 tiles
df::block_square_event_grassst * grev = NULL; df::block_square_event_grassst * grev = NULL;
for(size_t e=0; e<cur->block_events.size(); e++) for(size_t e=0; e<cur->block_events.size(); e++)
{ {
df::block_square_event * blev = cur->block_events[e]; df::block_square_event * blev = cur->block_events[e];
df::block_square_event_type blevtype = blev->getType(); df::block_square_event_type blevtype = blev->getType();
if(blevtype == df::block_square_event_type::grass) if(blevtype == df::block_square_event_type::grass)
@ -103,7 +103,7 @@ command_result df_regrass (color_ostream &out, vector <string> & parameters)
if(max) if(max)
{ {
for(size_t e=0; e<cur->block_events.size(); e++) for(size_t e=0; e<cur->block_events.size(); e++)
{ {
df::block_square_event * blev = cur->block_events[e]; df::block_square_event * blev = cur->block_events[e];
df::block_square_event_type blevtype = blev->getType(); df::block_square_event_type blevtype = blev->getType();
if(blevtype == df::block_square_event_type::grass) if(blevtype == df::block_square_event_type::grass)
@ -118,7 +118,7 @@ command_result df_regrass (color_ostream &out, vector <string> & parameters)
// try to find the 'original' event // try to find the 'original' event
bool regrew = false; bool regrew = false;
for(size_t e=0; e<cur->block_events.size(); e++) for(size_t e=0; e<cur->block_events.size(); e++)
{ {
df::block_square_event * blev = cur->block_events[e]; df::block_square_event * blev = cur->block_events[e];
df::block_square_event_type blevtype = blev->getType(); df::block_square_event_type blevtype = blev->getType();
if(blevtype == df::block_square_event_type::grass) if(blevtype == df::block_square_event_type::grass)
@ -138,7 +138,7 @@ command_result df_regrass (color_ostream &out, vector <string> & parameters)
{ {
vector <df::block_square_event_grassst *> gr_evs; vector <df::block_square_event_grassst *> gr_evs;
for(size_t e=0; e<cur->block_events.size(); e++) for(size_t e=0; e<cur->block_events.size(); e++)
{ {
df::block_square_event * blev = cur->block_events[e]; df::block_square_event * blev = cur->block_events[e];
df::block_square_event_type blevtype = blev->getType(); df::block_square_event_type blevtype = blev->getType();
if(blevtype == df::block_square_event_type::grass) if(blevtype == df::block_square_event_type::grass)

@ -79,7 +79,7 @@ rect2d getMapViewport()
} }
else else
return mkrect_wh(0,0,0,0); return mkrect_wh(0,0,0,0);
} }
int w=gps->dimx; int w=gps->dimx;
int h=gps->dimy; int h=gps->dimy;
@ -88,7 +88,7 @@ rect2d getMapViewport()
int menu_x2=w-MENU_WIDTH-2; int menu_x2=w-MENU_WIDTH-2;
int menu_x1=area_x2-MENU_WIDTH-1; int menu_x1=area_x2-MENU_WIDTH-1;
int view_rb=w-1; int view_rb=w-1;
int area_pos=*df::global::ui_area_map_width; int area_pos=*df::global::ui_area_map_width;
int menu_pos=*df::global::ui_menu_width; int menu_pos=*df::global::ui_menu_width;
if(area_pos<3) if(area_pos<3)
@ -97,7 +97,7 @@ rect2d getMapViewport()
} }
if (menu_pos<area_pos || df::global::ui->main.mode!=0) if (menu_pos<area_pos || df::global::ui->main.mode!=0)
{ {
if (menu_pos >= area_pos) if (menu_pos >= area_pos)
menu_pos = area_pos-1; menu_pos = area_pos-1;
int menu_x = menu_x2; int menu_x = menu_x2;
if(menu_pos < 2) menu_x = menu_x1; if(menu_pos < 2) menu_x = menu_x1;
@ -128,7 +128,7 @@ void lightingEngineViewscreen::reinit()
void plotCircle(int xm, int ym, int r,const std::function<void(int,int)>& setPixel) void plotCircle(int xm, int ym, int r,const std::function<void(int,int)>& setPixel)
{ {
int x = -r, y = 0, err = 2-2*r; /* II. Quadrant */ int x = -r, y = 0, err = 2-2*r; /* II. Quadrant */
do { do {
setPixel(xm-x, ym+y); /* I. Quadrant */ setPixel(xm-x, ym+y); /* I. Quadrant */
setPixel(xm-y, ym-x); /* II. Quadrant */ setPixel(xm-y, ym-x); /* II. Quadrant */
@ -156,7 +156,7 @@ void plotSquare(int xm, int ym, int r,const std::function<void(int,int)>& setPix
void plotLine(int x0, int y0, int x1, int y1,rgbf power,const std::function<rgbf(rgbf,int,int,int,int)>& setPixel) void plotLine(int x0, int y0, int x1, int y1,rgbf power,const std::function<rgbf(rgbf,int,int,int,int)>& setPixel)
{ {
int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1; int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
int dy = -abs(y1-y0), sy = y0<y1 ? 1 : -1; int dy = -abs(y1-y0), sy = y0<y1 ? 1 : -1;
int err = dx+dy, e2; /* error value e_xy */ int err = dx+dy, e2; /* error value e_xy */
int rdx=0; int rdx=0;
int rdy=0; int rdy=0;
@ -177,9 +177,9 @@ void plotLine(int x0, int y0, int x1, int y1,rgbf power,const std::function<rgbf
} }
void plotLineDiffuse(int x0, int y0, int x1, int y1,rgbf power,int num_diffuse,const std::function<rgbf(rgbf,int,int,int,int)>& setPixel,bool skip_hack=false) void plotLineDiffuse(int x0, int y0, int x1, int y1,rgbf power,int num_diffuse,const std::function<rgbf(rgbf,int,int,int,int)>& setPixel,bool skip_hack=false)
{ {
int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1; int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
int dy = -abs(y1-y0), sy = y0<y1 ? 1 : -1; int dy = -abs(y1-y0), sy = y0<y1 ? 1 : -1;
int dsq=dx*dx+dy*dy; int dsq=dx*dx+dy*dy;
int err = dx+dy, e2; /* error value e_xy */ int err = dx+dy, e2; /* error value e_xy */
int rdx=0; int rdx=0;
@ -214,7 +214,7 @@ void plotLineDiffuse(int x0, int y0, int x1, int y1,rgbf power,int num_diffuse,c
void plotLineAA(int x0, int y0, int x1, int y1,rgbf power,const std::function<rgbf(rgbf,int,int,int,int)>& setPixelAA) void plotLineAA(int x0, int y0, int x1, int y1,rgbf power,const std::function<rgbf(rgbf,int,int,int,int)>& setPixelAA)
{ {
int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1; int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1; int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1;
int err = dx-dy, e2, x2; /* error value e_xy */ int err = dx-dy, e2, x2; /* error value e_xy */
int ed = dx+dy == 0 ? 1 : sqrt((float)dx*dx+(float)dy*dy); int ed = dx+dy == 0 ? 1 : sqrt((float)dx*dx+(float)dy*dy);
int rdx=0; int rdx=0;
@ -232,7 +232,7 @@ void plotLineAA(int x0, int y0, int x1, int y1,rgbf power,const std::function<rg
rdx=rdy=0; rdx=rdy=0;
if (2*e2 >= -dx) { /* x step */ if (2*e2 >= -dx) { /* x step */
if (x0 == x1) break; if (x0 == x1) break;
if (e2+dy < ed) if (e2+dy < ed)
{ {
str=1-(e2+dy)/(float)ed; str=1-(e2+dy)/(float)ed;
@ -240,11 +240,11 @@ void plotLineAA(int x0, int y0, int x1, int y1,rgbf power,const std::function<rg
strsum+=str; strsum+=str;
} }
err -= dy; x0 += sx; rdx=sx; err -= dy; x0 += sx; rdx=sx;
} }
if (2*e2 <= dy) { /* y step */ if (2*e2 <= dy) { /* y step */
if (y0 == y1) break; if (y0 == y1) break;
if (dx-e2 < ed) if (dx-e2 < ed)
{ {
str=1-(dx-e2)/(float)ed; str=1-(dx-e2)/(float)ed;
sumPower+=setPixelAA(power*str,lrdx,lrdy,x2+sx,y0); sumPower+=setPixelAA(power*str,lrdx,lrdy,x2+sx,y0);
@ -320,16 +320,16 @@ void lightingEngineViewscreen::updateWindow()
else else
std::swap(lightMap,myRenderer->lightGrid); std::swap(lightMap,myRenderer->lightGrid);
rect2d vp=getMapViewport(); rect2d vp=getMapViewport();
myRenderer->invalidateRect(vp.first.x,vp.first.y,vp.second.x-vp.first.x,vp.second.y-vp.first.y); myRenderer->invalidateRect(vp.first.x,vp.first.y,vp.second.x-vp.first.x,vp.second.y-vp.first.y);
} }
void lightingEngineViewscreen::preRender() void lightingEngineViewscreen::preRender()
{ {
} }
void lightingEngineViewscreen::fixAdvMode(int mode) void lightingEngineViewscreen::fixAdvMode(int mode)
{ {
MapExtras::MapCache mc; MapExtras::MapCache mc;
const rgbf dim(levelDim,levelDim,levelDim); const rgbf dim(levelDim,levelDim,levelDim);
rect2d vp=getMapViewport(); rect2d vp=getMapViewport();
@ -413,7 +413,7 @@ matLightDef* lightingEngineViewscreen::getMaterialDef( int matType,int matIndex
auto it=matDefs.find(std::make_pair(matType,matIndex)); auto it=matDefs.find(std::make_pair(matType,matIndex));
if(it!=matDefs.end()) if(it!=matDefs.end())
return &it->second; return &it->second;
else else
return NULL; return NULL;
} }
buildingLightDef* lightingEngineViewscreen::getBuildingDef( df::building* bld ) buildingLightDef* lightingEngineViewscreen::getBuildingDef( df::building* bld )
@ -421,7 +421,7 @@ buildingLightDef* lightingEngineViewscreen::getBuildingDef( df::building* bld )
auto it=buildingDefs.find(std::make_tuple((int)bld->getType(),(int)bld->getSubtype(),(int)bld->getCustomType())); auto it=buildingDefs.find(std::make_tuple((int)bld->getType(),(int)bld->getSubtype(),(int)bld->getCustomType()));
if(it!=buildingDefs.end()) if(it!=buildingDefs.end())
return &it->second; return &it->second;
else else
return NULL; return NULL;
} }
creatureLightDef* lightingEngineViewscreen::getCreatureDef(df::unit* u) creatureLightDef* lightingEngineViewscreen::getCreatureDef(df::unit* u)
@ -502,10 +502,10 @@ rgbf lightingEngineViewscreen::propogateSun(MapExtras::Block* b, int x,int y,con
else if(basicShapeIce==df::tiletype_shape_basic::Floor || basicShapeIce==df::tiletype_shape_basic::Ramp || shapeIce==df::tiletype_shape::STAIR_UP) else if(basicShapeIce==df::tiletype_shape_basic::Floor || basicShapeIce==df::tiletype_shape_basic::Ramp || shapeIce==df::tiletype_shape::STAIR_UP)
if(!lastLevel) if(!lastLevel)
ret*=matIce.transparency.pow(1.0f/7.0f); ret*=matIce.transparency.pow(1.0f/7.0f);
} }
lightDef=getMaterialDef(mat.mat_type,mat.mat_index); lightDef=getMaterialDef(mat.mat_type,mat.mat_index);
if(!lightDef || !lightDef->isTransparent) if(!lightDef || !lightDef->isTransparent)
lightDef=&matWall; lightDef=&matWall;
if(basic_shape==df::tiletype_shape_basic::Wall) if(basic_shape==df::tiletype_shape_basic::Wall)
@ -514,9 +514,9 @@ rgbf lightingEngineViewscreen::propogateSun(MapExtras::Block* b, int x,int y,con
} }
else if(basic_shape==df::tiletype_shape_basic::Floor || basic_shape==df::tiletype_shape_basic::Ramp || shape==df::tiletype_shape::STAIR_UP) else if(basic_shape==df::tiletype_shape_basic::Floor || basic_shape==df::tiletype_shape_basic::Ramp || shape==df::tiletype_shape::STAIR_UP)
{ {
if(!lastLevel) if(!lastLevel)
ret*=lightDef->transparency.pow(1.0f/7.0f); ret*=lightDef->transparency.pow(1.0f/7.0f);
} }
else if(shape==df::tiletype_shape::STAIR_DOWN || shape==df::tiletype_shape::STAIR_UPDOWN) else if(shape==df::tiletype_shape::STAIR_DOWN || shape==df::tiletype_shape::STAIR_UPDOWN)
{ {
@ -574,7 +574,7 @@ void lightingEngineViewscreen::doSun(const lightSource& sky,MapExtras::MapCache&
rgbf& curCell=cellArray[block_x][block_y]; rgbf& curCell=cellArray[block_x][block_y];
curCell=propogateSun(b,block_x,block_y,curCell,z==window_z); curCell=propogateSun(b,block_x,block_y,curCell,z==window_z);
if(curCell.dot(curCell)<0.003f) if(curCell.dot(curCell)<0.003f)
emptyCell++; emptyCell++;
} }
} }
if(emptyCell==256) if(emptyCell==256)
@ -622,10 +622,10 @@ void lightingEngineViewscreen::doOcupancyAndLights()
} }
else else
daycol= fmod(dayHour,24.0f)/24.0f; //1->12h 0->24h daycol= fmod(dayHour,24.0f)/24.0f; //1->12h 0->24h
rgbf sky_col=getSkyColor(daycol); rgbf sky_col=getSkyColor(daycol);
lightSource sky(sky_col, -1);//auto calculate best size lightSource sky(sky_col, -1);//auto calculate best size
MapExtras::MapCache cache; MapExtras::MapCache cache;
doSun(sky,cache); doSun(sky,cache);
@ -640,7 +640,7 @@ void lightingEngineViewscreen::doOcupancyAndLights()
blockVp.second=(window2d+vpSize)/16; blockVp.second=(window2d+vpSize)/16;
blockVp.second.x=std::min(blockVp.second.x,(int16_t)df::global::world->map.x_count_block); blockVp.second.x=std::min(blockVp.second.x,(int16_t)df::global::world->map.x_count_block);
blockVp.second.y=std::min(blockVp.second.y,(int16_t)df::global::world->map.y_count_block); blockVp.second.y=std::min(blockVp.second.y,(int16_t)df::global::world->map.y_count_block);
for(int blockX=blockVp.first.x;blockX<=blockVp.second.x;blockX++) for(int blockX=blockVp.first.x;blockX<=blockVp.second.x;blockX++)
for(int blockY=blockVp.first.y;blockY<=blockVp.second.y;blockY++) for(int blockY=blockVp.first.y;blockY<=blockVp.second.y;blockY++)
{ {
@ -648,7 +648,7 @@ void lightingEngineViewscreen::doOcupancyAndLights()
MapExtras::Block* bDown=cache.BlockAt(DFCoord(blockX,blockY,window_z-1)); MapExtras::Block* bDown=cache.BlockAt(DFCoord(blockX,blockY,window_z-1));
if(!b) if(!b)
continue; //empty blocks fixed by sun propagation continue; //empty blocks fixed by sun propagation
for(int block_x = 0; block_x < 16; block_x++) for(int block_x = 0; block_x < 16; block_x++)
for(int block_y = 0; block_y < 16; block_y++) for(int block_y = 0; block_y < 16; block_y++)
{ {
@ -662,7 +662,7 @@ void lightingEngineViewscreen::doOcupancyAndLights()
int tile=getIndex(pos.x,pos.y); int tile=getIndex(pos.x,pos.y);
rgbf& curCell=ocupancy[tile]; rgbf& curCell=ocupancy[tile];
curCell=matAmbience.transparency; curCell=matAmbience.transparency;
df::tiletype type = b->tiletypeAt(gpos); df::tiletype type = b->tiletypeAt(gpos);
df::tile_designation d = b->DesignationAt(gpos); df::tile_designation d = b->DesignationAt(gpos);
@ -677,9 +677,9 @@ void lightingEngineViewscreen::doOcupancyAndLights()
bool is_floor=!ENUM_ATTR(tiletype_shape,passable_low,shape); bool is_floor=!ENUM_ATTR(tiletype_shape,passable_low,shape);
df::tiletype_shape_basic basic_shape = ENUM_ATTR(tiletype_shape, basic_shape, shape); df::tiletype_shape_basic basic_shape = ENUM_ATTR(tiletype_shape, basic_shape, shape);
df::tiletype_material tileMat= ENUM_ATTR(tiletype,material,type); df::tiletype_material tileMat= ENUM_ATTR(tiletype,material,type);
DFHack::t_matpair mat=b->staticMaterialAt(gpos); DFHack::t_matpair mat=b->staticMaterialAt(gpos);
matLightDef* lightDef=getMaterialDef(mat.mat_type,mat.mat_index); matLightDef* lightDef=getMaterialDef(mat.mat_type,mat.mat_index);
if(!lightDef || !lightDef->isTransparent) if(!lightDef || !lightDef->isTransparent)
lightDef=&matWall; lightDef=&matWall;
@ -698,7 +698,7 @@ void lightingEngineViewscreen::doOcupancyAndLights()
{ {
applyMaterial(tile,matWater, (float)d.bits.flow_size/7.0f, (float)d.bits.flow_size/7.0f); applyMaterial(tile,matWater, (float)d.bits.flow_size/7.0f, (float)d.bits.flow_size/7.0f);
} }
if(d.bits.liquid_type && d.bits.flow_size>0) if(d.bits.liquid_type && d.bits.flow_size>0)
{ {
applyMaterial(tile,matLava,(float)d.bits.flow_size/7.0f,(float)d.bits.flow_size/7.0f); applyMaterial(tile,matLava,(float)d.bits.flow_size/7.0f,(float)d.bits.flow_size/7.0f);
} }
@ -713,10 +713,10 @@ void lightingEngineViewscreen::doOcupancyAndLights()
} }
} }
} }
} }
df::map_block* block=b->getRaw(); df::map_block* block=b->getRaw();
if(!block) if(!block)
continue; continue;
@ -749,7 +749,7 @@ void lightingEngineViewscreen::doOcupancyAndLights()
} }
} }
} }
//blood and other goo //blood and other goo
for(int i=0;i<block->block_events.size();i++) for(int i=0;i<block->block_events.size();i++)
{ {
@ -829,12 +829,12 @@ void lightingEngineViewscreen::doOcupancyAndLights()
} }
} }
} }
//buildings //buildings
for(size_t i = 0; i < df::global::world->buildings.all.size(); i++) for(size_t i = 0; i < df::global::world->buildings.all.size(); i++)
{ {
df::building *bld = df::global::world->buildings.all[i]; df::building *bld = df::global::world->buildings.all[i];
if(window_z!=bld->z) if(window_z!=bld->z)
continue; continue;
if(bld->getBuildStage()<bld->getMaxBuildStage()) //only work if fully built if(bld->getBuildStage()<bld->getMaxBuildStage()) //only work if fully built
@ -846,7 +846,7 @@ void lightingEngineViewscreen::doOcupancyAndLights()
p2=worldToViewportCoord(p2,vp,window2d); p2=worldToViewportCoord(p2,vp,window2d);
if(isInRect(p1,vp)||isInRect(p2,vp)) if(isInRect(p1,vp)||isInRect(p2,vp))
{ {
int tile; int tile;
if(isInRect(p1,vp)) if(isInRect(p1,vp))
tile=getIndex(p1.x,p1.y); //TODO multitile buildings. How they would work? tile=getIndex(p1.x,p1.y); //TODO multitile buildings. How they would work?
@ -868,8 +868,8 @@ void lightingEngineViewscreen::doOcupancyAndLights()
if(!gate->gate_flags.bits.closed) if(!gate->gate_flags.bits.closed)
continue; continue;
} }
if(def->useMaterial) if(def->useMaterial)
{ {
matLightDef* mat=getMaterialDef(bld->mat_type,bld->mat_index); matLightDef* mat=getMaterialDef(bld->mat_type,bld->mat_index);
@ -903,7 +903,7 @@ void lightingEngineViewscreen::doOcupancyAndLights()
} }
} }
} }
} }
rgbf lua_parseLightCell(lua_State* L) rgbf lua_parseLightCell(lua_State* L)
{ {
@ -937,7 +937,7 @@ rgbf lua_parseLightCell(lua_State* L)
lua_pop(L,1) lua_pop(L,1)
matLightDef lua_parseMatDef(lua_State* L) matLightDef lua_parseMatDef(lua_State* L)
{ {
matLightDef ret; matLightDef ret;
lua_getfield(L,-1,"tr"); lua_getfield(L,-1,"tr");
if(ret.isTransparent=!lua_isnil(L,-1)) if(ret.isTransparent=!lua_isnil(L,-1))
@ -987,7 +987,7 @@ int lightingEngineViewscreen::parseMaterials(lua_State* L)
int index=lua_tonumber(L,-2); int index=lua_tonumber(L,-2);
//os->print("\tProcessing index:%d\n",index); //os->print("\tProcessing index:%d\n",index);
engine->matDefs[std::make_pair(type,index)]=lua_parseMatDef(L); engine->matDefs[std::make_pair(type,index)]=lua_parseMatDef(L);
lua_pop(L, 1); lua_pop(L, 1);
} }
lua_pop(L, 1); lua_pop(L, 1);
@ -1174,17 +1174,17 @@ void lightingEngineViewscreen::loadSettings()
std::string rawFolder; std::string rawFolder;
if(df::global::world->cur_savegame.save_dir!="") if(df::global::world->cur_savegame.save_dir!="")
{ {
rawFolder= "data/save/" + (df::global::world->cur_savegame.save_dir) + "/raw/"; rawFolder= "data/save/" + (df::global::world->cur_savegame.save_dir) + "/raw/";
} }
else else
{ {
rawFolder= "raw/"; rawFolder= "raw/";
} }
const std::string settingsfile=rawFolder+"rendermax.lua"; const std::string settingsfile=rawFolder+"rendermax.lua";
CoreSuspender lock; CoreSuspender lock;
color_ostream_proxy out(Core::getInstance().getConsole()); color_ostream_proxy out(Core::getInstance().getConsole());
lua_State* s=DFHack::Lua::Core::State; lua_State* s=DFHack::Lua::Core::State;
lua_newtable(s); lua_newtable(s);
int env=lua_gettop(s); int env=lua_gettop(s);
@ -1202,7 +1202,7 @@ void lightingEngineViewscreen::loadSettings()
else else
{ {
lua_pushvalue(s,env); lua_pushvalue(s,env);
if(Lua::SafeCall(out,s,1,0)) if(Lua::SafeCall(out,s,1,0))
{ {
lua_pushcfunction(s, parseMaterials); lua_pushcfunction(s, parseMaterials);
@ -1235,7 +1235,7 @@ void lightingEngineViewscreen::loadSettings()
Lua::SafeCall(out,s,2,0); Lua::SafeCall(out,s,2,0);
out.print("%d items loaded\n",itemDefs.size()); out.print("%d items loaded\n",itemDefs.size());
} }
} }
} }
catch(std::exception& e) catch(std::exception& e)
@ -1272,8 +1272,8 @@ void lightThread::run()
if(dispatch.occlusion.size()!=canvas.size()) //oh no somebody resized stuff if(dispatch.occlusion.size()!=canvas.size()) //oh no somebody resized stuff
canvas.resize(dispatch.occlusion.size()); canvas.resize(dispatch.occlusion.size());
} }
{ //get my rectangle (any will do) { //get my rectangle (any will do)
tthread::lock_guard<tthread::mutex> guard(dispatch.unprocessedMutex); tthread::lock_guard<tthread::mutex> guard(dispatch.unprocessedMutex);
if (dispatch.unprocessed.size()==0) if (dispatch.unprocessed.size()==0)
@ -1287,13 +1287,13 @@ void lightThread::run()
{ {
dispatch.occlusionReady=false; dispatch.occlusionReady=false;
} }
} }
work(); work();
{ {
tthread::lock_guard<tthread::mutex> guard(dispatch.writeLock); tthread::lock_guard<tthread::mutex> guard(dispatch.writeLock);
combine();//write it back combine();//write it back
dispatch.writeCount++; dispatch.writeCount++;
} }
dispatch.writesDone.notify_one();//tell about it to the dispatch. dispatch.writesDone.notify_one();//tell about it to the dispatch.
} }
@ -1311,7 +1311,7 @@ void lightThread::work()
void lightThread::combine() void lightThread::combine()
{ {
for(int i=0;i<canvas.size();i++) for(int i=0;i<canvas.size();i++)
{ {
rgbf& c=dispatch.lightMap[i]; rgbf& c=dispatch.lightMap[i];
c=blend(c,canvas[i]); c=blend(c,canvas[i]);
@ -1393,7 +1393,7 @@ void lightThread::doLight( int x,int y )
surrounds += lightUpCell( power, i, j,x+i, y+j); //and this is wall hack (so that walls look nice) surrounds += lightUpCell( power, i, j,x+i, y+j); //and this is wall hack (so that walls look nice)
if(surrounds.dot(surrounds)>0.00001f) //if we needed to light up the suroundings, then raycast if(surrounds.dot(surrounds)>0.00001f) //if we needed to light up the suroundings, then raycast
{ {
plotSquare(x,y,radius, plotSquare(x,y,radius,
std::bind(&lightThread::doRay,this,power,x,y,_1,_2,num_diffuse)); std::bind(&lightThread::doRay,this,power,x,y,_1,_2,num_diffuse));
} }
@ -1438,7 +1438,7 @@ void lightThreadDispatch::shutdown()
for(int i=0;i<threadPool.size();i++) for(int i=0;i<threadPool.size();i++)
{ {
threadPool[i]->isDone=true; threadPool[i]->isDone=true;
} }
occlusionDone.notify_all();//if stuck signal that you are done with stuff. occlusionDone.notify_all();//if stuck signal that you are done with stuff.
for(int i=0;i<threadPool.size();i++) for(int i=0;i<threadPool.size();i++)
@ -1465,7 +1465,7 @@ void threadStub(void * arg)
void lightThreadDispatch::start(int count) void lightThreadDispatch::start(int count)
{ {
for(int i=0;i<count;i++) for(int i=0;i<count;i++)
{ {
std::unique_ptr<lightThread> nthread(new lightThread(*this)); std::unique_ptr<lightThread> nthread(new lightThread(*this));
nthread->myThread=new tthread::thread(&threadStub,nthread.get()); nthread->myThread=new tthread::thread(&threadStub,nthread.get());
threadPool.push_back(std::move(nthread)); threadPool.push_back(std::move(nthread));

@ -53,7 +53,7 @@ private:
float intensity=(light.r+light.g+light.b)/3.0; float intensity=(light.r+light.g+light.b)/3.0;
light_adaptation=intensity*influence+light_adaptation*(1-influence); light_adaptation=intensity*influence+light_adaptation*(1-influence);
float delta=light_adaptation-intensity; float delta=light_adaptation-intensity;
rgbf ret; rgbf ret;
ret.r=light.r-delta; ret.r=light.r-delta;
ret.g=light.g-delta; ret.g=light.g-delta;
@ -65,7 +65,7 @@ private:
2. light adapted, real=dark -> darker delta>0 multiplier<1 2. light adapted, real=dark -> darker delta>0 multiplier<1
3. dark adapted, real=light -> lighter delta<0 multiplier>1 3. dark adapted, real=light -> lighter delta<0 multiplier>1
*/ */
//if light_adaptation/intensity!=0 then draw //if light_adaptation/intensity!=0 then draw
} }
void colorizeTile(int x,int y) void colorizeTile(int x,int y)
@ -98,7 +98,7 @@ private:
{ {
reinitLightGrid(df::global::gps->dimy,df::global::gps->dimx); reinitLightGrid(df::global::gps->dimy,df::global::gps->dimx);
} }
public: public:
tthread::fast_mutex dataMutex; tthread::fast_mutex dataMutex;
std::vector<rgbf> lightGrid; std::vector<rgbf> lightGrid;
@ -106,19 +106,19 @@ public:
{ {
reinitLightGrid(); reinitLightGrid();
} }
virtual void update_tile(int32_t x, int32_t y) { virtual void update_tile(int32_t x, int32_t y) {
renderer_wrap::update_tile(x,y); renderer_wrap::update_tile(x,y);
tthread::lock_guard<tthread::fast_mutex> guard(dataMutex); tthread::lock_guard<tthread::fast_mutex> guard(dataMutex);
colorizeTile(x,y); colorizeTile(x,y);
}; };
virtual void update_all() { virtual void update_all() {
renderer_wrap::update_all(); renderer_wrap::update_all();
tthread::lock_guard<tthread::fast_mutex> guard(dataMutex); tthread::lock_guard<tthread::fast_mutex> guard(dataMutex);
for (int x = 0; x < df::global::gps->dimx; x++) for (int x = 0; x < df::global::gps->dimx; x++)
for (int y = 0; y < df::global::gps->dimy; y++) for (int y = 0; y < df::global::gps->dimy; y++)
colorizeTile(x,y); colorizeTile(x,y);
}; };
virtual void grid_resize(int32_t w, int32_t h) { virtual void grid_resize(int32_t w, int32_t h) {
renderer_wrap::grid_resize(w,h); renderer_wrap::grid_resize(w,h);
reinitLightGrid(w,h); reinitLightGrid(w,h);
}; };
@ -150,7 +150,7 @@ public:
virtual void loadSettings()=0; virtual void loadSettings()=0;
virtual void clear()=0; virtual void clear()=0;
virtual void setHour(float h)=0; virtual void setHour(float h)=0;
virtual void debug(bool enable)=0; virtual void debug(bool enable)=0;
protected: protected:
@ -205,7 +205,7 @@ struct buildingLightDef
}; };
struct itemLightDef struct itemLightDef
{ {
matLightDef light; matLightDef light;
bool haul; bool haul;
bool equiped; bool equiped;
bool onGround; bool onGround;
@ -276,7 +276,7 @@ class lightingEngineViewscreen:public lightingEngine
{ {
public: public:
lightingEngineViewscreen(renderer_light* target); lightingEngineViewscreen(renderer_light* target);
~lightingEngineViewscreen(); ~lightingEngineViewscreen();
void reinit(); void reinit();
void calculate(); void calculate();
@ -289,14 +289,14 @@ public:
private: private:
void fixAdvMode(int mode); void fixAdvMode(int mode);
df::coord2d worldToViewportCoord(const df::coord2d& in,const DFHack::rect2d& r,const df::coord2d& window2d) ; df::coord2d worldToViewportCoord(const df::coord2d& in,const DFHack::rect2d& r,const df::coord2d& window2d) ;
void doSun(const lightSource& sky,MapExtras::MapCache& map); void doSun(const lightSource& sky,MapExtras::MapCache& map);
void doOcupancyAndLights(); void doOcupancyAndLights();
rgbf propogateSun(MapExtras::Block* b, int x,int y,const rgbf& in,bool lastLevel); rgbf propogateSun(MapExtras::Block* b, int x,int y,const rgbf& in,bool lastLevel);
void doRay(std::vector<rgbf> & target, rgbf power,int cx,int cy,int tx,int ty); void doRay(std::vector<rgbf> & target, rgbf power,int cx,int cy,int tx,int ty);
void doFovs(); void doFovs();
void doLight(std::vector<rgbf> & target, int index); void doLight(std::vector<rgbf> & target, int index);
rgbf lightUpCell(std::vector<rgbf> & target, rgbf power,int dx,int dy,int tx,int ty); rgbf lightUpCell(std::vector<rgbf> & target, rgbf power,int dx,int dy,int tx,int ty);
bool addLight(int tileId,const lightSource& light); bool addLight(int tileId,const lightSource& light);
void addOclusion(int tileId,const rgbf& c,float thickness); void addOclusion(int tileId,const rgbf& c,float thickness);
@ -310,7 +310,7 @@ private:
void applyMaterial(int tileId,const matLightDef& mat,float size=1, float thickness = 1); void applyMaterial(int tileId,const matLightDef& mat,float size=1, float thickness = 1);
//try to find and apply material, if failed return false, and if def!=null then apply def. //try to find and apply material, if failed return false, and if def!=null then apply def.
bool applyMaterial(int tileId,int matType,int matIndex,float size=1,float thickness = 1,const matLightDef* def=NULL); bool applyMaterial(int tileId,int matType,int matIndex,float size=1,float thickness = 1,const matLightDef* def=NULL);
size_t inline getIndex(int x,int y) size_t inline getIndex(int x,int y)
{ {
return x*h+y; return x*h+y;
@ -333,7 +333,7 @@ private:
int getW()const {return w;} int getW()const {return w;}
int getH()const {return h;} int getH()const {return h;}
public: public:
void lightWorkerThread(void * arg); void lightWorkerThread(void * arg);
private: private:
rgbf getSkyColor(float v); rgbf getSkyColor(float v);
bool doDebug; bool doDebug;
@ -343,7 +343,7 @@ private:
float dayHour; //<0 to cycle float dayHour; //<0 to cycle
std::vector<rgbf> dayColors; // a gradient of colors, first to 0, last to 24 std::vector<rgbf> dayColors; // a gradient of colors, first to 0, last to 24
///set up sane settings if setting file does not exist. ///set up sane settings if setting file does not exist.
void defaultSettings(); void defaultSettings();
static int parseMaterials(lua_State* L); static int parseMaterials(lua_State* L);
static int parseSpecial(lua_State* L); static int parseSpecial(lua_State* L);

@ -79,46 +79,46 @@ public:
{ {
copy_from_inner(); copy_from_inner();
} }
virtual void update_tile(int32_t x, int32_t y) { virtual void update_tile(int32_t x, int32_t y) {
copy_to_inner(); copy_to_inner();
parent->update_tile(x,y); parent->update_tile(x,y);
}; };
virtual void update_all() { virtual void update_all() {
copy_to_inner(); copy_to_inner();
parent->update_all(); parent->update_all();
}; };
virtual void render() { virtual void render() {
copy_to_inner(); copy_to_inner();
parent->render(); parent->render();
}; };
virtual void set_fullscreen() { virtual void set_fullscreen() {
copy_to_inner(); copy_to_inner();
parent->set_fullscreen(); parent->set_fullscreen();
copy_from_inner(); copy_from_inner();
}; };
virtual void zoom(df::zoom_commands z) { virtual void zoom(df::zoom_commands z) {
copy_to_inner(); copy_to_inner();
parent->zoom(z); parent->zoom(z);
copy_from_inner(); copy_from_inner();
}; };
virtual void resize(int32_t w, int32_t h) { virtual void resize(int32_t w, int32_t h) {
copy_to_inner(); copy_to_inner();
parent->resize(w,h); parent->resize(w,h);
copy_from_inner(); copy_from_inner();
}; };
virtual void grid_resize(int32_t w, int32_t h) { virtual void grid_resize(int32_t w, int32_t h) {
copy_to_inner(); copy_to_inner();
parent->grid_resize(w,h); parent->grid_resize(w,h);
copy_from_inner(); copy_from_inner();
}; };
virtual ~renderer_wrap() { virtual ~renderer_wrap() {
df::global::enabler->renderer=parent; df::global::enabler->renderer=parent;
}; };
virtual bool get_mouse_coords(int32_t* x, int32_t* y) { virtual bool get_mouse_coords(int32_t* x, int32_t* y) {
return parent->get_mouse_coords(x,y); return parent->get_mouse_coords(x,y);
}; };
virtual bool uses_opengl() { virtual bool uses_opengl() {
return parent->uses_opengl(); return parent->uses_opengl();
}; };
void invalidateRect(int32_t x,int32_t y,int32_t w,int32_t h) void invalidateRect(int32_t x,int32_t y,int32_t w,int32_t h)
@ -152,7 +152,7 @@ private:
float *bg = p->bg + tile * 4 * 6; float *bg = p->bg + tile * 4 * 6;
float *tex = p->tex + tile * 2 * 6; float *tex = p->tex + tile * 2 * 6;
const float val=1/2.0; const float val=1/2.0;
float r=rFloat()*val - val/2; float r=rFloat()*val - val/2;
float g=rFloat()*val - val/2; float g=rFloat()*val - val/2;
float b=rFloat()*val - val/2; float b=rFloat()*val - val/2;
@ -176,11 +176,11 @@ public:
renderer_trippy(renderer* parent):renderer_wrap(parent) renderer_trippy(renderer* parent):renderer_wrap(parent)
{ {
} }
virtual void update_tile(int32_t x, int32_t y) { virtual void update_tile(int32_t x, int32_t y) {
renderer_wrap::update_tile(x,y); renderer_wrap::update_tile(x,y);
colorizeTile(x,y); colorizeTile(x,y);
}; };
virtual void update_all() { virtual void update_all() {
renderer_wrap::update_all(); renderer_wrap::update_all();
for (int x = 0; x < df::global::gps->dimx; x++) for (int x = 0; x < df::global::gps->dimx; x++)
for (int y = 0; y < df::global::gps->dimy; y++) for (int y = 0; y < df::global::gps->dimy; y++)
@ -193,7 +193,7 @@ struct rgbf
float r,g,b; float r,g,b;
rgbf():r(0),g(0),b(0) rgbf():r(0),g(0),b(0)
{ {
} }
rgbf(float r,float g,float b):r(r),g(g),b(b) rgbf(float r,float g,float b):r(r),g(g),b(b)
{ {
@ -295,14 +295,14 @@ public:
{ {
reinitLightGrid(); reinitLightGrid();
} }
virtual void update_tile(int32_t x, int32_t y) { virtual void update_tile(int32_t x, int32_t y) {
renderer_wrap::update_tile(x,y); renderer_wrap::update_tile(x,y);
tthread::lock_guard<tthread::fast_mutex> guard(dataMutex); tthread::lock_guard<tthread::fast_mutex> guard(dataMutex);
colorizeTile(x,y); colorizeTile(x,y);
//some sort of mutex or sth? //some sort of mutex or sth?
//and then map read //and then map read
}; };
virtual void update_all() { virtual void update_all() {
renderer_wrap::update_all(); renderer_wrap::update_all();
tthread::lock_guard<tthread::fast_mutex> guard(dataMutex); tthread::lock_guard<tthread::fast_mutex> guard(dataMutex);
for (int x = 0; x < df::global::gps->dimx; x++) for (int x = 0; x < df::global::gps->dimx; x++)
@ -322,7 +322,7 @@ public:
renderer_wrap::zoom(z); renderer_wrap::zoom(z);
reinitLightGrid(); reinitLightGrid();
} }
virtual void grid_resize(int32_t w, int32_t h) { virtual void grid_resize(int32_t w, int32_t h) {
renderer_wrap::grid_resize(w,h); renderer_wrap::grid_resize(w,h);
reinitLightGrid(w,h); reinitLightGrid(w,h);
}; };
@ -388,14 +388,14 @@ public:
{ {
reinitGrids(); reinitGrids();
} }
virtual void update_tile(int32_t x, int32_t y) { virtual void update_tile(int32_t x, int32_t y) {
renderer_wrap::update_tile(x,y); renderer_wrap::update_tile(x,y);
tthread::lock_guard<tthread::fast_mutex> guard(dataMutex); tthread::lock_guard<tthread::fast_mutex> guard(dataMutex);
overwriteTile(x,y); overwriteTile(x,y);
//some sort of mutex or sth? //some sort of mutex or sth?
//and then map read //and then map read
}; };
virtual void update_all() { virtual void update_all() {
renderer_wrap::update_all(); renderer_wrap::update_all();
tthread::lock_guard<tthread::fast_mutex> guard(dataMutex); tthread::lock_guard<tthread::fast_mutex> guard(dataMutex);
for (int x = 0; x < df::global::gps->dimx; x++) for (int x = 0; x < df::global::gps->dimx; x++)
@ -405,7 +405,7 @@ public:
//and then map read //and then map read
//same stuff for all of them i guess... //same stuff for all of them i guess...
}; };
virtual void grid_resize(int32_t w, int32_t h) { virtual void grid_resize(int32_t w, int32_t h) {
renderer_wrap::grid_resize(w,h); renderer_wrap::grid_resize(w,h);
reinitGrids(w,h); reinitGrids(w,h);
}; };

@ -106,7 +106,7 @@ void removeOld()
} }
if(current_mode!=MODE_DEFAULT) if(current_mode!=MODE_DEFAULT)
delete enabler->renderer; delete enabler->renderer;
current_mode=MODE_DEFAULT; current_mode=MODE_DEFAULT;
} }
void installNew(df::renderer* r,RENDERER_MODE newMode) void installNew(df::renderer* r,RENDERER_MODE newMode)
@ -411,7 +411,7 @@ static command_result rendermax(color_ostream &out, vector <string> & parameters
renderer_light *myRender=new renderer_light(enabler->renderer); renderer_light *myRender=new renderer_light(enabler->renderer);
installNew(myRender,MODE_LIGHT); installNew(myRender,MODE_LIGHT);
engine=new lightingEngineViewscreen(myRender); engine=new lightingEngineViewscreen(myRender);
if (Core::getInstance().isWorldLoaded()) if (Core::getInstance().isWorldLoaded())
plugin_onstatechange(out, SC_WORLD_LOADED); plugin_onstatechange(out, SC_WORLD_LOADED);
} }
@ -446,7 +446,7 @@ static command_result rendermax(color_ostream &out, vector <string> & parameters
} }
else else
out.printerr("Light mode already enabled"); out.printerr("Light mode already enabled");
return CR_OK; return CR_OK;
} }
else if(cmd=="disable") else if(cmd=="disable")

@ -1,225 +1,225 @@
--scroll down to the end for configuration --scroll down to the end for configuration
ret={...} ret={...}
ret=ret[1] ret=ret[1]
ret.materials={} ret.materials={}
ret.buildings={} ret.buildings={}
ret.special={} ret.special={}
ret.items={} ret.items={}
ret.creatures={} ret.creatures={}
for k,v in pairs(ret) do for k,v in pairs(ret) do
_ENV[k]=v _ENV[k]=v
end end
-- add material by id (index,mat pair or token string or a type number), flags is a table of strings -- add material by id (index,mat pair or token string or a type number), flags is a table of strings
-- supported flags (but not implemented): -- supported flags (but not implemented):
-- flicker -- flicker
function addMaterial(id,transparency,emitance,radius,flags) function addMaterial(id,transparency,emitance,radius,flags)
local matinfo local matinfo
if type(id)=="string" then if type(id)=="string" then
matinfo=dfhack.matinfo.find(id) matinfo=dfhack.matinfo.find(id)
elseif type(id)=="table" then elseif type(id)=="table" then
matinfo=dfhack.matinfo.decode(id[1],id[2]) matinfo=dfhack.matinfo.decode(id[1],id[2])
else else
matinfo=dfhack.matinfo.decode(id,0) matinfo=dfhack.matinfo.decode(id,0)
end end
if matinfo==nil then if matinfo==nil then
error("Material not found") error("Material not found")
end end
materials[matinfo.type]=materials[matinfo.type] or {} materials[matinfo.type]=materials[matinfo.type] or {}
materials[matinfo.type][matinfo.index]=makeMaterialDef(transparency,emitance,radius,flags) materials[matinfo.type][matinfo.index]=makeMaterialDef(transparency,emitance,radius,flags)
end end
function buildingLookUp(id) function buildingLookUp(id)
local tokens={} local tokens={}
local lookup={ Workshop=df.workshop_type,Furnace=df.furnace_type,Trap=df.trap_type, local lookup={ Workshop=df.workshop_type,Furnace=df.furnace_type,Trap=df.trap_type,
SiegeEngine=df.siegeengine_type} SiegeEngine=df.siegeengine_type}
for i in string.gmatch(id, "[^:]+") do for i in string.gmatch(id, "[^:]+") do
table.insert(tokens,i) table.insert(tokens,i)
end end
local ret={} local ret={}
ret.type=df.building_type[tokens[1]] ret.type=df.building_type[tokens[1]]
if tokens[2] then if tokens[2] then
local type_array=lookup[tokens[1]] local type_array=lookup[tokens[1]]
if type_array then if type_array then
ret.subtype=type_array[tokens[2]] ret.subtype=type_array[tokens[2]]
end end
if tokens[2]=="Custom" and tokens[3] then --TODO cache for faster lookup if tokens[2]=="Custom" and tokens[3] then --TODO cache for faster lookup
if ret.type==df.building_type.Workshop then if ret.type==df.building_type.Workshop then
for k,v in pairs(df.global.world.raws.buildings.workshops) do for k,v in pairs(df.global.world.raws.buildings.workshops) do
if v.code==tokens[3] then if v.code==tokens[3] then
ret.custom=v.id ret.custom=v.id
return ret return ret
end end
end end
elseif ret.type==df.building_type.Furnace then elseif ret.type==df.building_type.Furnace then
for k,v in pairs(df.global.world.raws.buildings.furnaces) do for k,v in pairs(df.global.world.raws.buildings.furnaces) do
if v.code==tokens[3] then if v.code==tokens[3] then
ret.custom=v.id ret.custom=v.id
return ret return ret
end end
end end
end end
end end
qerror("Invalid custom building:"..tokens[3]) qerror("Invalid custom building:"..tokens[3])
end end
return ret return ret
end end
function itemLookup(id) function itemLookup(id)
local ret={} local ret={}
local tokens={} local tokens={}
for i in string.gmatch(id, "[^:]+") do for i in string.gmatch(id, "[^:]+") do
table.insert(tokens,i) table.insert(tokens,i)
end end
ret.type=df.item_type[tokens[1]] ret.type=df.item_type[tokens[1]]
ret.subtype=-1 ret.subtype=-1
if tokens[2] then if tokens[2] then
for k,v in ipairs(df.global.world.raws.itemdefs.all) do --todo lookup correct itemdef for k,v in ipairs(df.global.world.raws.itemdefs.all) do --todo lookup correct itemdef
if v.id==tokens[2] then if v.id==tokens[2] then
ret.subtype=v.subtype ret.subtype=v.subtype
return ret return ret
end end
end end
qerror("Failed item subtype lookup:"..tokens[2]) qerror("Failed item subtype lookup:"..tokens[2])
end end
return ret return ret
end end
function creatureLookup(id) function creatureLookup(id)
local ret={} local ret={}
local tokens={} local tokens={}
for i in string.gmatch(id, "[^:]+") do for i in string.gmatch(id, "[^:]+") do
table.insert(tokens,i) table.insert(tokens,i)
end end
for k,v in ipairs(df.global.world.raws.creatures.all) do for k,v in ipairs(df.global.world.raws.creatures.all) do
if v.creature_id==tokens[1] then if v.creature_id==tokens[1] then
ret.type=k ret.type=k
if tokens[2] then if tokens[2] then
for k,v in ipairs(v.caste) do for k,v in ipairs(v.caste) do
if v.caste_id==tokens[2] then if v.caste_id==tokens[2] then
ret.subtype=k ret.subtype=k
break break
end end
end end
if ret.subtype==nil then if ret.subtype==nil then
qerror("caste "..tokens[2].." for "..tokens[1].." not found") qerror("caste "..tokens[2].." for "..tokens[1].." not found")
end end
end end
return ret return ret
end end
end end
qerror("Failed to find race:"..tokens[1]) qerror("Failed to find race:"..tokens[1])
end end
-- add creature by id ("DWARF" or "DWARF:MALE") -- add creature by id ("DWARF" or "DWARF:MALE")
-- supported flags: -- supported flags:
function addCreature(id,transparency,emitance,radius,flags) function addCreature(id,transparency,emitance,radius,flags)
local crId=creatureLookup(id) local crId=creatureLookup(id)
local mat=makeMaterialDef(transparency,emitance,radius,flags) local mat=makeMaterialDef(transparency,emitance,radius,flags)
table.insert(creatures,{race=crId.type,caste=crId.subtype or -1, light=mat}) table.insert(creatures,{race=crId.type,caste=crId.subtype or -1, light=mat})
end end
-- add item by id ( "TOTEM" or "WEAPON:PICK" or "WEAPON" for all the weapon types) -- add item by id ( "TOTEM" or "WEAPON:PICK" or "WEAPON" for all the weapon types)
-- supported flags: -- supported flags:
-- hauling --active when hauled TODO::currently all mean same thing... -- hauling --active when hauled TODO::currently all mean same thing...
-- equiped --active while equiped TODO::currently all mean same thing... -- equiped --active while equiped TODO::currently all mean same thing...
-- inBuilding --active in building TODO::currently all mean same thing... -- inBuilding --active in building TODO::currently all mean same thing...
-- contained --active in container TODO::currently all mean same thing... -- contained --active in container TODO::currently all mean same thing...
-- onGround --active on ground -- onGround --active on ground
-- useMaterial --uses material, but the defined things overwrite -- useMaterial --uses material, but the defined things overwrite
function addItem(id,transparency,emitance,radius,flags) function addItem(id,transparency,emitance,radius,flags)
local itemId=itemLookup(id) local itemId=itemLookup(id)
local mat=makeMaterialDef(transparency,emitance,radius,flags) local mat=makeMaterialDef(transparency,emitance,radius,flags)
table.insert(items,{["type"]=itemId.type,subtype=itemId.subtype,light=mat}) table.insert(items,{["type"]=itemId.type,subtype=itemId.subtype,light=mat})
end end
-- add building by id (string e.g. "Statue" or "Workshop:Masons", flags is a table of strings -- add building by id (string e.g. "Statue" or "Workshop:Masons", flags is a table of strings
-- supported flags: -- supported flags:
-- useMaterial --uses material, but the defined things overwrite -- useMaterial --uses material, but the defined things overwrite
-- poweredOnly --glow only when powered -- poweredOnly --glow only when powered
function addBuilding(id,transparency,emitance,radius,flags,size,thickness) function addBuilding(id,transparency,emitance,radius,flags,size,thickness)
size=size or 1 size=size or 1
thickness=thickness or 1 thickness=thickness or 1
local bld=buildingLookUp(id) local bld=buildingLookUp(id)
local mat=makeMaterialDef(transparency,emitance,radius,flags) local mat=makeMaterialDef(transparency,emitance,radius,flags)
mat.size=size mat.size=size
mat.thickness=thickness mat.thickness=thickness
buildings[bld.type]=buildings[bld.type] or {} buildings[bld.type]=buildings[bld.type] or {}
if bld.subtype then if bld.subtype then
if bld.custom then if bld.custom then
buildings[bld.type][bld.subtype]=buildings[bld.type][bld.subtype] or {} buildings[bld.type][bld.subtype]=buildings[bld.type][bld.subtype] or {}
buildings[bld.type][bld.subtype][bld.custom]=mat buildings[bld.type][bld.subtype][bld.custom]=mat
else else
buildings[bld.type][bld.subtype]={[-1]=mat} buildings[bld.type][bld.subtype]={[-1]=mat}
end end
else else
buildings[bld.type][-1]={[-1]=mat} buildings[bld.type][-1]={[-1]=mat}
end end
end end
function makeMaterialDef(transparency,emitance,radius,flags) function makeMaterialDef(transparency,emitance,radius,flags)
local flg local flg
if flags then if flags then
flg={} flg={}
for k,v in ipairs(flags) do for k,v in ipairs(flags) do
flg[v]=true flg[v]=true
end end
end end
return {tr=transparency,em=emitance,rad=radius,flags=flg} return {tr=transparency,em=emitance,rad=radius,flags=flg}
end end
function colorFrom16(col16) function colorFrom16(col16)
local col=df.global.enabler.ccolor[col16] local col=df.global.enabler.ccolor[col16]
return {col[0],col[1],col[2]} return {col[0],col[1],col[2]}
end end
function addGems() function addGems()
for k,v in pairs(df.global.world.raws.inorganics) do for k,v in pairs(df.global.world.raws.inorganics) do
if v.material.flags.IS_GEM then if v.material.flags.IS_GEM then
addMaterial("INORGANIC:"..v.id,colorFrom16(v.material.tile_color[0]+v.material.tile_color[2]*8)) addMaterial("INORGANIC:"..v.id,colorFrom16(v.material.tile_color[0]+v.material.tile_color[2]*8))
end end
end end
end end
------------------------------------------------------------------------ ------------------------------------------------------------------------
---------------- Configuration Starts Here ------------------------- ---------------- Configuration Starts Here -------------------------
------------------------------------------------------------------------ ------------------------------------------------------------------------
is_computer_quantum=false -- will enable more costly parts in the future is_computer_quantum=false -- will enable more costly parts in the future
--special things --special things
special.LAVA=makeMaterialDef({0.8,0.2,0.2},{0.8,0.2,0.2},5) special.LAVA=makeMaterialDef({0.8,0.2,0.2},{0.8,0.2,0.2},5)
special.WATER=makeMaterialDef({0.5,0.5,0.8}) special.WATER=makeMaterialDef({0.5,0.5,0.8})
special.FROZEN_LIQUID=makeMaterialDef({0.2,0.7,0.9}) -- ice special.FROZEN_LIQUID=makeMaterialDef({0.2,0.7,0.9}) -- ice
special.AMBIENT=makeMaterialDef({0.85,0.85,0.85}) --ambient fog special.AMBIENT=makeMaterialDef({0.85,0.85,0.85}) --ambient fog
special.CURSOR=makeMaterialDef({1,1,1},{0.96,0.84,0.03},11, {"flicker"}) special.CURSOR=makeMaterialDef({1,1,1},{0.96,0.84,0.03},11, {"flicker"})
special.CITIZEN=makeMaterialDef(nil,{0.80,0.80,0.90},6) special.CITIZEN=makeMaterialDef(nil,{0.80,0.80,0.90},6)
special.LevelDim=0.2 -- darkness. Do not set to 0 special.LevelDim=0.2 -- darkness. Do not set to 0
special.dayHour=-1 -- <0 cycle, else hour of the day special.dayHour=-1 -- <0 cycle, else hour of the day
special.dayColors={ {0,0,0}, --dark at 0 hours special.dayColors={ {0,0,0}, --dark at 0 hours
{0.6,0.5,0.5}, --reddish twilight {0.6,0.5,0.5}, --reddish twilight
{1,1,1}, --fullbright at 12 hours {1,1,1}, --fullbright at 12 hours
{0.5,0.5,0.5}, {0.5,0.5,0.5},
{0,0,0}} --dark at 24 hours {0,0,0}} --dark at 24 hours
special.daySpeed=1 -- 1->1200 cur_year_ticks per day. 2->600 ticks special.daySpeed=1 -- 1->1200 cur_year_ticks per day. 2->600 ticks
special.diffusionCount=1 -- split beam max 1 times to mimic diffuse lights special.diffusionCount=1 -- split beam max 1 times to mimic diffuse lights
special.advMode=0 -- 1 or 0 different modes for adv mode. 0-> use df vision system, special.advMode=0 -- 1 or 0 different modes for adv mode. 0-> use df vision system,
-- 1(does not work)->everything visible, let rendermax light do the work -- 1(does not work)->everything visible, let rendermax light do the work
--TODO dragonfire --TODO dragonfire
--materials --materials
-- glasses -- glasses
addMaterial("GLASS_GREEN",{0.1,0.9,0.5}) addMaterial("GLASS_GREEN",{0.1,0.9,0.5})
addMaterial("GLASS_CLEAR",{0.5,0.95,0.9}) addMaterial("GLASS_CLEAR",{0.5,0.95,0.9})
addMaterial("GLASS_CRYSTAL",{0.75,0.95,0.95}) addMaterial("GLASS_CRYSTAL",{0.75,0.95,0.95})
-- Plants -- Plants
addMaterial("PLANT:TOWER_CAP",nil,{0.65,0.65,0.65},6) addMaterial("PLANT:TOWER_CAP",nil,{0.65,0.65,0.65},6)
addMaterial("PLANT:MUSHROOM_CUP_DIMPLE",nil,{0.03,0.03,0.5},3) addMaterial("PLANT:MUSHROOM_CUP_DIMPLE",nil,{0.03,0.03,0.5},3)
addMaterial("PLANT:CAVE MOSS",nil,{0.1,0.1,0.4},2) addMaterial("PLANT:CAVE MOSS",nil,{0.1,0.1,0.4},2)
addMaterial("PLANT:MUSHROOM_HELMET_PLUMP",nil,{0.2,0.1,0.6},2) addMaterial("PLANT:MUSHROOM_HELMET_PLUMP",nil,{0.2,0.1,0.6},2)
-- inorganics -- inorganics
addMaterial("INORGANIC:ADAMANTINE",{0.1,0.3,0.3},{0.1,0.3,0.3},4) addMaterial("INORGANIC:ADAMANTINE",{0.1,0.3,0.3},{0.1,0.3,0.3},4)
-- creature stuff -- creature stuff
addMaterial("CREATURE:DRAGON:BLOOD",nil,{0.6,0.1,0.1},4) addMaterial("CREATURE:DRAGON:BLOOD",nil,{0.6,0.1,0.1},4)
addGems() addGems()
--buildings --buildings
addBuilding("Statue",{1,1,1},{0.9,0.75,0.3},8) addBuilding("Statue",{1,1,1},{0.9,0.75,0.3},8)
addBuilding("Bed",{1,1,1},{0.3,0.2,0.0},2) addBuilding("Bed",{1,1,1},{0.3,0.2,0.0},2)
addBuilding("WindowGlass",nil,nil,0,{"useMaterial"}) addBuilding("WindowGlass",nil,nil,0,{"useMaterial"})
addBuilding("WindowGem",nil,nil,0,{"useMaterial"}) addBuilding("WindowGem",nil,nil,0,{"useMaterial"})
addBuilding("Door",nil,nil,0,{"useMaterial"}) -- special case, only closed door obstruct/emit light addBuilding("Door",nil,nil,0,{"useMaterial"}) -- special case, only closed door obstruct/emit light
addBuilding("Floodgate",nil,nil,0,{"useMaterial"}) -- special case, only closed door obstruct/emit light addBuilding("Floodgate",nil,nil,0,{"useMaterial"}) -- special case, only closed door obstruct/emit light
--creatures --creatures
addCreature("ELEMENTMAN_MAGMA",{0.8,0.2,0.2},{0.8,0.2,0.2},5) addCreature("ELEMENTMAN_MAGMA",{0.8,0.2,0.2},{0.8,0.2,0.2},5)
--items --items
addItem("GEM",nil,nil,{"useMaterial","onGround"}) addItem("GEM",nil,nil,{"useMaterial","onGround"})
addItem("ROUGH",nil,nil,{"useMaterial","onGround"}) addItem("ROUGH",nil,nil,{"useMaterial","onGround"})
addItem("SMALLGEM",nil,nil,{"useMaterial","onGround"}) addItem("SMALLGEM",nil,nil,{"useMaterial","onGround"})

@ -56,7 +56,7 @@ static void for_each_(vector<T> &v, Fn func)
for_each(v.begin(), v.end(), func); for_each(v.begin(), v.end(), func);
} }
template <class T, class V, typename Fn> template <class T, class V, typename Fn>
static void transform_(vector<T> &src, vector<V> &dst, Fn func) static void transform_(vector<T> &src, vector<V> &dst, Fn func)
{ {
transform(src.begin(), src.end(), back_inserter(dst), func); transform(src.begin(), src.end(), back_inserter(dst), func);
@ -299,7 +299,7 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <Plug
commands.push_back( commands.push_back(
PluginCommand( PluginCommand(
"resume", "A plugin to help display and resume suspended constructions conveniently", "resume", "A plugin to help display and resume suspended constructions conveniently",
resume_cmd, false, resume_cmd, false,
"resume show\n" "resume show\n"
" Show overlay when paused:\n" " Show overlay when paused:\n"
" Yellow: Suspended construction\n" " Yellow: Suspended construction\n"

@ -321,7 +321,7 @@ module DFHack
def building_setowner(bld, unit) def building_setowner(bld, unit)
return unless bld.is_room return unless bld.is_room
return if bld.owner == unit return if bld.owner == unit
if bld.owner if bld.owner
if idx = bld.owner.owned_buildings.index { |ob| ob.id == bld.id } if idx = bld.owner.owned_buildings.index { |ob| ob.id == bld.id }
bld.owner.owned_buildings.delete_at(idx) bld.owner.owned_buildings.delete_at(idx)

@ -58,7 +58,7 @@ module DFHack
# returns an Array of all units that are current fort citizen (dwarves, on map, not hostile) # returns an Array of all units that are current fort citizen (dwarves, on map, not hostile)
def unit_citizens def unit_citizens
world.units.active.find_all { |u| world.units.active.find_all { |u|
unit_iscitizen(u) unit_iscitizen(u)
} }
end end
@ -178,7 +178,7 @@ module DFHack
when :Unsure when :Unsure
# from df code, with removed duplicate checks already in other_category # from df code, with removed duplicate checks already in other_category
return true if u.enemy.undead or u.flags3.ghostly or u.flags1.marauder return true if u.enemy.undead or u.flags3.ghostly or u.flags1.marauder
return false if u.flags1.forest or u.flags1.merchant or u.flags1.diplomat or u.flags2.visitor return false if u.flags1.forest or u.flags1.merchant or u.flags1.diplomat or u.flags2.visitor
return true if u.flags1.tame or u.flags2.underworld return true if u.flags1.tame or u.flags2.underworld
@ -282,7 +282,7 @@ module DFHack
def unit_isidler(u) def unit_isidler(u)
unit_isworker(u) and unit_isworker(u) and
# current_job includes eat/drink/sleep/pickupequip # current_job includes eat/drink/sleep/pickupequip
!u.job.current_job and !u.job.current_job and
# filter 'attend meeting' # filter 'attend meeting'
not u.specific_refs.find { |s| s.type == :ACTIVITY } and not u.specific_refs.find { |s| s.type == :ACTIVITY } and
# filter soldiers (TODO check schedule) # filter soldiers (TODO check schedule)

@ -119,7 +119,7 @@ command_result df_seedwatch(color_ostream &out, vector<string>& parameters)
World::ReadGameMode(gm);// FIXME: check return value World::ReadGameMode(gm);// FIXME: check return value
// if game mode isn't fortress mode // if game mode isn't fortress mode
if(gm.g_mode != game_mode::DWARF || if(gm.g_mode != game_mode::DWARF ||
!(gm.g_type == game_type::DWARF_MAIN || gm.g_type == game_type::DWARF_RECLAIM)) !(gm.g_type == game_type::DWARF_MAIN || gm.g_type == game_type::DWARF_RECLAIM))
{ {
// just print the help // just print the help
@ -310,7 +310,7 @@ DFhackCExport command_result plugin_onupdate(color_ostream &out)
t_gamemodes gm; t_gamemodes gm;
World::ReadGameMode(gm);// FIXME: check return value World::ReadGameMode(gm);// FIXME: check return value
// if game mode isn't fortress mode // if game mode isn't fortress mode
if(gm.g_mode != game_mode::DWARF || if(gm.g_mode != game_mode::DWARF ||
!(gm.g_type == game_type::DWARF_MAIN || gm.g_type == game_type::DWARF_RECLAIM)) !(gm.g_type == game_type::DWARF_MAIN || gm.g_type == game_type::DWARF_RECLAIM))
{ {
// stop running. // stop running.

@ -65,7 +65,7 @@ class LuaHelper {
public: public:
void cycle(color_ostream &out) { void cycle(color_ostream &out) {
bool found = false; bool found = false;
if (fast) { if (fast) {
// Ignore the bookkeeper; either gather or enqueue orders every cycle. // Ignore the bookkeeper; either gather or enqueue orders every cycle.
found = !bookkeeping; found = !bookkeeping;
@ -80,7 +80,7 @@ public:
} }
} }
} }
if (found && !bookkeeping) { if (found && !bookkeeping) {
command_method("start_bookkeeping", out); command_method("start_bookkeeping", out);
bookkeeping = true; bookkeeping = true;
@ -89,7 +89,7 @@ public:
bookkeeping = false; bookkeeping = false;
} }
} }
void init() { void init() {
stockpile_id = -1; stockpile_id = -1;
initialized = false; initialized = false;
@ -105,96 +105,96 @@ public:
initialized = false; initialized = false;
return command_method("clear_caches", out); return command_method("clear_caches", out);
} }
return true; return true;
} }
bool command_method(const char *method, color_ostream &out) { bool command_method(const char *method, color_ostream &out) {
// Calls a lua function with no parameters. // Calls a lua function with no parameters.
// Suspension is required for "stockflow enable" from the command line, // Suspension is required for "stockflow enable" from the command line,
// but may be overkill for other situations. // but may be overkill for other situations.
CoreSuspender suspend; CoreSuspender suspend;
auto L = Lua::Core::State; auto L = Lua::Core::State;
Lua::StackUnwinder top(L); Lua::StackUnwinder top(L);
if (!lua_checkstack(L, 1)) if (!lua_checkstack(L, 1))
return false; return false;
if (!Lua::PushModulePublic(out, L, "plugins.stockflow", method)) if (!Lua::PushModulePublic(out, L, "plugins.stockflow", method))
return false; return false;
if (!Lua::SafeCall(out, L, 0, 0)) if (!Lua::SafeCall(out, L, 0, 0))
return false; return false;
return true; return true;
} }
bool stockpile_method(const char *method, building_stockpilest *sp) { bool stockpile_method(const char *method, building_stockpilest *sp) {
// Combines the select_order and toggle_trigger method calls, // Combines the select_order and toggle_trigger method calls,
// because they share the same signature. // because they share the same signature.
CoreSuspendClaimer suspend; CoreSuspendClaimer suspend;
auto L = Lua::Core::State; auto L = Lua::Core::State;
color_ostream_proxy out(Core::getInstance().getConsole()); color_ostream_proxy out(Core::getInstance().getConsole());
Lua::StackUnwinder top(L); Lua::StackUnwinder top(L);
if (!lua_checkstack(L, 2)) if (!lua_checkstack(L, 2))
return false; return false;
if (!Lua::PushModulePublic(out, L, "plugins.stockflow", method)) if (!Lua::PushModulePublic(out, L, "plugins.stockflow", method))
return false; return false;
Lua::Push(L, sp); Lua::Push(L, sp);
if (!Lua::SafeCall(out, L, 1, 0)) if (!Lua::SafeCall(out, L, 1, 0))
return false; return false;
// Invalidate the string cache. // Invalidate the string cache.
stockpile_id = -1; stockpile_id = -1;
return true; return true;
} }
bool collect_settings(building_stockpilest *sp) { bool collect_settings(building_stockpilest *sp) {
// Find strings representing the job to order, and the trigger condition. // Find strings representing the job to order, and the trigger condition.
// There might be a memory leak here; C++ is odd like that. // There might be a memory leak here; C++ is odd like that.
auto L = Lua::Core::State; auto L = Lua::Core::State;
color_ostream_proxy out(Core::getInstance().getConsole()); color_ostream_proxy out(Core::getInstance().getConsole());
CoreSuspendClaimer suspend; CoreSuspendClaimer suspend;
Lua::StackUnwinder top(L); Lua::StackUnwinder top(L);
if (!lua_checkstack(L, 2)) if (!lua_checkstack(L, 2))
return false; return false;
if (!Lua::PushModulePublic(out, L, "plugins.stockflow", "stockpile_settings")) if (!Lua::PushModulePublic(out, L, "plugins.stockflow", "stockpile_settings"))
return false; return false;
Lua::Push(L, sp); Lua::Push(L, sp);
if (!Lua::SafeCall(out, L, 1, 2)) if (!Lua::SafeCall(out, L, 1, 2))
return false; return false;
if (!lua_isstring(L, -1)) if (!lua_isstring(L, -1))
return false; return false;
current_trigger = lua_tostring(L, -1); current_trigger = lua_tostring(L, -1);
lua_pop(L, 1); lua_pop(L, 1);
if (!lua_isstring(L, -1)) if (!lua_isstring(L, -1))
return false; return false;
current_job = lua_tostring(L, -1); current_job = lua_tostring(L, -1);
lua_pop(L, 1); lua_pop(L, 1);
stockpile_id = sp->id; stockpile_id = sp->id;
return true; return true;
} }
void draw(building_stockpilest *sp) { void draw(building_stockpilest *sp) {
if (sp->id != stockpile_id) { if (sp->id != stockpile_id) {
if (!collect_settings(sp)) { if (!collect_settings(sp)) {
@ -202,12 +202,12 @@ public:
return; return;
} }
} }
auto dims = Gui::getDwarfmodeViewDims(); auto dims = Gui::getDwarfmodeViewDims();
int left_margin = dims.menu_x1 + 1; int left_margin = dims.menu_x1 + 1;
int x = left_margin; int x = left_margin;
int y = dims.y2 - 3; int y = dims.y2 - 3;
int links = 0; int links = 0;
links += sp->links.give_to_pile.size(); links += sp->links.give_to_pile.size();
links += sp->links.take_from_pile.size(); links += sp->links.take_from_pile.size();
@ -215,7 +215,7 @@ public:
links += sp->links.take_from_workshop.size(); links += sp->links.take_from_workshop.size();
if (links + 12 >= y) if (links + 12 >= y)
y += 1; y += 1;
OutputHotkeyString(x, y, current_job, "j", true, left_margin, COLOR_WHITE, COLOR_LIGHTRED); OutputHotkeyString(x, y, current_job, "j", true, left_margin, COLOR_WHITE, COLOR_LIGHTRED);
if (*current_trigger) if (*current_trigger)
OutputHotkeyString(x, y, current_trigger, " J", true, left_margin, COLOR_WHITE, COLOR_LIGHTRED); OutputHotkeyString(x, y, current_trigger, " J", true, left_margin, COLOR_WHITE, COLOR_LIGHTRED);
@ -235,9 +235,9 @@ static LuaHelper helper;
#define DELTA_TICKS 600 #define DELTA_TICKS 600
DFhackCExport command_result plugin_onupdate(color_ostream &out) { DFhackCExport command_result plugin_onupdate(color_ostream &out) {
if (!enabled) if (!enabled)
return CR_OK; return CR_OK;
if (!Maps::IsValid()) if (!Maps::IsValid())
return CR_OK; return CR_OK;
@ -262,39 +262,39 @@ DFhackCExport command_result plugin_onupdate(color_ostream &out) {
*/ */
struct stockflow_hook : public df::viewscreen_dwarfmodest { struct stockflow_hook : public df::viewscreen_dwarfmodest {
typedef df::viewscreen_dwarfmodest interpose_base; typedef df::viewscreen_dwarfmodest interpose_base;
bool handleInput(set<df::interface_key> *input) { bool handleInput(set<df::interface_key> *input) {
building_stockpilest *sp = get_selected_stockpile(); building_stockpilest *sp = get_selected_stockpile();
if (!sp) if (!sp)
return false; return false;
if (input->count(interface_key::CUSTOM_J)) { if (input->count(interface_key::CUSTOM_J)) {
// Select a new order for this stockpile. // Select a new order for this stockpile.
if (!helper.stockpile_method("select_order", sp)) { if (!helper.stockpile_method("select_order", sp)) {
Core::printerr("Stockflow order selection failed!\n"); Core::printerr("Stockflow order selection failed!\n");
} }
return true; return true;
} else if (input->count(interface_key::CUSTOM_SHIFT_J)) { } else if (input->count(interface_key::CUSTOM_SHIFT_J)) {
// Toggle the order trigger for this stockpile. // Toggle the order trigger for this stockpile.
if (!helper.stockpile_method("toggle_trigger", sp)) { if (!helper.stockpile_method("toggle_trigger", sp)) {
Core::printerr("Stockflow trigger toggle failed!\n"); Core::printerr("Stockflow trigger toggle failed!\n");
} }
return true; return true;
} }
return false; return false;
} }
DEFINE_VMETHOD_INTERPOSE(void, feed, (set<df::interface_key> *input)) { DEFINE_VMETHOD_INTERPOSE(void, feed, (set<df::interface_key> *input)) {
if (!handleInput(input)) if (!handleInput(input))
INTERPOSE_NEXT(feed)(input); INTERPOSE_NEXT(feed)(input);
} }
DEFINE_VMETHOD_INTERPOSE(void, render, ()) { DEFINE_VMETHOD_INTERPOSE(void, render, ()) {
INTERPOSE_NEXT(render)(); INTERPOSE_NEXT(render)();
building_stockpilest *sp = get_selected_stockpile(); building_stockpilest *sp = get_selected_stockpile();
if (sp) if (sp)
helper.draw(sp); helper.draw(sp);
@ -310,17 +310,17 @@ static bool apply_hooks(color_ostream &out, bool enabling) {
out.printerr("Stockflow needs graphics.\n"); out.printerr("Stockflow needs graphics.\n");
return false; return false;
} }
if (!INTERPOSE_HOOK(stockflow_hook, feed).apply(enabling) || !INTERPOSE_HOOK(stockflow_hook, render).apply(enabling)) { if (!INTERPOSE_HOOK(stockflow_hook, feed).apply(enabling) || !INTERPOSE_HOOK(stockflow_hook, render).apply(enabling)) {
out.printerr("Could not %s stockflow hooks!\n", enabling? "insert": "remove"); out.printerr("Could not %s stockflow hooks!\n", enabling? "insert": "remove");
return false; return false;
} }
if (!helper.reset(out, enabling && Maps::IsValid())) { if (!helper.reset(out, enabling && Maps::IsValid())) {
out.printerr("Could not reset stockflow world data!\n"); out.printerr("Could not reset stockflow world data!\n");
return false; return false;
} }
return true; return true;
} }
@ -344,12 +344,12 @@ static command_result stockflow_cmd(color_ostream &out, vector <string> & parame
out.printerr("Stockflow is not currently enabled.\n"); out.printerr("Stockflow is not currently enabled.\n");
return CR_FAILURE; return CR_FAILURE;
} }
if (!Maps::IsValid()) { if (!Maps::IsValid()) {
out.printerr("You haven't loaded a map yet.\n"); out.printerr("You haven't loaded a map yet.\n");
return CR_FAILURE; return CR_FAILURE;
} }
// Tell Lua to list any saved stockpile orders. // Tell Lua to list any saved stockpile orders.
return helper.command_method("list_orders", out)? CR_OK: CR_FAILURE; return helper.command_method("list_orders", out)? CR_OK: CR_FAILURE;
} else if (parameters[0] != "status") { } else if (parameters[0] != "status") {
@ -358,13 +358,13 @@ static command_result stockflow_cmd(color_ostream &out, vector <string> & parame
} else if (parameters.size() > 1) { } else if (parameters.size() > 1) {
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
if (desired != enabled) { if (desired != enabled) {
if (!apply_hooks(out, desired)) { if (!apply_hooks(out, desired)) {
return CR_FAILURE; return CR_FAILURE;
} }
} }
out.print("Stockflow is %s %s%s.\n", (desired == enabled)? "currently": "now", desired? "enabled": "disabled", fast? ", in fast mode": ""); out.print("Stockflow is %s %s%s.\n", (desired == enabled)? "currently": "now", desired? "enabled": "disabled", fast? ", in fast mode": "");
enabled = desired; enabled = desired;
return CR_OK; return CR_OK;
@ -383,7 +383,7 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan
return CR_FAILURE; return CR_FAILURE;
} }
} }
return CR_OK; return CR_OK;
} }
@ -394,10 +394,10 @@ DFhackCExport command_result plugin_enable(color_ostream& out, bool enable) {
if (!apply_hooks(out, enable)) { if (!apply_hooks(out, enable)) {
return CR_FAILURE; return CR_FAILURE;
} }
enabled = enable; enabled = enable;
} }
return CR_OK; return CR_OK;
} }
@ -407,10 +407,10 @@ DFhackCExport command_result plugin_init(color_ostream &out, std::vector <Plugin
if (!apply_hooks(out, true)) { if (!apply_hooks(out, true)) {
return CR_FAILURE; return CR_FAILURE;
} }
enabled = true; enabled = true;
} }
commands.push_back(PluginCommand(name, tagline, stockflow_cmd, false, usage)); commands.push_back(PluginCommand(name, tagline, stockflow_cmd, false, usage));
return CR_OK; return CR_OK;
} }

Some files were not shown because too many files have changed in this diff Show More