From b76bdad50f03e5083b7dae99c5e1d2d8f80fc72d Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Wed, 28 Mar 2012 01:47:52 +0800 Subject: [PATCH 01/11] Implement recursive transfer of values from lua to c++ structures. E.g. df.global.cursor = { x = 1, y = 2, z = 3 }. The lua data must be represented by raw lua tables. For structs, the entries in the table are assigned to matching fields. For containers, if a 'resize' field is missing or nil, the table is treated like 1-based lua array, and the container is resized to match its # length. Otherwise, the field must be either an explicit number, true or false. If it is true, the size is selected by the highest index in the table. After that, entries are copied using 0-based indices. For pointers, the table must match the target object. If the pointer is null, the object is auto-allocated; this can be controlled using the 'new' field, the value of which will be passed to df.new(). --- library/LuaTypes.cpp | 70 ++++++++++++++++++++- library/LuaWrapper.cpp | 115 ++++++++++++++++++++++++++++++++--- library/include/LuaWrapper.h | 7 +++ 3 files changed, 181 insertions(+), 11 deletions(-) diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp index 536bcd72a..1e33ed713 100644 --- a/library/LuaTypes.cpp +++ b/library/LuaTypes.cpp @@ -65,9 +65,22 @@ void constructed_identity::lua_read(lua_State *state, int fname_idx, void *ptr) push_object_internal(state, this, ptr); } +static void invoke_assign(lua_State *state, type_identity *id, void *ptr, int val_index) +{ + lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_ASSIGN_NAME); + push_object_internal(state, id, ptr); + lua_pushvalue(state, val_index); + lua_call(state, 2, 0); +} + void constructed_identity::lua_write(lua_State *state, int fname_idx, void *ptr, int val_index) { - field_error(state, fname_idx, "complex object", "write"); + if (lua_istable(state, val_index)) + { + invoke_assign(state, this, ptr, val_index); + } + else + field_error(state, fname_idx, "complex object", "write"); } void enum_identity::lua_read(lua_State *state, int fname_idx, void *ptr) @@ -150,6 +163,47 @@ void df::pointer_identity::lua_read(lua_State *state, int fname_idx, void *ptr) lua_read(state, fname_idx, ptr, target); } +static void autovivify_ptr(lua_State *state, int fname_idx, void **pptr, + type_identity *target, int val_index) +{ + lua_getfield(state, val_index, "new"); + + if (!lua_isnil(state, -1)) + { + int top = lua_gettop(state); + + type_identity *suggested = get_object_identity(state, top, "autovivify", true, true); + + if (!is_type_compatible(state, target, 0, suggested, top+1, false)) + field_error(state, fname_idx, "incompatible suggested autovivify type", "write"); + + lua_pop(state, 1); + + lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_NEW_NAME); + lua_swap(state); + lua_call(state, 1, 1); + + void *nval = get_object_internal(state, target, top, false); + + if (!nval) + field_error(state, fname_idx, "inconsistent autovivify type", "write"); + + *pptr = nval; + } + else + { + if (!target) + field_error(state, fname_idx, "trying to autovivify void*", "write"); + + *pptr = target->allocate(); + + if (!*pptr) + field_error(state, fname_idx, "could not allocate in autovivify", "write"); + } + + lua_pop(state, 1); +} + void df::pointer_identity::lua_write(lua_State *state, int fname_idx, void *ptr, type_identity *target, int val_index) { @@ -157,6 +211,13 @@ void df::pointer_identity::lua_write(lua_State *state, int fname_idx, void *ptr, if (lua_isnil(state, val_index)) *pptr = NULL; + else if (lua_istable(state, val_index)) + { + if (!*pptr) + autovivify_ptr(state, fname_idx, pptr, target, val_index); + + invoke_assign(state, target, *pptr, val_index); + } else { void *nval = get_object_internal(state, target, val_index, false); @@ -435,10 +496,15 @@ static void write_field(lua_State *state, const struct_field_info *field, void * case struct_field_info::POINTER: df::pointer_identity::lua_write(state, 2, ptr, field->type, value_idx); + return; case struct_field_info::STATIC_ARRAY: case struct_field_info::STL_VECTOR_PTR: - field_error(state, 2, "complex object", "write"); + lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_ASSIGN_NAME); + read_field(state, field, ptr); + lua_pushvalue(state, value_idx); + lua_call(state, 2, 0); + return; case struct_field_info::END: return; diff --git a/library/LuaWrapper.cpp b/library/LuaWrapper.cpp index 4758f04f1..11db14875 100644 --- a/library/LuaWrapper.cpp +++ b/library/LuaWrapper.cpp @@ -255,8 +255,8 @@ static void fetch_container_details(lua_State *state, int meta, type_identity ** /** * Check if type1 and type2 are compatible, possibly using additional metatable data. */ -static bool is_type_compatible(lua_State *state, type_identity *type1, int meta1, - type_identity *type2, int meta2, bool exact_equal) +bool LuaWrapper::is_type_compatible(lua_State *state, type_identity *type1, int meta1, + type_identity *type2, int meta2, bool exact_equal) { if (type1 == type2) return true; @@ -417,9 +417,9 @@ static bool is_valid_metatable(lua_State *state, int objidx, int metaidx) /** * Given a DF object reference or type, safely retrieve its identity pointer. */ -static type_identity *get_object_identity(lua_State *state, int objidx, - const char *ctx, bool allow_type = false, - bool keep_metatable = false) +type_identity *LuaWrapper::get_object_identity(lua_State *state, int objidx, + const char *ctx, bool allow_type, + bool keep_metatable) { if (!lua_getmetatable(state, objidx)) luaL_error(state, "Invalid object in %s", ctx); @@ -608,6 +608,31 @@ static int meta_new(lua_State *state) return 1; } +static void invoke_resize(lua_State *state, int table, lua_Integer size) +{ + lua_getfield(state, table, "resize"); + lua_pushvalue(state, table); + lua_pushinteger(state, size); + lua_call(state, 2, 0); +} + +static void copy_table(lua_State *state, int dest, int src, int skipkey) +{ + lua_pushnil(state); + + while (lua_next(state, src)) + { + if (lua_equal(state, -2, skipkey)) + lua_pop(state, 1); + else + { + lua_pushvalue(state, -2); + lua_swap(state); + lua_settable(state, dest); + } + } +} + /** * Method: assign data between objects. */ @@ -618,11 +643,83 @@ static int meta_assign(lua_State *state) if (argc != 2) luaL_error(state, "Usage: target:assign(src) or df.assign(target,src)"); - type_identity *id1, *id2; - check_type_compatible(state, 1, 2, &id1, &id2, "df.assign()", false, false); + if (!lua_istable(state, 2)) + { + type_identity *id1, *id2; + check_type_compatible(state, 1, 2, &id1, &id2, "df.assign()", false, false); + + if (!id1->copy(get_object_ref(state, 1), get_object_ref(state, 2))) + luaL_error(state, "No copy support for %s", id1->getFullName().c_str()); + } + else + { + type_identity *id = get_object_identity(state, 1, "df.assign()", false); + + if (id->isContainer()) + { + lua_pushstring(state, "resize"); + int resize_str = lua_gettop(state); - if (!id1->copy(get_object_ref(state, 1), get_object_ref(state, 2))) - luaL_error(state, "No copy support for %s", id1->getFullName().c_str()); + lua_dup(state); + lua_rawget(state, 2); + + if (lua_isnil(state,-1)) + { + /* + * nil or missing resize field => 1-based lua array + */ + int size = lua_objlen(state, 2); + + lua_pop(state, 1); + invoke_resize(state, 1, size); + + for (int i = 1; i <= size; i++) + { + lua_pushinteger(state, i-1); + lua_rawgeti(state, 2, i); + lua_settable(state, 1); + } + } + else + { + if (lua_isboolean(state, -1)) + { + // resize=false => just assign + // resize=true => find the largest index + if (lua_toboolean(state, -1)) + { + lua_Integer size = 0; + + lua_pushnil(state); + while (lua_next(state, 2)) + { + lua_pop(state, 1); + if (lua_isnumber(state,-1)) + size = std::max(size, lua_tointeger(state,-1)+1); + } + + invoke_resize(state, 1, size); + } + } + else + { + // otherwise, must be an explicit number + if (!lua_isnumber(state,-1)) + luaL_error(state, "Invalid container.resize value in df.assign()"); + + invoke_resize(state, 1, lua_tointeger(state, -1)); + } + + lua_pop(state, 1); + copy_table(state, 1, 2, resize_str); + } + } + else + { + lua_pushstring(state, "new"); + copy_table(state, 1, 2, lua_gettop(state)); + } + } return 0; } diff --git a/library/include/LuaWrapper.h b/library/include/LuaWrapper.h index d043d96f7..64ebf4de6 100644 --- a/library/include/LuaWrapper.h +++ b/library/include/LuaWrapper.h @@ -149,6 +149,13 @@ namespace DFHack { namespace LuaWrapper { */ uint8_t *get_object_addr(lua_State *state, int obj, int field, const char *mode); + bool is_type_compatible(lua_State *state, type_identity *type1, int meta1, + type_identity *type2, int meta2, bool exact_equal); + + type_identity *get_object_identity(lua_State *state, int objidx, + const char *ctx, bool allow_type = false, + bool keep_metatable = false); + void LookupInTable(lua_State *state, void *id, const char *tname); void SaveInTable(lua_State *state, void *node, const char *tname); void SaveTypeInfo(lua_State *state, void *node); From 13d7beda4b6b4187852745ebbe48a25b036e26b3 Mon Sep 17 00:00:00 2001 From: Warmist Date: Wed, 28 Mar 2012 03:47:23 +0800 Subject: [PATCH 02/11] Dfusion crash fix --- plugins/Dfusion/src/lua_VersionInfo.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/Dfusion/src/lua_VersionInfo.cpp b/plugins/Dfusion/src/lua_VersionInfo.cpp index 5ce469d35..9f5cd17e7 100644 --- a/plugins/Dfusion/src/lua_VersionInfo.cpp +++ b/plugins/Dfusion/src/lua_VersionInfo.cpp @@ -96,7 +96,8 @@ const luaL_Reg lua_vinfo_func[]= VI_FUNC(setAddress), VI_FUNC(getAddress), VI_FUNC(setOS), - VI_FUNC(getOS) + VI_FUNC(getOS), + {NULL,NULL} }; #undef VI_FUNC void lua::RegisterVersionInfo(lua::state &st) From 9604be2701616c437a7b3a84974d761d1143dd20 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 28 Mar 2012 10:39:06 +0800 Subject: [PATCH 03/11] Fix crash in autolabor that happens when all dorfs decide to tipple at the same time --- plugins/autolabor.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/autolabor.cpp b/plugins/autolabor.cpp index 3ef0f9e5c..c87d6ffbf 100644 --- a/plugins/autolabor.cpp +++ b/plugins/autolabor.cpp @@ -802,7 +802,6 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) } // Idle dwarves come first, then we sort from least-skilled to most-skilled. - std::sort(hauler_ids.begin(), hauler_ids.end(), [&dwarf_info] (int i, int j) -> bool { if (dwarf_info[i].state == IDLE && dwarf_info[j].state != IDLE) @@ -812,6 +811,11 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) return dwarf_info[i].mastery_penalty > dwarf_info[j].mastery_penalty; }); + // don't set any haulers if everyone is off drinking or something + if (hauler_ids.size() == 0) { + num_haulers = 0; + } + FOR_ENUM_ITEMS(unit_labor, labor) { if (labor == df::enums::unit_labor::NONE) @@ -831,7 +835,6 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) assert(dwarf >= 0); assert(dwarf < n_dwarfs); - dwarfs[dwarf]->status.labors[labor] = true; dwarf_info[dwarf].assigned_jobs++; } @@ -848,7 +851,6 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) dwarfs[dwarf]->status.labors[labor] = false; } } - return CR_OK; } From fe091de0b23791a7a76382e66b2c923edeea19cb Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Wed, 28 Mar 2012 15:25:55 +0800 Subject: [PATCH 04/11] Fix F keys in keybindings: they obviously don't have unicode symbols. --- library/Core.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/library/Core.cpp b/library/Core.cpp index afaf23683..b298b9550 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -972,6 +972,7 @@ int Core::UnicodeAwareSym(const SDL::KeyboardEvent& ke) { // Assume keyboard layouts don't change the order of numbers: if( '0' <= ke.ksym.sym && ke.ksym.sym <= '9') return ke.ksym.sym; + if(SDL::K_F1 <= ke.ksym.sym && ke.ksym.sym <= SDL::K_F12) return ke.ksym.sym; int unicode = ke.ksym.unicode; From 929657bed4e1300537a88401de9e3b14f2e1dc72 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Wed, 28 Mar 2012 15:28:42 +0800 Subject: [PATCH 05/11] Disable pointer auto-vivification unless new is specified. Since it is essentially allocating non-gc managed objects, it can lead to memory leaks and shouldn't happen invisibly. Also support using the 'assign' key to request assign() from another object before processing the current map. --- library/LuaTypes.cpp | 13 +++++++++- library/LuaWrapper.cpp | 58 +++++++++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp index 1e33ed713..79f515d40 100644 --- a/library/LuaTypes.cpp +++ b/library/LuaTypes.cpp @@ -168,10 +168,16 @@ static void autovivify_ptr(lua_State *state, int fname_idx, void **pptr, { lua_getfield(state, val_index, "new"); - if (!lua_isnil(state, -1)) + // false or nil => bail out + if (!lua_toboolean(state, -1)) + field_error(state, fname_idx, "null and autovivify not requested", "write"); + + // not 'true' => call df.new() + if (!lua_isboolean(state, -1)) { int top = lua_gettop(state); + // Verify new points to a reasonable type of object type_identity *suggested = get_object_identity(state, top, "autovivify", true, true); if (!is_type_compatible(state, target, 0, suggested, top+1, false)) @@ -179,17 +185,22 @@ static void autovivify_ptr(lua_State *state, int fname_idx, void **pptr, lua_pop(state, 1); + // Invoke df.new() lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_NEW_NAME); lua_swap(state); lua_call(state, 1, 1); + // Retrieve the pointer void *nval = get_object_internal(state, target, top, false); + // shouldn't happen: this means suggested type is compatible, + // but its new() result isn't for some reason. if (!nval) field_error(state, fname_idx, "inconsistent autovivify type", "write"); *pptr = nval; } + // otherwise use the target type else { if (!target) diff --git a/library/LuaWrapper.cpp b/library/LuaWrapper.cpp index 11db14875..36b24a403 100644 --- a/library/LuaWrapper.cpp +++ b/library/LuaWrapper.cpp @@ -616,20 +616,32 @@ static void invoke_resize(lua_State *state, int table, lua_Integer size) lua_call(state, 2, 0); } -static void copy_table(lua_State *state, int dest, int src, int skipkey) +static void copy_table(lua_State *state, int dest, int src, int skipbase) { + // stack: (skipbase) skipkey skipkey | + + int top = lua_gettop(state); + lua_pushnil(state); while (lua_next(state, src)) { - if (lua_equal(state, -2, skipkey)) - lua_pop(state, 1); - else + for (int i = skipbase+1; i <= top; i++) + { + if (lua_rawequal(state, -2, i)) + { + lua_pop(state, 1); + goto next_outer; + } + } + { lua_pushvalue(state, -2); lua_swap(state); lua_settable(state, dest); } + + next_outer:; } } @@ -655,18 +667,40 @@ static int meta_assign(lua_State *state) { type_identity *id = get_object_identity(state, 1, "df.assign()", false); + int base = lua_gettop(state); + + // x:assign{ assign = foo } => x:assign(foo) + bool has_assign = false; + + lua_pushstring(state, "assign"); + lua_dup(state); + lua_rawget(state, 2); + + if (!lua_isnil(state,-1)) + { + has_assign = true; + lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_ASSIGN_NAME); + lua_pushvalue(state, 1); + lua_pushvalue(state, base+2); + lua_call(state, 2, 0); + } + + lua_pop(state, 1); + + // new is used by autovivification and should be skipped + lua_pushstring(state, "new"); + if (id->isContainer()) { + // check resize field lua_pushstring(state, "resize"); - int resize_str = lua_gettop(state); - lua_dup(state); lua_rawget(state, 2); - if (lua_isnil(state,-1)) + if (lua_isnil(state,-1) && !has_assign) { /* - * nil or missing resize field => 1-based lua array + * no assign && nil or missing resize field => 1-based lua array */ int size = lua_objlen(state, 2); @@ -682,7 +716,7 @@ static int meta_assign(lua_State *state) } else { - if (lua_isboolean(state, -1)) + if (lua_isboolean(state, -1) || lua_isnil(state, -1)) { // resize=false => just assign // resize=true => find the largest index @@ -711,13 +745,13 @@ static int meta_assign(lua_State *state) } lua_pop(state, 1); - copy_table(state, 1, 2, resize_str); + copy_table(state, 1, 2, base); } } else { - lua_pushstring(state, "new"); - copy_table(state, 1, 2, lua_gettop(state)); + + copy_table(state, 1, 2, base); } } From 515a4467e84943b28221b7830fd57dc996bef1c0 Mon Sep 17 00:00:00 2001 From: Robert Heinrich Date: Mon, 26 Mar 2012 20:59:18 +0800 Subject: [PATCH 06/11] minor: fixed typo --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index f6046e344..988a6dd6a 100644 --- a/README.rst +++ b/README.rst @@ -112,7 +112,7 @@ Options ------- :all_biomes: Change layer for all biomes on your map. Result may be undesirable since the same layer can AND WILL be on different z-levels for different biomes. Use the tool 'probe' to get an idea how layers and biomes are distributed on your map. -:all-layers: Change all layers on your map. Candy mountain, anyone? Will make your map quite boring, but tidy. +:all_layers: Change all layers on your map. Candy mountain, anyone? Will make your map quite boring, but tidy. :force: Allow changing stone to soil and vice versa. !!THIS CAN HAVE WEIRD EFFECTS, USE WITH CARE!! Note that soil will not be magically replaced with stone. You will, however, get a stone floor after digging so it will allow the floor to be engraved. Note that stone will not be magically replaced with soil. You will, however, get a soil floor after digging so it could be helpful for creating farm plots on maps with no soil. From cebdbff46dc5db9424a1ac4ba96738a2115f01fe Mon Sep 17 00:00:00 2001 From: Robert Heinrich Date: Tue, 27 Mar 2012 17:28:10 +0800 Subject: [PATCH 07/11] minor updates in readme.rst; moved changelayer plugin to main plugin folder --- README.rst | 37 ++++++++++++----------- plugins/CMakeLists.txt | 8 +---- plugins/{changelayer => }/changelayer.cpp | 16 +++++++--- plugins/changelayer/CMakeLists.txt | 32 -------------------- 4 files changed, 31 insertions(+), 62 deletions(-) rename plugins/{changelayer => }/changelayer.cpp (96%) delete mode 100644 plugins/changelayer/CMakeLists.txt diff --git a/README.rst b/README.rst index 988a6dd6a..a1f8445ce 100644 --- a/README.rst +++ b/README.rst @@ -110,9 +110,10 @@ tl;dr: You will end up with changing quite big areas in one go, especially if yo Options ------- -:all_biomes: Change layer for all biomes on your map. +:all_biomes: Change selected layer for all biomes on your map. Result may be undesirable since the same layer can AND WILL be on different z-levels for different biomes. Use the tool 'probe' to get an idea how layers and biomes are distributed on your map. -:all_layers: Change all layers on your map. Candy mountain, anyone? Will make your map quite boring, but tidy. +:all_layers: Change all layers on your map (only for the selected biome unless 'all_biomes' is added). + Candy mountain, anyone? Will make your map quite boring, but tidy. :force: Allow changing stone to soil and vice versa. !!THIS CAN HAVE WEIRD EFFECTS, USE WITH CARE!! Note that soil will not be magically replaced with stone. You will, however, get a stone floor after digging so it will allow the floor to be engraved. Note that stone will not be magically replaced with soil. You will, however, get a soil floor after digging so it could be helpful for creating farm plots on maps with no soil. @@ -121,23 +122,27 @@ Options Examples: --------- -``changelayer GRANITE`` : Convert layer at cursor position into granite. -``changelayer SILTY_CLAY force`` : Convert layer at cursor position into clay even if it's stone. -``changelayer MARBLE all_biomes all_layers`` : Convert all layers of all biomes which are not soil into marble. +``changelayer GRANITE`` + Convert layer at cursor position into granite. +``changelayer SILTY_CLAY force`` + Convert layer at cursor position into clay even if it's stone. +``changelayer MARBLE all_biomes all_layers`` + Convert all layers of all biomes which are not soil into marble. -.. note:: +.. Notes:: - * If you use changelayer and nothing happens, try to pause/unpause the game for a while and try to move the cursor to another tile. + * If you use changelayer and nothing happens, try to pause/unpause the game for a while and try to move the cursor to another tile. Then try again. If that doesn't help try temporarily changing some other layer, undo your changes and try again for the layer you want to change. Saving and reloading your map might also help. * You should be fine if you only change single layers without the use of 'force'. Still it's advisable to save your game before messing with the map. - * When you force changelayer to convert soil to stone you might experience weird stuff (flashing tiles, tiles changed all over the map, ...). Try reverting the changes manually or even better use an older savegame. You did save your game, right? + * When you force changelayer to convert soil to stone you might experience weird stuff (flashing tiles, tiles changed all over place etc). Try reverting the changes manually or even better use an older savegame. You did save your game, right? changevein ========== Changes material of the vein under cursor to the specified inorganic RAW material. Example: ---------- -``changevein NATIVE_PLATINUM`` : Convert vein at cursor position into platinum ore. +-------- +``changevein NATIVE_PLATINUM`` + Convert vein at cursor position into platinum ore. cursecheck ========== @@ -157,14 +162,10 @@ Options Examples: --------- -Check one single map tile if one of the creatures on it is cursed (in-game cursor required): - * cursecheck -Count all active cursed creatures who roam around on your map (no in-game cursor) without giving more details: - * cursecheck -Give detailed info about all cursed creatures including deceased ones (no in-game cursor): - * cursecheck detail all -Give a nickname all living/active cursed creatures on the map(no in-game cursor): - * cursecheck nick +``cursecheck detail all`` + Give detailed info about all cursed creatures including deceased ones (no in-game cursor). +``cursecheck nick`` + Give a nickname all living/active cursed creatures on the map(no in-game cursor). .. note:: diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index b2f700e41..84bdf8239 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -90,6 +90,7 @@ if (BUILD_SUPPORTED) DFHACK_PLUGIN(fixpositions fixpositions.cpp) DFHACK_PLUGIN(follow follow.cpp) DFHACK_PLUGIN(changevein changevein.cpp) + DFHACK_PLUGIN(changelayer changelayer.cpp) DFHACK_PLUGIN(advtools advtools.cpp) DFHACK_PLUGIN(tweak tweak.cpp) DFHACK_PLUGIN(feature feature.cpp) @@ -104,10 +105,3 @@ OPTION(BUILD_SKELETON "Build the skeleton plugin." OFF) if(BUILD_SKELETON) add_subdirectory(skeleton) endif() - -# this is the changelayer plugin. -OPTION(BUILD_CHANGELAYER "Build the changelayer plugin." ON) -if(BUILD_CHANGELAYER) - add_subdirectory(changelayer) -endif() - diff --git a/plugins/changelayer/changelayer.cpp b/plugins/changelayer.cpp similarity index 96% rename from plugins/changelayer/changelayer.cpp rename to plugins/changelayer.cpp index ebe249afe..5f7d5cf0e 100644 --- a/plugins/changelayer/changelayer.cpp +++ b/plugins/changelayer.cpp @@ -71,7 +71,9 @@ const string changelayer_help = const string changelayer_trouble = "Known problems with changelayer:\n\n" " Nothing happens, the material stays the old.\n" - " Try pausing/unpausing the game or moving the cursor a bit.\n\n" + " Pause/unpause the game and/or move the cursor a bit. Then retry.\n" + " Try changing another layer, undo the changes and try again.\n" + " Try saving and loading the game.\n\n" " Weird stuff happening after using the 'force' option.\n" " Change former stone layers back to stone, soil back to soil.\n" " If in doubt, use the 'probe' tool to find tiles with soil walls\n" @@ -221,7 +223,7 @@ command_result changelayer (color_ostream &out, std::vector & para // 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 // Step 1) is optional, but it would make implementing 3) easier. - // Otherwise that "check which geolayer 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 // though it wouldn't matter much since there is not much data to be processed @@ -291,7 +293,7 @@ command_result changelayer (color_ostream &out, std::vector & para vector &geolayers = geo_biome->layers; // complain if layer is out of range - // geology has up to 16 layers currently, but size can be < 15 sometimes! + // geology has up to 16 layers currently, but can have less! if(layer >= geolayers.size() || layer < 0) { if(verbose) @@ -379,7 +381,10 @@ bool conversionAllowed(color_ostream &out, MaterialInfo mat_new, MaterialInfo ma { if(force) { - out << "You've been warned, good luck." << endl; + if(!warned) + { + out << "You've been warned, good luck." << endl; + } allowed = true; } else @@ -389,10 +394,11 @@ bool conversionAllowed(color_ostream &out, MaterialInfo mat_new, MaterialInfo ma out << "Use the option 'force' if you REALLY want to do that." << endl << "Weird things can happen with your map, so save your game before trying!" << endl << "Example: 'changelayer GRANITE force'" << endl; - warned = true; } allowed = false; } + // avoid multiple warnings for the same stuff + warned = true; } return allowed; } \ No newline at end of file diff --git a/plugins/changelayer/CMakeLists.txt b/plugins/changelayer/CMakeLists.txt deleted file mode 100644 index 147f8986b..000000000 --- a/plugins/changelayer/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -PROJECT (changelayer) -# A list of source files -SET(PROJECT_SRCS - changelayer.cpp -) -# A list of headers -SET(PROJECT_HDRS -) -SET_SOURCE_FILES_PROPERTIES( ${PROJECT_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE) - -# mash them together (headers are marked as headers and nothing will try to compile them) -LIST(APPEND PROJECT_SRCS ${PROJECT_HDRS}) - -# option to use a thread for no particular reason -OPTION(CHANGELAYER_THREAD "Use threads in the changelayer plugin." ON) -#linux -IF(UNIX) - add_definitions(-DLINUX_BUILD) - SET(PROJECT_LIBS - # add any extra linux libs here - ${PROJECT_LIBS} - ) -# windows -ELSE(UNIX) - SET(PROJECT_LIBS - # add any extra linux libs here - ${PROJECT_LIBS} - $(NOINHERIT) - ) -ENDIF(UNIX) -# this makes sure all the stuff is put in proper places and linked to dfhack -DFHACK_PLUGIN(changelayer ${PROJECT_SRCS} LINK_LIBRARIES ${PROJECT_LIBS}) From 7c728a1e8180a96429218096cb60be6892170009 Mon Sep 17 00:00:00 2001 From: Robert Heinrich Date: Tue, 27 Mar 2012 18:06:46 +0800 Subject: [PATCH 08/11] minor fix in readme.rst --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index a1f8445ce..1e5f84ca7 100644 --- a/README.rst +++ b/README.rst @@ -435,7 +435,7 @@ When multiple commands are bound to the same key combination, DFHack selects the liquids ======= -Allows adding magma, water and obsidian to the game. It replaces the normal dfhack command line and can't be used from a hotkey. Settings will be remembered as long as dfhack runs. Intended for use in combination with the command liquidsgo-here (which can be bound to a hotkey). +Allows adding magma, water and obsidian to the game. It replaces the normal dfhack command line and can't be used from a hotkey. Settings will be remembered as long as dfhack runs. Intended for use in combination with the command liquids-here (which can be bound to a hotkey). For more information, refer to the command's internal help. .. note:: @@ -445,7 +445,7 @@ For more information, refer to the command's internal help. liquids-here ============ -Run the liquid spawner with the current/last settings made in liquidsgo (if no settings in liquidsgo were made it paints a point of 7/7 magma by default). +Run the liquid spawner with the current/last settings made in liquids (if no settings in liquids were made it paints a point of 7/7 magma by default). Intended to be used as keybinding. Requires an active in-game cursor. mode From 40cf5fe53842d518b2f4f616a3555188e1694896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Wed, 28 Mar 2012 11:46:23 +0200 Subject: [PATCH 09/11] Track structures --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index b41c666c6..8bb7f923b 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit b41c666c6be6fe18906a98dababdc4ff681b8382 +Subproject commit 8bb7f923b1d124610db7e30aeb3be8f4cb9bd021 From 4b2837dc397e363c8e6d65edebd90199232bffa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Wed, 28 Mar 2012 11:56:46 +0200 Subject: [PATCH 10/11] Bump version to 0.34.06-1 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 60b4ab656..83130b303 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,10 +50,10 @@ endif() # set up versioning. set(DF_VERSION_MAJOR "0") set(DF_VERSION_MINOR "34") -set(DF_VERSION_PATCH "05") +set(DF_VERSION_PATCH "06") set(DF_VERSION "${DF_VERSION_MAJOR}.${DF_VERSION_MINOR}.${DF_VERSION_PATCH}") -set(DFHACK_RELEASE "1f") +set(DFHACK_RELEASE "1") set(DFHACK_VERSION "${DF_VERSION_MAJOR}.${DF_VERSION_MINOR}.${DF_VERSION_PATCH}-r${DFHACK_RELEASE}") add_definitions(-DDFHACK_VERSION="${DFHACK_VERSION}") From 06188da380fe80cb7907a30b999075080b93615d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Wed, 28 Mar 2012 12:46:50 +0200 Subject: [PATCH 11/11] Track structures --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index 8bb7f923b..1b1fe798e 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 8bb7f923b1d124610db7e30aeb3be8f4cb9bd021 +Subproject commit 1b1fe798e553cf0ed309606f32b8448bb96b30c8