Merge pull request #2757 from ab9rf/5005-autolabor

reenable autolabor
develop
Myk 2023-02-02 17:15:20 -08:00 committed by GitHub
commit b514d9b7f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 109 additions and 20 deletions

@ -18,8 +18,31 @@ untouched by autolabor.
.. warning::
autolabor will override any manual changes you make to labors while it is
enabled, including through other tools such as Dwarf Therapist.
**This plugin is still being tested. Use at your own risk.**
The algorithms that autolabor uses to choose labor assignments have *not* been updated for version 50 of
Dwarf Fortress. There is no particular guarantee that the labor assignments autolabor is making are optimal,
and it is entirely possible that the assignments it makes will lead to unforeseen consequences. You should
monitor what your dwarves are doing, and more importantly not doing, when using autolabor.
At this time there is no way to easily see what labors are being assigned to whom, as there is no longer
any vanilla means for seeing the labor assignment table. Until `manipulator` is once again available,
probably the best way to see what autolabor is doing is to use
`Dwarf Therapist <https://github.com/Dwarf-Therapist/Dwarf-Therapist>`_. You can also increase autolabor's
logging level using the `debugfilter<debug>` command (setting either ``debug`` or ``trace`` level for the
``cycle`` mode) but be warned that this may generate a large amount of console spam, especially in a large fort.
When it is enabled, autolabor automatically disables the work detail system. You cannot
use autolabor and work details at the same time. If you attempt to open the work detail screen while
autolabor is active, a warning box should appear advising you that autolabor is managing labors and preventing
you from making any changes on that screen.
Finally, should you disable autolabor, autolabor will automatically reenable the vanilla work detail system.
However, the work detail system only updates labors when the work detail screen is open and some change is
made on that screen. Therefore, if you choose to disable autolabor, you should probably immediately
thereafter open the work details screen and make some change to force the game to recompute all labor
assignments based on the vanilla algorithm. At this time, it is not possible for autolabor to do this
automatically.
Usage
-----

@ -81,7 +81,7 @@ dfhack_plugin(autoclothing autoclothing.cpp)
dfhack_plugin(autodump autodump.cpp)
dfhack_plugin(autofarm autofarm.cpp)
#dfhack_plugin(autogems autogems.cpp LINK_LIBRARIES jsoncpp_static)
#add_subdirectory(autolabor)
add_subdirectory(autolabor)
#dfhack_plugin(automaterial automaterial.cpp LINK_LIBRARIES lua)
dfhack_plugin(automelt automelt.cpp LINK_LIBRARIES lua)
#dfhack_plugin(autonestbox autonestbox.cpp LINK_LIBRARIES lua)

