Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate nestboxes to lua and add to autobutcher #4947

Open
wants to merge 18 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/about/Removed.rst
Original file line number Diff line number Diff line change
Expand Up @@ -371,3 +371,9 @@ workorder-recheck
=================
Tool to set 'Checking' status of the selected work order, allowing conditions
to be reevaluated. Merged into `orders`.

.. _nestboxes:

nestboxes
=================
Migrated to lua and merged into autobutcher plugin
2 changes: 2 additions & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ Template for new versions:
- Quickfort blueprint library: ``aquifer_tap`` blueprint walkthough rewritten for clarity
- Quickfort blueprint library: ``aquifer_tap`` blueprint now designated at priority 3 and marks the stairway tile below the tap in "blueprint" mode to prevent drips while the drainage pipe is being prepared
- `preserve-rooms`: automatically release room reservations for captured squad members. we were kidding ourselves with our optimistic kept reservations. they're unlikely to come back : ((
- `autobutcher`: added nestboxes feature giving more control how fertile eggs should be protected, with possibility to adjust configuration per race

## Documentation

Expand All @@ -77,6 +78,7 @@ Template for new versions:
- ``dfhack.units``: new function ``setPathGoal``

## Removed
- `nestboxes`: merged into `autobutcher`

# 50.14-r1

Expand Down
83 changes: 83 additions & 0 deletions docs/plugins/autobutcher.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@ The default targets are: 2 male kids, 4 female kids, 2 male adults, and
4 female adults. Note that you may need to set a target above 1 to have a
reliable breeding population due to asexuality etc.

Nestboxes module extends autobutcher functionality to monitoring and protection
of fertile eggs. It facilitates steady supplay of eggs protected for breading
purposes while maintaining egg based food production. With default settings it
will forbid fertile eggs in claimed nestboxes up to 4 + number of annimals
missing to autobutcher target. This will allow for larger number of hatchilings
in initial breadin program phase when increasing livestock.
When population reaches intended target only base amount of eggs will be left
for breading purpose.
It is possible to alter this behaviour and compleatly stop protection of eggs
when population target is reached.
In case of clutch larger than needed target eggs will be split in two separate
stacks and only one of them forbidden.
Check for forbidding eggs is made when fertile eggs are laid for one of
watched races.

Usage
-----

Expand Down Expand Up @@ -78,6 +93,50 @@ Usage
``autobutcher list_export``
Print commands required to set the current settings in another fort.

``autobutcher nestboxes enable (autobutcher nb e)``
``autobutcher nestboxes disable (autobutcher nb d)``

It is possible to enable/ disable autobutcher nestboxes module.

``autobutcher nestboxes ignore <true/false> (autobutcher nb i <1/0>)``

By default nestboxes module respects main plugin's enabled status,
autowatch and watched status for specific races.
It is possible to allow nestboxes module to ignore that and work
on it's own. In case like that missing animal count will not be added
to target of protected eggs.

``autobutcher nestboxes target <race> <base_target> <ama> <stop> <watched>``
``autobutcher nb t <race> <base_target> <ama> <stop> <watched>``

Nestboxes target command allows to change how script handles specific
animal race, DEFAULT settings for new races or ALL curently watched races
and default value for new ones.
<race> parameter accepts "DEFAULT", "ALL", creature id (e.g. BIRD_TURKEY)
or race id (190 for Turkey)
<base_target> base number of fertile eggs that will be protected by
frobidding them in nestboxes. Default 4.
<ama> true/false value, if set to true animal count missing to autobutcher
popualtion targets will be added to base target for protected eggs.
Default true.
<stop> if set to true module will stop protection of eggs for race as long
as population target is maintained. Default true.
<watched> If eggs laid by race should be monitored and protected.
Default true.
If parameter is not specified already existing value will be mantained.
If new race is added missing values will be taken from default settings.

``autobutcher nestboxes split_stacks <true/false> (autobutcher nb s <1/0>)``

