Skip to content

Commit

Permalink
add description to autobutcher.rst, take autobutcher setting into acc…
Browse files Browse the repository at this point in the history
…ount when checking and adding config for new race
  • Loading branch information
Birkow committed Sep 18, 2024
1 parent 184798f commit de77231
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 74 deletions.
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.
2 changes: 1 addition & 1 deletion plugins/autobutcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -983,7 +983,7 @@ static int autobutcher_getInfoForNestboxes(lua_State* L) {
int raceId = lua_tointeger(L, 1);
lua_newtable(L);
int ctable = lua_gettop(L);
Lua::SetField(L, config.get_bool(CONFIG_IS_ENABLED), ctable, "autobutcher_enabled");
Lua::SetField(L, config.get_bool(CONFIG_IS_ENABLED), ctable, "enabled");

if (!out)
out = &Core::getInstance().getConsole();
Expand Down
73 changes: 31 additions & 42 deletions plugins/lua/autobutcher/nestboxes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ local default_table = {
watched = true, -- monitor eggs for race
target = 4, --basic target for protected(forbidden) eggs
ama = true, --Add Missing Animals to basic target for prottected eggs, difference between current amount of animals and target set for autobutcher, speeds up population growth in initial phase whiile limitting population explosion near end if egg target has low value
full_stop = false -- stop protecting eggs once autobutcher target for live animals is reached
stop = true -- stop protecting eggs once autobutcher target for live animals is reached
}
---------------------------------------------------------------------------------------------------
local function getDefaultState()
Expand Down Expand Up @@ -140,14 +140,14 @@ local function doDisable()
printDetails(('end doDisable'))
end --doDisable
---------------------------------------------------------------------------------------------------
local function getConfigForRace(race)
local function getConfigForRace(race , autobutcher_watched)
printDetails(('start getConfigForRace'))
printDetails(('getting config for race %s '):format(race))
if state.config_per_race[race] == nil then
if state.config_per_race[race] == nil and autobutcher_watched and state.default.watched then
state.config_per_race[race] = state.default
persistState()
end
printDetails(('end 2 getConfigForRace'))
printDetails(('end getConfigForRace'))
return state.config_per_race[race]
end --getConfigForRace
---------------------------------------------------------------------------------------------------
Expand All @@ -169,7 +169,7 @@ local function validateCreatureOrRace(value)
handleError(('could not find %s'):format(value))
end --validateCreatureOrRace
---------------------------------------------------------------------------------------------------
local function setTarget(target_race, target_count, add_missing_animals, full_stop, watch_race)
local function setTarget(target_race, target_count, add_missing_animals, stop, watch_race)
printDetails(('start setTarget'))

if type(target_race) == 'string' then
Expand All @@ -184,7 +184,7 @@ local function setTarget(target_race, target_count, add_missing_animals, full_st
watched = getBoolean(watch_race),
target = tonumber(target_count),
ama = getBoolean(add_missing_animals),
full_stop = getBoolean(full_stop)
stop = getBoolean(stop)
}

local race = validateCreatureOrRace(target_race)
Expand All @@ -193,6 +193,7 @@ local function setTarget(target_race, target_count, add_missing_animals, full_st
elseif race == 'ALL' then
for _, v in pairs(state.config_per_race) do
utils.assign(v, new_config)
utils.assign(state.default, new_config)
end
elseif race >= 0 then
utils.assign(state.config_per_race[race], new_config)
Expand All @@ -211,26 +212,30 @@ local function clearConfig()
updateEventListener()
end
---------------------------------------------------------------------------------------------------
local function setIgnore(value)
state.ignore_autobutcher = getBoolean(value)
end
---------------------------------------------------------------------------------------------------
local function setVerbose(value)
state.verbose = getBoolean(value)
nestboxesCommon.verbose = state.verbose
end
---------------------------------------------------------------------------------------------------
local function format_target_count_row(category, row)
return (('%s: watched %s; target %s; add missing animals %s; full stop once animal target reached %s'):format(
return (('%s: watched: %s; target: %s; ama: %s; stop: %s'):format(
category,
row.watched and 'enabled' or 'disabled',
tostring(row.target),
row.ama and 'enabled' or 'disabled',
row.full_stop and 'enabled' or 'disabled'
row.stop and 'enabled' or 'disabled'
))
end
---------------------------------------------------------------------------------------------------
local function printStatus()
printLocal(('Script is currently %s.'):format(state.enabled and 'enabled' or 'disabled'))
printLocal(('Egg stack splitting is %s'):format(state.split_stacks and 'enabled' or 'disabled'))
printLocal(('Status %s.'):format(state.enabled and 'enabled' or 'disabled'))
printLocal(('Stack splitting: %s'):format(state.split_stacks and 'enabled' or 'disabled'))
printLocal(
('Script is %s autobutcher\'s enabled status'):format(state.ignore_autobutcher and 'ignoring' or 'respecting')
('%s autobutcher\'s enabled status'):format(state.ignore_autobutcher and 'Ignoring' or 'Tespecting')
)
printDetails(('verbose mode is %s'):format(state.verbose and 'enabled' or 'disabled'))
printDetails(
Expand All @@ -242,7 +247,7 @@ local function printStatus()
printLocal(format_target_count_row(df.global.world.raws.creatures.all[k].creature_id, v))
end
end
printDetails(dumpToString(state))
--printDetails(dumpToString(state))
end
---------------------------------------------------------------------------------------------------
local function handleOnStateChange(sc)
Expand All @@ -260,7 +265,7 @@ end --handleOnStateChange
---------------------------------------------------------------------------------------------------
local function getInfoFromAutobutcher(race)
local v_return = {
autobutcher_enabled = false,
enabled = false,
watched = false,
mac = 0
}
Expand All @@ -279,29 +284,6 @@ local function getInfoFromAutobutcher(race)
return v_return
end --getInfoFromAutobutcher
---------------------------------------------------------------------------------------------------
local function validateEggs(eggs)
if not eggs.egg_flags.fertile then
printDetails('Newly laid eggs are not fertile, do nothing')
return false
end

local should_be_nestbox = dfhack.items.getHolderBuilding(eggs)
if should_be_nestbox ~= nil then
for _, nestbox in ipairs(df.global.world.buildings.other.NEST_BOX) do
if nestbox == should_be_nestbox then
printDetails('Found nestbox, continue with egg handling')
return true
end
end
printDetails('Newly laid eggs are in building different than nestbox, we were to late')
return false
else
printDetails('Newly laid eggs are not in building, we were to late')
return false
end
return true
end --validateEggs
---------------------------------------------------------------------------------------------------
--<Global functions>
---------------------------------------------------------------------------------------------------
-- checkItemCreated function, called from eventfful on ITEM_CREATED event
Expand All @@ -310,16 +292,21 @@ function checkItemCreated(item_id)
if item == nil or df.item_type.EGG ~= item:getType() then
return
else
if validateEggs(item) then
if nestboxesEvent.validateEggs(item) then
local autobutcher_info = getInfoFromAutobutcher(item.race)
local race_config = getConfigForRace(item.race)

local race_config = getConfigForRace(item.race, (autobutcher_info.watched and autobutcher_info.enabled) or state.ignore_autobutcher)
if race_config == nil then -- if nil new race without config and no new races are being watched
return
end
if
(((autobutcher_info.watched and autobutcher_info.autobutcher_enabled and not state.ignore_autobutcher -- check eggs respecting autobutcher settings
and not (race_config.full_stop and autobutcher_info.mac == 0)) -- do not check eggs if reached animal targets for race and full stop enabled
(((autobutcher_info.watched and autobutcher_info.enabled and not state.ignore_autobutcher -- check eggs respecting autobutcher settings
and not (race_config.stop and autobutcher_info.mac == 0)) -- do not check eggs if reached animal targets for race and full stop enabled
or state.ignore_autobutcher) -- or check eggs ignoring autobutcher settings
and race_config.watched)-- check eggs only when nestboxes is watching race
and race_config.watched -- check eggs only when nestboxes is watching race
)
then
nestboxesEvent.handleEggs(item, race_config, state.split_stacks, autobutcher_info.mac)
nestboxesEvent.handleEggs(item, race_config.target, race_config.ama, state.split_stacks, autobutcher_info.mac)
end
end
end
Expand All @@ -345,6 +332,8 @@ function handleCommand(positionals, opts)
updateEventListener()
elseif command == 'TARGET' or command == 'T' then
setTarget(positionals[3], positionals[4], positionals[5], positionals[6], positionals[7])
elseif command == 'IGNORE' or command == 'I' then
setIgnore(positionals[3])
elseif command == 'VERBOSE' or command == 'V' then
setVerbose(positionals[3])
elseif command == 'SPLIT_STACKS' or command == 'S' then
Expand Down
Loading

0 comments on commit de77231

Please sign in to comment.