@ -144,13 +144,15 @@ static struct BadFlags {
} badFlags ;
class Tailor {
private :
std : : map < std : : pair < df : : item_type , int > , int > available ; // key is item type & size
std : : map < std : : pair < df : : item_type , int > , int > needed ; // same
std : : map < std : : pair < df : : item_type , int > , int > queued ; // same
private :
std : : map < int , int > sizes ; // this maps body size to races
std : : map < std : : tuple < df : : job_type , int , int > , int > orders ; // key is item type, item subtype, size
std : : map < std : : pair < df : : item_type , int > , int > available ;
std : : map < std : : pair < df : : item_type , int > , int > needed ;
std : : map < std : : tuple < df : : job_type , int , int > , int > orders ;
std : : map < MatType , int > supply ;
std : : map < MatType , int > reserves ;
@ -169,41 +171,18 @@ public:
{
available . clear ( ) ;
needed . clear ( ) ;
queued . clear ( ) ;
sizes . clear ( ) ;
orders . clear ( ) ;
supply . clear ( ) ;
orders . clear ( ) ;
}
void scan_clothing ( )
{
if ( ! inventory_sanity_checking )
{
for ( auto i : world - > items . other [ df : : items_other_id : : ANY_GENERIC37 ] ) // GENERIC37 is "clothing"
for ( auto i : world - > items . other [ df : : items_other_id : : ANY_GENERIC37 ] ) // GENERIC37 is "nontattered clothing"
{
if ( i - > flags . whole & badFlags . whole )
continue ;
if ( i - > getWear ( ) > = 1 )
continue ;
df : : item_type t = i - > getType ( ) ;
int size = world - > raws . creatures . all [ i - > getMakerRace ( ) ] - > adultsize ;
available [ std : : make_pair ( t , size ) ] + = 1 ;
}
}
else
{
auto & l = world - > items . other [ df : : items_other_id : : ANY_GENERIC37 ] ;
for ( auto i : world - > items . other [ df : : items_other_id : : IN_PLAY ] )
{
if ( i - > flags . whole & badFlags . whole )
continue ;
if ( ! i - > isClothing ( ) )
continue ;
if ( std : : find ( std : : begin ( l ) , std : : end ( l ) , i ) = = std : : end ( l ) )
{
DEBUG ( cycle ) . print ( " tailor: clothing item %d missing from GENERIC37 list \n " , i - > id ) ;
}
if ( i - > getWear ( ) > = 1 )
continue ;
@ -213,6 +192,13 @@ public:
available [ std : : make_pair ( t , size ) ] + = 1 ;
}
for ( auto & i : available )
{
df : : item_type t ;
int size ;
std : : tie ( t , size ) = i . first ;
DEBUG ( cycle ) . print ( " tailor: %d %s of size %d found \n " ,
i . second , ENUM_KEY_STR ( item_type , t ) . c_str ( ) , size ) ;
}
}
@ -273,14 +259,13 @@ public:
if ( ! Units : : isOwnCiv ( u ) | |
! Units : : isOwnGroup ( u ) | |
! Units : : isActive ( u ) | |
Units : : isBaby ( u ) )
continue ; // skip units we don't control
Units : : isBaby ( u ) | |
! Units : : casteFlagSet ( u - > race , u - > caste , df : : enums : : caste_raw_flags : : EQUIPS ) )
continue ; // skip units we don't control or that can't wear clothes
std : : set < df : : item_type > wearing ;
wearing . clear ( ) ;
std : : set < df : : item_type > ordered ;
std : : deque < df : : item * > worn ;
worn . clear ( ) ;
for ( auto inv : u - > inventory )
{
@ -295,33 +280,37 @@ public:
int usize = world - > raws . creatures . all [ u - > race ] - > adultsize ;
sizes [ usize ] = u - > race ;
for ( auto ty : std : : set < df : : item_type > { df : : item_type : : ARMOR , df : : item_type : : PANTS , df : : item_type : : SHOES } )
{
if ( wearing . count ( ty ) = = 0 )
{
TRACE ( cycle ) . print ( " tailor: one %s of size %d needed to cover %s \n " ,
ENUM_KEY_STR ( item_type , ty ) . c_str ( ) ,
usize ,
Translation : : TranslateName ( & u - > name , false ) . c_str ( ) ) ;
needed [ std : : make_pair ( ty , usize ) ] + = 1 ;
}
}
for ( auto w : worn )
{
auto ty = w - > getType ( ) ;
auto oo = itemTypeMap . find ( ty ) ;
if ( oo = = itemTypeMap . end ( ) )
{
continue ;
}
const df : : job_type o = oo - > second ;
int isize = world - > raws . creatures . all [ w - > getMakerRace ( ) ] - > adultsize ;
std : : string description ;
w - > getItemDescription ( & description , 0 ) ;
bool allocated = false ;
if ( wearing . count ( ty ) = = 0 )
{
if ( available [ std : : make_pair ( ty , usize ) ] > 0 )
{
available [ std : : make_pair ( ty , usize ) ] - = 1 ;
DEBUG ( cycle ) . print ( " tailor: allocating a %s (size %d) to %s \n " ,
ENUM_KEY_STR ( item_type , ty ) . c_str ( ) , usize ,
Translation : : TranslateName ( & u - > name , false ) . c_str ( ) ) ;
wearing . insert ( ty ) ;
}
else if ( ordered . count ( ty ) = = 0 )
{
DEBUG ( cycle ) . print ( " tailor: %s (size %d) worn by %s (size %d) needs replacement, but none available \n " ,
description . c_str ( ) , isize ,
Translation : : TranslateName ( & u - > name , false ) . c_str ( ) , usize ) ;
needed [ std : : make_pair ( ty , usize ) ] + = 1 ;
ordered . insert ( ty ) ;
}
}
if ( wearing . count ( ty ) > 0 )
{
if ( w - > flags . bits . owned )
{
@ -335,23 +324,21 @@ public:
) ;
}
if ( wearing . count ( ty ) = = 0 )
{
DEBUG ( cycle ) . print ( " tailor: allocating a %s (size %d) to %s \n " ,
ENUM_KEY_STR ( item_type , ty ) . c_str ( ) , usize ,
Translation : : TranslateName ( & u - > name , false ) . c_str ( ) ) ;
available [ std : : make_pair ( ty , usize ) ] - = 1 ;
}
if ( w - > getWear ( ) > 1 )
w - > flags . bits . dump = true ;
}
else
}
for ( auto ty : std : : set < df : : item_type > { df : : item_type : : ARMOR , df : : item_type : : PANTS , df : : item_type : : SHOES } )
{
DEBUG ( cycle ) . print ( " tailor: %s (size %d) worn by %s (size %d) needs replacement, but none available \n " ,
description . c_str ( ) , isize ,
Translation : : TranslateName ( & u - > name , false ) . c_str ( ) , usize ) ;
orders [ std : : make_tuple ( o , w - > getSubtype ( ) , usize ) ] + = 1 ;
if ( wearing . count ( ty ) = = 0 & & ordered . count ( ty ) = = 0 )
{
TRACE ( cycle ) . print ( " tailor: one %s of size %d needed to cover %s \n " ,
ENUM_KEY_STR ( item_type , ty ) . c_str ( ) ,
usize ,
Translation : : TranslateName ( & u - > name , false ) . c_str ( ) ) ;
needed [ std : : make_pair ( ty , usize ) ] + = 1 ;
}
}
}
@ -367,6 +354,9 @@ public:
int size = a . first . second ;
int count = a . second ;
if ( count < = 0 )
continue ;
int sub = 0 ;
std : : vector < int16_t > v ;
@ -432,7 +422,14 @@ public:
int size = world - > raws . creatures . all [ race ] - > adultsize ;
orders [ std : : make_tuple ( o - > job_type , sub , size ) ] - = o - > amount_left ;
auto tt = jobTypeMap . find ( o - > job_type ) ;
if ( tt = = jobTypeMap . end ( ) )
{
continue ;
}
needed [ std : : make_pair ( tt - > second , size ) ] - = o - > amount_left ;
TRACE ( cycle ) . print ( " tailor: existing order for %d %s of size %d detected \n " ,
o - > amount_left ,
ENUM_KEY_STR ( job_type , o - > job_type ) . c_str ( ) ,
@ -576,8 +573,8 @@ public:
scan_clothing ( ) ;
scan_materials ( ) ;
scan_replacements ( ) ;
create_orders ( ) ;
scan_existing_orders ( ) ;
create_orders ( ) ;
return place_orders ( ) ;
}