split_stacks command allows to specify how egg stacks that are only
partialy over target should be handled. If set to false whole stack will
be forbidden. If set to true only eggs below target will be forbidden,
remaining part of stack will be separated and left for dwarves to collect.

``autobutcher nestboxes clear (autobutcher nb clear)``

Remove all settings for module and restore them to initial default values.

To see a list of all races, run this command::

devel/query --table df.global.world.raws.creatures.all --search ^creature_id --maxdepth 1
Expand Down Expand Up @@ -116,3 +175,27 @@ fortress::
autobutcher target 2 2 4 2 ALPACA SHEEP LLAMA
autobutcher target 5 5 6 2 PIG
autobutcher target 0 0 0 0 new


autobutcher nb t BEAK_DOG 10 1 1 1
autobutcher nestboxes target BEAK_DOG 5 true true true

Command sets base target for beak dog eggs to 5, animals missing to population tresholds will be added to base target.
Once autobutcher population target is reached no new eggs will be forbidden as long as population is at or above target.

autobutcher nb t DEFAULT 4 1 0 0
autobutcher nestboxes target DEFAULT 4 true true false

Command will change default settings for watching new races disabling it.

autobutcher nb t ALL 15 0 1 1
autobutcher nestboxes target ALL 15 false true true

Command will change setting for all currently watched egg races as well as default ones.
Target for protected eggs is set to 15, missing animals count to livestock targets is not taken into account.
Once population target is reached eggs will no longer be protected. All current and new races will be watched.

autobutcher nestboxes split_stacks false
autobutcher nb s 0

Disable spliting of egg stacks.
18 changes: 0 additions & 18 deletions docs/plugins/nestboxes.rst

This file was deleted.

22 changes: 22 additions & 0 deletions library/LuaApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4169,6 +4169,27 @@ static int internal_getClipboardTextCp437Multiline(lua_State *L) {
return 1;
}

static int internal_get_persistent_data_int(lua_State* L, get_data_fn get_data) {
CoreSuspender suspend;

PersistentDataItem data = get_data(L);

if (!data.isValid() || !lua_isnumber(L, 2)){
lua_pushnil(L);
}
else {
const int idx = lua_tointeger(L, 2);
lua_pushinteger(L, data.get_int(idx));
}

return 1;
}

static int internal_readPersistentSiteDataInt(lua_State* L) {
return internal_get_persistent_data_int(L, get_site_data);
}


