Merge branch 'develop' into automelt-autochop-lua-stack-fix

develop
Eamon Bode 2023-02-08 15:45:29 -05:00 committed by GitHub
commit 07fd4b25b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 85 additions and 97 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 997 B

@ -1138,42 +1138,6 @@
"job" : "MakeWeapon", "job" : "MakeWeapon",
"material" : "INORGANIC:SILVER" "material" : "INORGANIC:SILVER"
}, },
{
"amount_left" : 1,
"amount_total" : 1,
"frequency" : "Daily",
"id" : 64,
"is_active" : false,
"is_validated" : false,
"item_conditions" :
[
{
"condition" : "AtLeast",
"item_type" : "BAR",
"material" : "INORGANIC:SILVER",
"value" : 20
},
{
"condition" : "AtLeast",
"item_type" : "BAR",
"material" : "COAL",
"value" : 100
},
{
"condition" : "AtMost",
"flags" :
[
"metal"
],
"item_subtype" : "ITEM_WEAPON_CROSSBOW",
"item_type" : "WEAPON",
"value" : 10
}
],
"item_subtype" : "ITEM_WEAPON_CROSSBOW",
"job" : "MakeWeapon",
"material" : "INORGANIC:SILVER"
},
{ {
"amount_left" : 1, "amount_left" : 1,
"amount_total" : 1, "amount_total" : 1,
@ -1656,12 +1620,6 @@
"item_type" : "WEAPON", "item_type" : "WEAPON",
"material" : "INORGANIC:STEEL", "material" : "INORGANIC:STEEL",
"value" : 10 "value" : 10
},
{
"condition" : "LessThan",
"item_type" : "BAR",
"material" : "INORGANIC:SILVER",
"value" : 5
} }
], ],
"item_subtype" : "ITEM_WEAPON_CROSSBOW", "item_subtype" : "ITEM_WEAPON_CROSSBOW",
@ -2357,12 +2315,6 @@
"material" : "INORGANIC:STEEL", "material" : "INORGANIC:STEEL",
"value" : 30 "value" : 30
}, },
{
"condition" : "LessThan",
"item_type" : "BAR",
"material" : "INORGANIC:SILVER",
"value" : 5
},
{ {
"condition" : "AtMost", "condition" : "AtMost",
"flags" : "flags" :
@ -3068,12 +3020,6 @@
"material" : "INORGANIC:STEEL", "material" : "INORGANIC:STEEL",
"value" : 30 "value" : 30
}, },
{
"condition" : "LessThan",
"item_type" : "BAR",
"material" : "INORGANIC:SILVER",
"value" : 5
},
{ {
"condition" : "AtMost", "condition" : "AtMost",
"flags" : "flags" :
@ -3856,12 +3802,6 @@
"material" : "INORGANIC:STEEL", "material" : "INORGANIC:STEEL",
"value" : 30 "value" : 30
}, },
{
"condition" : "LessThan",
"item_type" : "BAR",
"material" : "INORGANIC:SILVER",
"value" : 5
},
{ {
"condition" : "AtMost", "condition" : "AtMost",
"flags" : "flags" :
@ -4734,12 +4674,6 @@
"material" : "INORGANIC:STEEL", "material" : "INORGANIC:STEEL",
"value" : 30 "value" : 30
}, },
{
"condition" : "LessThan",
"item_type" : "BAR",
"material" : "INORGANIC:SILVER",
"value" : 5
},
{ {
"condition" : "AtMost", "condition" : "AtMost",
"flags" : "flags" :

@ -39,6 +39,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
- ``Units::isFortControlled``: Account for agitated wildlife - ``Units::isFortControlled``: Account for agitated wildlife
- Fix right click sometimes closing both a DFHack window and a vanilla panel - Fix right click sometimes closing both a DFHack window and a vanilla panel
- Fixed issue with scrollable lists having some data off-screen if they were scrolled before being made visible - Fixed issue with scrollable lists having some data off-screen if they were scrolled before being made visible
- `channel-safely`: fixed bug resulting in marker mode never being set for any designation
## Misc Improvements ## Misc Improvements
- `automelt`: is now more resistent to savegame corruption - `automelt`: is now more resistent to savegame corruption
@ -49,6 +50,8 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
- `clean`: new hotkey for `spotclean`: Ctrl-C - `clean`: new hotkey for `spotclean`: Ctrl-C
- `autobutcher`: changed defaults from 5 females / 1 male to 4 females / 2 males so a single unfortunate accident doesn't leave players without a mating pair - `autobutcher`: changed defaults from 5 females / 1 male to 4 females / 2 males so a single unfortunate accident doesn't leave players without a mating pair
- `autobutcher`: now immediately loads races available at game start into the watchlist - `autobutcher`: now immediately loads races available at game start into the watchlist
- replaced DFHack logo used for the hover hotspot with a crisper image
- `orders`: recipe for silver crossbows removed from ``library/military`` as it is not a vanilla recipe, but is available in ``library/military_include_artifact_materials``
## Documentation ## Documentation
@ -57,6 +60,9 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
## Lua ## Lua
- `overlay`: overlay widgets can now specify focus paths for the viewscreens they attach to so they only appear in specific contexts. see `overlay-dev-guide` for details. - `overlay`: overlay widgets can now specify focus paths for the viewscreens they attach to so they only appear in specific contexts. see `overlay-dev-guide` for details.
- ``widgets.CycleHotkeyLabel``: Added ``key_back`` optional parameter to cycle backwards. - ``widgets.CycleHotkeyLabel``: Added ``key_back`` optional parameter to cycle backwards.
- ``widgets.HotkeyLabel``: Added ``setLabel`` method to allow easily updating the label text without mangling the keyboard shortcut.
- ``widgets.HotkeyLabel``: Added ``setOnActivate`` method to allow easily updating the ``on_activate`` callback.
- ``widgets.FilteredList``: Added ``case_sensitive`` optional paramter to determine if filtering is case sensitive.
## Removed ## Removed

@ -4808,6 +4808,16 @@ It has the following attributes:
:on_activate: If specified, it is the callback that will be called whenever :on_activate: If specified, it is the callback that will be called whenever
the hotkey is pressed or the label is clicked. the hotkey is pressed or the label is clicked.
The HotkeyLabel widget implements the following methods:
* ``hotkeylabel:setLabel(label)``
Updates the label without altering the hotkey text.
* ``hotkeylabel:setOnActivate(on_activate)``
Updates the on_activate callback.
CycleHotkeyLabel class CycleHotkeyLabel class
---------------------- ----------------------
@ -4958,6 +4968,7 @@ construction that allows filtering the list by subwords of its items.
In addition to passing through all attributes supported by List, it In addition to passing through all attributes supported by List, it
supports: supports:
:case_sensitive: If true, matching is case sensitive. Defaults to true.
:edit_pen: If specified, used instead of ``cursor_pen`` for the edit field. :edit_pen: If specified, used instead of ``cursor_pen`` for the edit field.
:edit_below: If true, the edit field is placed below the list instead of above. :edit_below: If true, the edit field is placed below the list instead of above.
:edit_key: If specified, the edit field is disabled until this key is pressed. :edit_key: If specified, the edit field is disabled until this key is pressed.

@ -478,7 +478,7 @@ static void OpenPersistent(lua_State *state)
static int DFHACK_MATINFO_TOKEN = 0; static int DFHACK_MATINFO_TOKEN = 0;
void Lua::Push(lua_State *state, MaterialInfo &info) void Lua::Push(lua_State *state, const MaterialInfo &info)
{ {
if (!info.isValid()) if (!info.isValid())
{ {

@ -101,7 +101,7 @@ void DFHack::Lua::Push(lua_State *state, const Units::NoblePosition &pos)
lua_setfield(state, -2, "position"); lua_setfield(state, -2, "position");
} }
void DFHack::Lua::Push(lua_State *state, df::coord pos) void DFHack::Lua::Push(lua_State *state, const df::coord &pos)
{ {
lua_createtable(state, 0, 3); lua_createtable(state, 0, 3);
lua_pushinteger(state, pos.x); lua_pushinteger(state, pos.x);
@ -112,7 +112,7 @@ void DFHack::Lua::Push(lua_State *state, df::coord pos)
lua_setfield(state, -2, "z"); lua_setfield(state, -2, "z");
} }
void DFHack::Lua::Push(lua_State *state, df::coord2d pos) void DFHack::Lua::Push(lua_State *state, const df::coord2d &pos)
{ {
lua_createtable(state, 0, 2); lua_createtable(state, 0, 2);
lua_pushinteger(state, pos.x); lua_pushinteger(state, pos.x);
@ -191,7 +191,7 @@ void DFHack::Lua::PushInterfaceKeys(lua_State *L,
} }
} }
int DFHack::Lua::PushPosXYZ(lua_State *state, df::coord pos) int DFHack::Lua::PushPosXYZ(lua_State *state, const df::coord &pos)
{ {
if (!pos.isValid()) if (!pos.isValid())
{ {
@ -207,7 +207,7 @@ int DFHack::Lua::PushPosXYZ(lua_State *state, df::coord pos)
} }
} }
int DFHack::Lua::PushPosXY(lua_State *state, df::coord2d pos) int DFHack::Lua::PushPosXY(lua_State *state, const df::coord2d &pos)
{ {
if (!pos.isValid()) if (!pos.isValid())
{ {

@ -325,10 +325,10 @@ namespace DFHack {namespace Lua {
inline void Push(lua_State *state, const std::string &str) { inline void Push(lua_State *state, const std::string &str) {
lua_pushlstring(state, str.data(), str.size()); lua_pushlstring(state, str.data(), str.size());
} }
DFHACK_EXPORT void Push(lua_State *state, df::coord obj); DFHACK_EXPORT void Push(lua_State *state, const df::coord &obj);
DFHACK_EXPORT void Push(lua_State *state, df::coord2d obj); DFHACK_EXPORT void Push(lua_State *state, const df::coord2d &obj);
void Push(lua_State *state, const Units::NoblePosition &pos); void Push(lua_State *state, const Units::NoblePosition &pos);
DFHACK_EXPORT void Push(lua_State *state, MaterialInfo &info); DFHACK_EXPORT void Push(lua_State *state, const MaterialInfo &info);
DFHACK_EXPORT void Push(lua_State *state, const Screen::Pen &info); DFHACK_EXPORT void Push(lua_State *state, const Screen::Pen &info);
template<class T> inline void Push(lua_State *state, T *ptr) { template<class T> inline void Push(lua_State *state, T *ptr) {
PushDFObject(state, ptr); PushDFObject(state, ptr);
@ -361,29 +361,34 @@ namespace DFHack {namespace Lua {
DFHACK_EXPORT void GetVector(lua_State *state, std::vector<std::string> &pvec); DFHACK_EXPORT void GetVector(lua_State *state, std::vector<std::string> &pvec);
DFHACK_EXPORT int PushPosXYZ(lua_State *state, df::coord pos); DFHACK_EXPORT int PushPosXYZ(lua_State *state, const df::coord &pos);
DFHACK_EXPORT int PushPosXY(lua_State *state, df::coord2d pos); DFHACK_EXPORT int PushPosXY(lua_State *state, const df::coord2d &pos);
template <typename T_Key, typename T_Value>
inline void TableInsert(lua_State *state, T_Key key, T_Value value)
{
Lua::Push(state, key);
Lua::Push(state, value);
lua_settable(state, -3);
}
template<typename T_Key, typename T_Value> template<typename T_Key, typename T_Value>
void Push(lua_State *L, const std::map<T_Key, T_Value> &pmap) { void Push(lua_State *L, const std::map<T_Key, T_Value> &pmap) {
lua_createtable(L, 0, pmap.size()); lua_createtable(L, 0, pmap.size());
for (auto &entry : pmap) for (auto &entry : pmap) {
TableInsert(L, entry.first, entry.second); Lua::Push(L, entry.first);
Lua::Push(L, entry.second);
lua_settable(L, -3);
}
} }
template<typename T_Key, typename T_Value> template<typename T_Key, typename T_Value>
void Push(lua_State *L, const std::unordered_map<T_Key, T_Value> &pmap) { void Push(lua_State *L, const std::unordered_map<T_Key, T_Value> &pmap) {
lua_createtable(L, 0, pmap.size()); lua_createtable(L, 0, pmap.size());
for (auto &entry : pmap) for (auto &entry : pmap) {
TableInsert(L, entry.first, entry.second); Lua::Push(L, entry.first);
Lua::Push(L, entry.second);
lua_settable(L, -3);
}
}
template <typename T_Key, typename T_Value>
inline void TableInsert(lua_State *state, const T_Key &key, const T_Value &value) {
Lua::Push(state, key);
Lua::Push(state, value);
lua_settable(state, -3);
} }
DFHACK_EXPORT void CheckPen(lua_State *L, Screen::Pen *pen, int index, bool allow_nil = false, bool allow_color = true); DFHACK_EXPORT void CheckPen(lua_State *L, Screen::Pen *pen, int index, bool allow_nil = false, bool allow_color = true);

@ -1419,6 +1419,20 @@ HotkeyLabel.ATTRS{
} }
function HotkeyLabel:init() function HotkeyLabel:init()
self:initializeLabel()
end
function HotkeyLabel:setOnActivate(on_activate)
self.on_activate = on_activate
self:initializeLabel()
end
function HotkeyLabel:setLabel(label)
self.label = label
self:initializeLabel()
end
function HotkeyLabel:initializeLabel()
self:setText{{key=self.key, key_sep=self.key_sep, text=self.label, self:setText{{key=self.key, key_sep=self.key_sep, text=self.label,
on_activate=self.on_activate}} on_activate=self.on_activate}}
end end
@ -1868,6 +1882,7 @@ end
FilteredList = defclass(FilteredList, Widget) FilteredList = defclass(FilteredList, Widget)
FilteredList.ATTRS { FilteredList.ATTRS {
case_sensitive = true,
edit_below = false, edit_below = false,
edit_key = DEFAULT_NIL, edit_key = DEFAULT_NIL,
edit_ignore_keys = DEFAULT_NIL, edit_ignore_keys = DEFAULT_NIL,
@ -2028,11 +2043,17 @@ function FilteredList:setFilter(filter, pos)
-- start matches at non-space or non-punctuation. this allows -- start matches at non-space or non-punctuation. this allows
-- punctuation itself to be matched if that is useful (e.g. -- punctuation itself to be matched if that is useful (e.g.
-- filenames or parameter names) -- filenames or parameter names)
if key ~= '' and if key ~= '' then
not search_key:match('%f[^%p\x00]'..key) and if not self.case_sensitive then
search_key = string.lower(search_key)
key = string.lower(key)
end
if not search_key:match('%f[^%p\x00]'..key) and
not search_key:match('%f[^%s\x00]'..key) then not search_key:match('%f[^%s\x00]'..key) then
ok = false ok = false
break break
end
end end
end end
if ok then if ok then

@ -5,7 +5,17 @@
#include <modules/EventManager.h> //hash function for df::coord #include <modules/EventManager.h> //hash function for df::coord
#include <df/block_square_event_designation_priorityst.h> #include <df/block_square_event_designation_priorityst.h>
#define NUMARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value
#define d_assert(condition, ...) \
static_assert(NUMARGS(__VA_ARGS__) >= 1, "d_assert(condition, format, ...) requires at least up to format as arguments"); \
if (!condition) { \
DFHack::Core::getInstance().getConsole().printerr(__VA_ARGS__); \
assert(0); \
}
df::unit* find_dwarf(const df::coord &map_pos) { df::unit* find_dwarf(const df::coord &map_pos) {
df::unit* nearest = nullptr; df::unit* nearest = nullptr;
uint32_t distance; uint32_t distance;
for (auto unit : df::global::world->units.active) { for (auto unit : df::global::world->units.active) {
@ -57,6 +67,7 @@ void ChannelManager::manage_group(const Group &group, bool set_marker_mode, bool
// cavein prevention // cavein prevention
bool cavein_possible = false; bool cavein_possible = false;
uint8_t least_access = 100; uint8_t least_access = 100;
std::unordered_map<df::coord, uint8_t> cavein_candidates; std::unordered_map<df::coord, uint8_t> cavein_candidates;
if (!marker_mode) { if (!marker_mode) {
/* To prevent cave-ins we're looking at accessibility of tiles with open space below them /* To prevent cave-ins we're looking at accessibility of tiles with open space below them
@ -111,7 +122,7 @@ void ChannelManager::manage_group(const Group &group, bool set_marker_mode, bool
// if no cave-in is possible [or we don't check for], we'll just execute normally and move on // if no cave-in is possible [or we don't check for], we'll just execute normally and move on
if (!cavein_possible) { if (!cavein_possible) {
TRACE(manager).print("cave-in evaluated false\n"); TRACE(manager).print("cave-in evaluated false\n");
assert(manage_one(pos, true, marker_mode)); d_assert(manage_one(pos, true, marker_mode), "manage_one() is failing under !cavein");
continue; continue;
} }
// cavein is only possible if marker_mode is false // cavein is only possible if marker_mode is false
@ -136,16 +147,16 @@ void ChannelManager::manage_group(const Group &group, bool set_marker_mode, bool
evT->priority[Coord(local)] = v; evT->priority[Coord(local)] = v;
} }
} }
assert(manage_one(pos, true, false)); d_assert(manage_one(pos, true, false), "manage_one() is failing for cavein ");
continue; continue;
} }
// cavein possible, but we failed to meet the criteria for activation // cavein possible, but we failed to meet the criteria for activation
if (cavein_candidates.count(pos)) { if (cavein_candidates.count(pos)) {
DEBUG(manager).print("cave-in evaluated true and no dignow and (%d > %d)\n", cavein_candidates[pos], least_access+OFFSET); DEBUG(manager).print("cave-in evaluated true and the cavein candidate's accessibility check was made as (%d <= %d)\n", cavein_candidates[pos], least_access+OFFSET);
} else { } else {
DEBUG(manager).print("cave-in evaluated true and no dignow and pos is not a candidate\n"); DEBUG(manager).print("cave-in evaluated true and the position was not a candidate, nor was it set for dignow\n");
} }
assert(manage_one(pos, true, true)); d_assert(manage_one(pos, true, true), "manage_one() is failing to set a cave-in causing designation to marker mode");
} }
INFO(manager).print("manage_group() is done\n"); INFO(manager).print("manage_group() is done\n");
} }