@ -10,6 +10,6 @@ set_source_files_properties(${COMMON_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE)
# mash them together (headers are marked as headers and nothing will try to compile them)
list(APPEND COMMON_SRCS ${COMMON_HDRS})
dfhack_plugin(labormanager labormanager.cpp joblabormapper.cpp ${COMMON_SRCS})
#dfhack_plugin(labormanager labormanager.cpp joblabormapper.cpp ${COMMON_SRCS})
dfhack_plugin(autolabor autolabor.cpp ${COMMON_SRCS})
dfhack_plugin(autolabor autolabor.cpp ${COMMON_SRCS} LINK_LIBRARIES lua)

@ -34,6 +34,8 @@
#include <df/items_other_id.h>
#include <df/plotinfost.h>
#include <df/activity_info.h>
#include <df/global_objects.h>
#include <df/gamest.h>
#include <MiscUtils.h>
@ -49,6 +51,7 @@ using namespace df::enums;
DFHACK_PLUGIN("autolabor");
REQUIRE_GLOBAL(plotinfo);
REQUIRE_GLOBAL(world);
REQUIRE_GLOBAL(game);
#define ARRAY_COUNT(array) (sizeof(array)/sizeof((array)[0]))
@ -172,9 +175,9 @@ static const struct labor_default default_labor_infos[] = {
/* CLEAN */ {HAULERS, false, 1, 200, 0},
/* CUTWOOD */ {AUTOMATIC, true, 1, 200, 0},
/* CARPENTER */ {AUTOMATIC, false, 1, 200, 0},
/* DETAIL */ {AUTOMATIC, false, 1, 200, 0},
/* STONECUTTER */ {AUTOMATIC, false, 1, 200, 0},
/* STONE_CARVER */ {AUTOMATIC, false, 1, 200, 0},
/* MASON */ {AUTOMATIC, false, 1, 200, 0},
/* ARCHITECT */ {AUTOMATIC, false, 1, 200, 0},
/* ANIMALTRAIN */ {AUTOMATIC, false, 1, 200, 0},
/* ANIMALCARE */ {AUTOMATIC, false, 1, 200, 0},
/* DIAGNOSE */ {AUTOMATIC, false, 1, 200, 0},
@ -242,7 +245,18 @@ static const struct labor_default default_labor_infos[] = {
/* BUILD_ROAD */ {AUTOMATIC, false, 1, 200, 0},
/* BUILD_CONSTRUCTION */ {AUTOMATIC, false, 1, 200, 0},
/* PAPERMAKING */ {AUTOMATIC, false, 1, 200, 0},
/* BOOKBINDING */ {AUTOMATIC, false, 1, 200, 0}
/* BOOKBINDING */ {AUTOMATIC, false, 1, 200, 0},
/* ANON_LABOR_83 */ {DISABLE, false, 0, 0, 0},
/* ANON_LABOR_84 */ {DISABLE, false, 0, 0, 0},
/* ANON_LABOR_85 */ {DISABLE, false, 0, 0, 0},
/* ANON_LABOR_86 */ {DISABLE, false, 0, 0, 0},
/* ANON_LABOR_87 */ {DISABLE, false, 0, 0, 0},
/* ANON_LABOR_88 */ {DISABLE, false, 0, 0, 0},
/* ANON_LABOR_89 */ {DISABLE, false, 0, 0, 0},
/* ANON_LABOR_90 */ {DISABLE, false, 0, 0, 0},
/* ANON_LABOR_91 */ {DISABLE, false, 0, 0, 0},
/* ANON_LABOR_92 */ {DISABLE, false, 0, 0, 0},
/* ANON_LABOR_93 */ {DISABLE, false, 0, 0, 0},
};
static const int responsibility_penalties[] = {
@ -399,6 +413,8 @@ static void enable_plugin(color_ostream &out)
cleanup_state();
init_state();
df::global::game->external_flag |= 1; // shut down DF's work detail system
}
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
@ -711,15 +727,18 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan
DFhackCExport command_result plugin_onupdate ( color_ostream &out )
{
static int step_count = 0;
static int last_run = 0;
static const int run_frequency = 60;
if(!world || !world->map.block_index || !enable_autolabor)
{
return CR_OK;
}
if (++step_count < 60)
if (world->frame_counter - last_run <= run_frequency)
return CR_OK;
step_count = 0;
last_run = world->frame_counter;
std::vector<df::unit *> dwarfs;
@ -1065,6 +1084,8 @@ DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable )
enable_autolabor = false;
setOptionEnabled(CF_ENABLED, false);
df::global::game->external_flag &= ~1; // reenable DF's work detail system
out << "Autolabor is disabled." << std::endl;
}

@ -42,6 +42,8 @@ char const* state_names[] {
const dwarf_state dwarf_states[] = {
dwarf_state::BUSY /* CarveFortification */,
dwarf_state::BUSY /* SmoothWall */,
dwarf_state::BUSY /* SmoothFloor */,
dwarf_state::BUSY /* DetailWall */,
dwarf_state::BUSY /* DetailFloor */,
dwarf_state::EXCLUSIVE /* Dig */,
@ -75,21 +77,17 @@ const dwarf_state dwarf_states[] = {
dwarf_state::BUSY /* CatchLiveLandAnimal */,
dwarf_state::BUSY /* CatchLiveFish */,
dwarf_state::BUSY /* ReturnKill */,
dwarf_state::BUSY /* CheckChest */,
dwarf_state::BUSY /* StoreOwnedItem */,
dwarf_state::BUSY /* PlaceItemInTomb */,
dwarf_state::BUSY /* StoreItemInStockpile */,
dwarf_state::BUSY /* StoreItemInBag */,
dwarf_state::BUSY /* StoreItemInHospital */,
dwarf_state::BUSY /* StoreItemInChest */,
dwarf_state::BUSY /* StoreItemInCabinet */,
dwarf_state::BUSY /* StoreItemInLocation */,
dwarf_state::BUSY /* StoreWeapon */,
dwarf_state::BUSY /* StoreArmor */,
dwarf_state::BUSY /* StoreItemInBarrel */,
dwarf_state::BUSY /* StoreItemInBin */,
dwarf_state::BUSY /* SeekArtifact */,
dwarf_state::BUSY /* SeekInfant */,
dwarf_state::OTHER /* AttendParty */,
dwarf_state::OTHER /* GoShopping */,
dwarf_state::OTHER /* GoShopping2 */,
dwarf_state::BUSY /* Clean */,
@ -117,6 +115,7 @@ const dwarf_state dwarf_states[] = {
dwarf_state::BUSY /* ConstructCoffin */,
dwarf_state::BUSY /* ConstructTable */,
dwarf_state::BUSY /* ConstructChest */,
dwarf_state::BUSY /* ConstructBag */,
dwarf_state::BUSY /* ConstructBin */,
dwarf_state::BUSY /* ConstructArmorStand */,
dwarf_state::BUSY /* ConstructWeaponRack */,
@ -153,7 +152,7 @@ const dwarf_state dwarf_states[] = {
dwarf_state::BUSY /* MilkCreature */,
dwarf_state::BUSY /* MakeCheese */,
dwarf_state::BUSY /* ProcessPlants */,
dwarf_state::BUSY /* ProcessPlantsBag */,
dwarf_state::BUSY /* PolishStones */,
dwarf_state::BUSY /* ProcessPlantsVial */,
dwarf_state::BUSY /* ProcessPlantsBarrel */,
dwarf_state::BUSY /* PrepareMeal */,
@ -165,7 +164,6 @@ const dwarf_state dwarf_states[] = {
dwarf_state::BUSY /* MakeChain */,
dwarf_state::BUSY /* MakeFlask */,
dwarf_state::BUSY /* MakeGoblet */,
dwarf_state::BUSY /* MakeInstrument */,
dwarf_state::BUSY /* MakeToy */,
dwarf_state::BUSY /* MakeAnimalTrap */,
dwarf_state::BUSY /* MakeBarrel */,
@ -188,10 +186,10 @@ const dwarf_state dwarf_states[] = {
dwarf_state::BUSY /* LoadStoneTrap */,
dwarf_state::BUSY /* LoadWeaponTrap */,
dwarf_state::BUSY /* CleanTrap */,
dwarf_state::BUSY /* CastSpell */,
dwarf_state::BUSY /* EncrustWithStones */,
dwarf_state::BUSY /* LinkBuildingToTrigger */,
dwarf_state::BUSY /* PullLever */,
dwarf_state::BUSY /* BrewDrink */,
dwarf_state::OTHER /* _unk_0x94*/,
dwarf_state::BUSY /* ExtractFromPlants */,
dwarf_state::BUSY /* ExtractFromRawFish */,
dwarf_state::BUSY /* ExtractFromLandAnimal */,

@ -0,0 +1,47 @@
local _ENV = mkmodule('plugins.autolabor')
local gui = require('gui')
local overlay = require('plugins.overlay')
local widgets = require('gui.widgets')
local function is_labor_panel_visible()
local info = df.global.game.main_interface.info
return info.open and info.current_mode == df.info_interface_mode_type.LABOR
end
AutolaborOverlay = defclass(AutolaborOverlay, overlay.OverlayWidget)
AutolaborOverlay.ATTRS{
default_pos={x=7,y=-13},
default_enabled=true,
viewscreens='dwarfmode',
frame={w=29, h=5},
frame_style=gui.MEDIUM_FRAME,
frame_background=gui.CLEAR_PEN,
}
function AutolaborOverlay:init()
self:addviews{
widgets.Label{
frame={t=0, l=0},
text_pen=COLOR_RED,
text={
'DFHack autolabor is active!', NEWLINE,
'Any changes made on this', NEWLINE,
'screen will have no effect.'
},
},
}
end
function AutolaborOverlay:render(dc)
if not is_labor_panel_visible() or not isEnabled() then
return false
end
AutolaborOverlay.super.render(self, dc)
end
OVERLAY_WIDGETS = {
overlay=AutolaborOverlay,
}
return _ENV