static const luaL_Reg dfhack_internal_funcs[] = {
{ "getPE", internal_getPE },
{ "getMD5", internal_getmd5 },
Expand Down Expand Up @@ -4204,6 +4225,7 @@ static const luaL_Reg dfhack_internal_funcs[] = {
{ "getPerfCounters", internal_getPerfCounters },
{ "getPreferredNumberFormat", internal_getPreferredNumberFormat },
{ "getClipboardTextCp437Multiline", internal_getClipboardTextCp437Multiline },
{ "readPersistentSiteConfigInt", internal_readPersistentSiteDataInt },
{ NULL, NULL }
};

Expand Down
1 change: 0 additions & 1 deletion plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ if(BUILD_SUPPORTED)
#dfhack_plugin(map-render map-render.cpp LINK_LIBRARIES lua)
dfhack_plugin(misery misery.cpp LINK_LIBRARIES lua)
#dfhack_plugin(mode mode.cpp)
dfhack_plugin(nestboxes nestboxes.cpp)
dfhack_plugin(orders orders.cpp LINK_LIBRARIES jsoncpp_static lua)
dfhack_plugin(overlay overlay.cpp LINK_LIBRARIES lua)
dfhack_plugin(pathable pathable.cpp LINK_LIBRARIES lua)
Expand Down
37 changes: 37 additions & 0 deletions plugins/autobutcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,42 @@ static int autobutcher_getWatchList(lua_State *L) {
return 1;
}

static int getMax(int first, int second) {
return first > second ? first : second;
}
// push info used by nestboxes
static int autobutcher_getInfoForNestboxes(lua_State* L) {
PersistentDataItem rconfig;
color_ostream* out = Lua::GetOutput(L);

if (lua_isnumber(L, 1)) {
int raceId = lua_tointeger(L, 1);
lua_newtable(L);
int ctable = lua_gettop(L);
Lua::SetField(L, config.get_bool(CONFIG_IS_ENABLED), ctable, "enabled");

if (!out)
out = &Core::getInstance().getConsole();

WatchedRace* w;
if (watched_races.count(raceId)) {
w = watched_races[raceId];
WatchedRace* tally = checkRaceStocksTotal(*out, raceId);
Lua::SetField(L, w->isWatched, ctable, "watched");
// missing animals count for race,
// diff between target for child/adult female/male and current amounts,
// ignore amounts over target
int mac = getMax(w->fk - tally->fk_units.size(), 0);
mac += getMax(w->mk - tally->mk_units.size(), 0);
mac += getMax(w->fa - tally->fa_units.size(), 0);
mac += getMax(w->ma - tally->ma_units.size(), 0);
Lua::SetField(L, mac, ctable, "mac");
delete tally;
}
}
return 1;
}

DFHACK_PLUGIN_LUA_FUNCTIONS {
DFHACK_LUA_FUNCTION(autowatch_isEnabled),
DFHACK_LUA_FUNCTION(autowatch_setEnabled),
Expand All @@ -986,5 +1022,6 @@ DFHACK_PLUGIN_LUA_FUNCTIONS {
DFHACK_PLUGIN_LUA_COMMANDS {
DFHACK_LUA_COMMAND(autobutcher_getSettings),
DFHACK_LUA_COMMAND(autobutcher_getWatchList),
DFHACK_LUA_COMMAND(autobutcher_getInfoForNestboxes),
DFHACK_LUA_END
};
12 changes: 12 additions & 0 deletions plugins/lua/autobutcher.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local _ENV = mkmodule('plugins.autobutcher')

local argparse = require('argparse')
local nestboxes = require('plugins.autobutcher.nestboxes')

local function is_int(val)
return val and val == math.floor(val)
Expand Down Expand Up @@ -45,6 +46,13 @@ local function process_races(opts, races, start_idx)
end
end

local function reload_modules()
reload('plugins.autobutcher.common')
reload('plugins.autobutcher.nestboxesEvent')
reload('plugins.autobutcher.nestboxes')
reload('plugins.autobutcher')
end

function parse_commandline(opts, args)
local positionals = process_args(opts, args)

Expand All @@ -65,6 +73,10 @@ function parse_commandline(opts, args)
opts.fa = check_nonnegative_int(positionals[4])
opts.ma = check_nonnegative_int(positionals[5])
process_races(opts, positionals, 6)
elseif command == 'reload' then
reload_modules()
elseif string.upper(command) == 'NESTBOXES' or string.upper(command) =='NB' then
nestboxes.handleCommand(positionals, opts)
else
qerror(('unrecognized command: "%s"'):format(command))
end
Expand Down
34 changes: 34 additions & 0 deletions plugins/lua/autobutcher/common.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
local _ENV = mkmodule('plugins.autobutcher.common')

verbose = verbose or nil
prefix = prefix or ''

function printLocal(text)
print(prefix .. ': ' .. text)
end

function handleError(text)
qerror(prefix .. ': ' .. text)
end

function printDetails(text)
if verbose then
printLocal(text)
end
end

function dumpToString(o)
if type(o) == 'table' then
local s = '{ '
for k, v in pairs(o) do
if type(k) ~= 'number' then
k = '"' .. k .. '"'
end
s = s .. '[' .. k .. '] = ' .. dumpToString(v) .. ','
end
return s .. '} '
else
return tostring(o)
end
end
return _ENV
Loading