@ -82,6 +82,8 @@ static PersistentDataItem config;
enum ConfigFlags {
enum ConfigFlags {
CF_ENABLED = 1 ,
CF_ENABLED = 1 ,
CF_ALLOW_FISHING = 2 ,
CF_ALLOW_HUNTING = 4 ,
} ;
} ;
@ -482,6 +484,8 @@ struct dwarf_info_t
}
}
void set_labor ( df : : unit_labor labor )
void set_labor ( df : : unit_labor labor )
{
if ( labor > = 0 & & labor < = ENUM_LAST_ITEM ( unit_labor ) )
{
{
dwarf - > status . labors [ labor ] = true ;
dwarf - > status . labors [ labor ] = true ;
if ( ( labor = = df : : unit_labor : : MINE & & ! has_pick ) | |
if ( ( labor = = df : : unit_labor : : MINE & & ! has_pick ) | |
@ -489,8 +493,11 @@ struct dwarf_info_t
( labor = = df : : unit_labor : : HUNT & & ! has_crossbow ) )
( labor = = df : : unit_labor : : HUNT & & ! has_crossbow ) )
dwarf - > military . pickup_flags . bits . update = 1 ;
dwarf - > military . pickup_flags . bits . update = 1 ;
}
}
}
void clear_labor ( df : : unit_labor labor )
void clear_labor ( df : : unit_labor labor )
{
if ( labor > = 0 & & labor < = ENUM_LAST_ITEM ( unit_labor ) )
{
{
dwarf - > status . labors [ labor ] = false ;
dwarf - > status . labors [ labor ] = false ;
if ( ( labor = = df : : unit_labor : : MINE & & has_pick ) | |
if ( ( labor = = df : : unit_labor : : MINE & & has_pick ) | |
@ -498,6 +505,7 @@ struct dwarf_info_t
( labor = = df : : unit_labor : : HUNT & & has_crossbow ) )
( labor = = df : : unit_labor : : HUNT & & has_crossbow ) )
dwarf - > military . pickup_flags . bits . update = 1 ;
dwarf - > military . pickup_flags . bits . update = 1 ;
}
}
}
} ;
} ;
@ -752,6 +760,7 @@ private:
case df : : building_type : : WindowGem :
case df : : building_type : : WindowGem :
case df : : building_type : : Cage :
case df : : building_type : : Cage :
case df : : building_type : : NestBox :
case df : : building_type : : NestBox :
case df : : building_type : : TractionBench :
return df : : unit_labor : : HAUL_FURNITURE ;
return df : : unit_labor : : HAUL_FURNITURE ;
case df : : building_type : : Trap :
case df : : building_type : : Trap :
return df : : unit_labor : : MECHANIC ;
return df : : unit_labor : : MECHANIC ;
@ -1736,7 +1745,7 @@ private:
FOR_ENUM_ITEMS ( job_skill , skill )
FOR_ENUM_ITEMS ( job_skill , skill )
{
{
int skill_level = Units : : get Effective Skill( dwarf - > dwarf , skill ) ;
int skill_level = Units : : get Nominal Skill( dwarf - > dwarf , skill , false ) ;
high_skill = std : : max ( high_skill , skill_level ) ;
high_skill = std : : max ( high_skill , skill_level ) ;
}
}
@ -1866,6 +1875,14 @@ public:
if ( ( * v ) - > route_id ! = - 1 )
if ( ( * v ) - > route_id ! = - 1 )
labor_needed [ df : : unit_labor : : PUSH_HAUL_VEHICLE ] + + ;
labor_needed [ df : : unit_labor : : PUSH_HAUL_VEHICLE ] + + ;
// add fishing & hunting
if ( isOptionEnabled ( CF_ALLOW_FISHING ) & & has_fishery )
labor_needed [ df : : unit_labor : : FISH ] + + ;
if ( isOptionEnabled ( CF_ALLOW_HUNTING ) & & has_butchers )
labor_needed [ df : : unit_labor : : HUNT ] + + ;
if ( print_debug )
if ( print_debug )
{
{
for ( auto i = labor_needed . begin ( ) ; i ! = labor_needed . end ( ) ; i + + )
for ( auto i = labor_needed . begin ( ) ; i ! = labor_needed . end ( ) ; i + + )
@ -1893,6 +1910,31 @@ public:
if ( print_debug )
if ( print_debug )
out . print ( " available count = %d, distinct labors needed = %d \n " , available_dwarfs . size ( ) , pq . size ( ) ) ;
out . print ( " available count = %d, distinct labors needed = %d \n " , available_dwarfs . size ( ) , pq . size ( ) ) ;
std : : map < df : : unit_labor , int > to_assign ;
to_assign . clear ( ) ;
int av = available_dwarfs . size ( ) ;
while ( ! pq . empty ( ) & & av > 0 )
{
df : : unit_labor labor = pq . top ( ) . second ;
int priority = pq . top ( ) . first ;
to_assign [ labor ] + + ;
pq . pop ( ) ;
av - - ;
if ( print_debug )
out . print ( " Will assign: %s priority %d (%d) \n " , ENUM_KEY_STR ( unit_labor , labor ) . c_str ( ) , priority , to_assign [ labor ] ) ;
if ( - - labor_needed [ labor ] > 0 )
{
priority / = 2 ;
pq . push ( make_pair ( priority , labor ) ) ;
}
}
int canary = ( 1 < < df : : unit_labor : : HAUL_STONE ) |
int canary = ( 1 < < df : : unit_labor : : HAUL_STONE ) |
( 1 < < df : : unit_labor : : HAUL_WOOD ) |
( 1 < < df : : unit_labor : : HAUL_WOOD ) |
( 1 < < df : : unit_labor : : HAUL_BODY ) |
( 1 < < df : : unit_labor : : HAUL_BODY ) |
@ -1902,18 +1944,20 @@ public:
( 1 < < df : : unit_labor : : HAUL_FURNITURE ) |
( 1 < < df : : unit_labor : : HAUL_FURNITURE ) |
( 1 < < df : : unit_labor : : HAUL_ANIMAL ) ;
( 1 < < df : : unit_labor : : HAUL_ANIMAL ) ;
while ( ! available_dwarfs . empty ( ) & & ! pq . empty ( ) )
while ( ! available_dwarfs . empty ( ) )
{
{
df : : unit_labor labor = pq . top ( ) . second ;
int priority = pq . top ( ) . first ;
df : : job_skill skill = labor_to_skill [ labor ] ;
if ( print_debug )
out . print ( " labor %s skill %s priority %d \n " , ENUM_KEY_STR ( unit_labor , labor ) . c_str ( ) , ENUM_KEY_STR ( job_skill , skill ) . c_str ( ) , priority ) ;
std : : list < dwarf_info_t * > : : iterator bestdwarf = available_dwarfs . begin ( ) ;
std : : list < dwarf_info_t * > : : iterator bestdwarf = available_dwarfs . begin ( ) ;
int best_score = - 10000 ;
int best_score = - 10000 ;
df : : unit_labor best_labor = df : : unit_labor : : NONE ;
for ( auto j = to_assign . begin ( ) ; j ! = to_assign . end ( ) ; j + + )
{
if ( j - > second < = 0 )
continue ;
df : : unit_labor labor = j - > first ;
df : : job_skill skill = labor_to_skill [ labor ] ;
for ( std : : list < dwarf_info_t * > : : iterator k = available_dwarfs . begin ( ) ; k ! = available_dwarfs . end ( ) ; k + + )
for ( std : : list < dwarf_info_t * > : : iterator k = available_dwarfs . begin ( ) ; k ! = available_dwarfs . end ( ) ; k + + )
{
{
@ -1921,44 +1965,44 @@ public:
int skill_level = 0 ;
int skill_level = 0 ;
if ( skill ! = df : : job_skill : : NONE )
if ( skill ! = df : : job_skill : : NONE )
{
{
int skill_level = Units : : getEffectiveSkill ( d - > dwarf , skill ) ;
skill_level = Units : : getEffectiveSkill ( d - > dwarf , skill ) ;
}
}
int score = skill_level * 100 - ( d - > high_skill - skill_level ) * 500 ;
int score = skill_level * 100 - ( d - > high_skill - skill_level ) * 200 ;
if ( d - > dwarf - > status . labors [ labor ] )
if ( d - > dwarf - > status . labors [ labor ] )
score + = 500 ;
score + = 500 ;
if ( ( labor = = df : : unit_labor : : MINE & & d - > has_pick ) | |
if ( ( labor = = df : : unit_labor : : MINE & & d - > has_pick ) | |
( labor = = df : : unit_labor : : CUTWOOD & & d - > has_axe ) | |
( labor = = df : : unit_labor : : CUTWOOD & & d - > has_axe ) | |
( labor = = df : : unit_labor : : HUNT & & d - > has_crossbow ) )
( labor = = df : : unit_labor : : HUNT & & d - > has_crossbow ) )
score + = 500 ;
score + = 500 ;
if ( score > best_score )
if ( score > best_score )
{
{
bestdwarf = k ;
bestdwarf = k ;
best_score = score ;
best_score = score ;
best_labor = labor ;
}
}
}
}
}
if ( print_debug )
if ( print_debug )
out . print ( " assign \" %s \" labor %s score=%d \n " , ( * bestdwarf ) - > dwarf - > name . first_name . c_str ( ) , ENUM_KEY_STR ( unit_labor , labor ) . c_str ( ) , best_score ) ;
out . print ( " assign \" %s \" labor %s score=%d \n " , ( * bestdwarf ) - > dwarf - > name . first_name . c_str ( ) , ENUM_KEY_STR ( unit_labor , best_labor ) . c_str ( ) , best_score ) ;
FOR_ENUM_ITEMS ( unit_labor , l )
FOR_ENUM_ITEMS ( unit_labor , l )
{
{
if ( l = = labor )
if ( l = = df : : unit_labor : : NONE )
continue ;
if ( l = = best_labor )
( * bestdwarf ) - > set_labor ( l ) ;
( * bestdwarf ) - > set_labor ( l ) ;
else
else
( * bestdwarf ) - > clear_labor ( l ) ;
( * bestdwarf ) - > clear_labor ( l ) ;
}
}
if ( labor > = df : : unit_labor : : HAUL_STONE & & labor < = df : : unit_labor : : HAUL_ANIMAL )
if ( best_ labor > = df : : unit_labor : : HAUL_STONE & & best_ labor < = df : : unit_labor : : HAUL_ANIMAL )
canary & = ~ ( 1 < < labor) ;
canary & = ~ ( 1 < < best_ labor) ;
labor_infos [ labor] . active_dwarfs + + ;
labor_infos [ best_ labor] . active_dwarfs + + ;
to_assign [ best_labor ] - - ;
available_dwarfs . erase ( bestdwarf ) ;
available_dwarfs . erase ( bestdwarf ) ;
pq . pop ( ) ;
if ( - - labor_needed [ labor ] > 0 )
{
priority / = 2 ;
pq . push ( make_pair ( priority , labor ) ) ;
}
}
}
if ( canary ! = 0 )
if ( canary ! = 0 )
@ -2125,6 +2169,28 @@ command_result autolabor (color_ostream &out, std::vector <std::string> & parame
print_labor ( labor , out ) ;
print_labor ( labor , out ) ;
return CR_OK ;
return CR_OK ;
}
}
else if ( parameters . size ( ) = = 1 & & ( parameters [ 0 ] = = " allow-fishing " | | parameters [ 0 ] = = " forbid-fishing " ) )
{
if ( ! enable_autolabor )
{
out < < " Error: The plugin is not enabled. " < < endl ;
return CR_FAILURE ;
}
setOptionEnabled ( CF_ALLOW_FISHING , ( parameters [ 0 ] = = " allow-fishing " ) ) ;
return CR_OK ;
}
else if ( parameters . size ( ) = = 1 & & ( parameters [ 0 ] = = " allow-hunting " | | parameters [ 0 ] = = " forbid-hunting " ) )
{
if ( ! enable_autolabor )
{
out < < " Error: The plugin is not enabled. " < < endl ;
return CR_FAILURE ;
}
setOptionEnabled ( CF_ALLOW_HUNTING , ( parameters [ 0 ] = = " allow-hunting " ) ) ;
return CR_OK ;
}
else if ( parameters . size ( ) = = 1 & & parameters [ 0 ] = = " reset-all " )
else if ( parameters . size ( ) = = 1 & & parameters [ 0 ] = = " reset-all " )
{
{
if ( ! enable_autolabor )
if ( ! enable_autolabor )