|  |  |  | @ -157,10 +157,14 @@ static const char *state_names[] = { | 
		
	
		
			
				|  |  |  |  |     "BUSY", | 
		
	
		
			
				|  |  |  |  |     "MILITARY", | 
		
	
		
			
				|  |  |  |  |     "CHILD", | 
		
	
		
			
				|  |  |  |  |     "OTHER", | 
		
	
		
			
				|  |  |  |  |     "OTHER" | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // List of possible activites of a dwarf that will be further narrowed to states
 | 
		
	
		
			
				|  |  |  |  | // IDLE - Specifically waiting to be assigned a task (No Job)
 | 
		
	
		
			
				|  |  |  |  | // BUSY - Performing a toggleable labor, or a support action for that labor.
 | 
		
	
		
			
				|  |  |  |  | // OTHER - Doing something else
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static const dwarf_state dwarf_states[] = { | 
		
	
		
			
				|  |  |  |  |     BUSY  /* CarveFortification */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* DetailWall */, | 
		
	
	
		
			
				
					|  |  |  | @ -187,17 +191,17 @@ static const dwarf_state dwarf_states[] = { | 
		
	
		
			
				|  |  |  |  |     BUSY  /* CollectSand */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* Fish */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* Hunt */, | 
		
	
		
			
				|  |  |  |  |     OTHER /* HuntVermin */, | 
		
	
		
			
				|  |  |  |  |     BUSY /* Kidnap */, | 
		
	
		
			
				|  |  |  |  |     BUSY /* BeatCriminal */, | 
		
	
		
			
				|  |  |  |  |     BUSY /* StartingFistFight */, | 
		
	
		
			
				|  |  |  |  |     BUSY /* CollectTaxes */, | 
		
	
		
			
				|  |  |  |  |     BUSY /* GuardTaxCollector */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* HuntVermin */, | 
		
	
		
			
				|  |  |  |  |     OTHER /* Kidnap */, | 
		
	
		
			
				|  |  |  |  |     OTHER /* BeatCriminal */, | 
		
	
		
			
				|  |  |  |  |     OTHER /* StartingFistFight */, | 
		
	
		
			
				|  |  |  |  |     OTHER /* CollectTaxes */, | 
		
	
		
			
				|  |  |  |  |     OTHER /* GuardTaxCollector */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* CatchLiveLandAnimal */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* CatchLiveFish */, | 
		
	
		
			
				|  |  |  |  |     BUSY /* ReturnKill */, | 
		
	
		
			
				|  |  |  |  |     BUSY /* CheckChest */, | 
		
	
		
			
				|  |  |  |  |     BUSY /* StoreOwnedItem */, | 
		
	
		
			
				|  |  |  |  |     OTHER /* ReturnKill */, | 
		
	
		
			
				|  |  |  |  |     OTHER /* CheckChest */, | 
		
	
		
			
				|  |  |  |  |     OTHER /* StoreOwnedItem */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* PlaceItemInTomb */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* StoreItemInStockpile */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* StoreItemInBag */, | 
		
	
	
		
			
				
					|  |  |  | @ -208,12 +212,12 @@ static const dwarf_state dwarf_states[] = { | 
		
	
		
			
				|  |  |  |  |     BUSY  /* StoreArmor */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* StoreItemInBarrel */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* StoreItemInBin */, | 
		
	
		
			
				|  |  |  |  |     BUSY /* SeekArtifact */, | 
		
	
		
			
				|  |  |  |  |     BUSY /* SeekInfant */, | 
		
	
		
			
				|  |  |  |  |     OTHER /* SeekArtifact */, | 
		
	
		
			
				|  |  |  |  |     OTHER /* SeekInfant */, | 
		
	
		
			
				|  |  |  |  |     OTHER /* AttendParty */, | 
		
	
		
			
				|  |  |  |  |     OTHER /* GoShopping */, | 
		
	
		
			
				|  |  |  |  |     OTHER /* GoShopping2 */, | 
		
	
		
			
				|  |  |  |  |     BUSY /* Clean */, | 
		
	
		
			
				|  |  |  |  |     OTHER /* Clean */, | 
		
	
		
			
				|  |  |  |  |     OTHER /* Rest */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* PickupEquipment */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* DumpItem */, | 
		
	
	
		
			
				
					|  |  |  | @ -309,7 +313,7 @@ static const dwarf_state dwarf_states[] = { | 
		
	
		
			
				|  |  |  |  |     BUSY  /* LoadStoneTrap */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* LoadWeaponTrap */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* CleanTrap */, | 
		
	
		
			
				|  |  |  |  |     BUSY /* CastSpell */, | 
		
	
		
			
				|  |  |  |  |     OTHER /* CastSpell */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* LinkBuildingToTrigger */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* PullLever */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* BrewDrink */, | 
		
	
	
		
			
				
					|  |  |  | @ -370,7 +374,7 @@ static const dwarf_state dwarf_states[] = { | 
		
	
		
			
				|  |  |  |  |     BUSY  /* ConstructSplint */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* ConstructCrutch */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* ConstructTractionBench */, | 
		
	
		
			
				|  |  |  |  |     BUSY /* CleanSelf */, | 
		
	
		
			
				|  |  |  |  |     OTHER /* CleanSelf */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* BringCrutch */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* ApplyCast */, | 
		
	
		
			
				|  |  |  |  |     BUSY  /* CustomReaction */, | 
		
	
	
		
			
				
					|  |  |  | @ -426,6 +430,7 @@ struct labor_info | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Return the labor_mode associated with this labor
 | 
		
	
		
			
				|  |  |  |  |     labor_mode mode() { return (labor_mode) config.ival(0); } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Set the labor_mode associated with this labor
 | 
		
	
		
			
				|  |  |  |  |     void set_mode(labor_mode mode) { config.ival(0) = mode; } | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
	
		
			
				
					|  |  |  | @ -458,7 +463,7 @@ static const struct labor_default default_labor_infos[] = { | 
		
	
		
			
				|  |  |  |  |     /* BONE_SETTING */          {ALLOW,   0}, | 
		
	
		
			
				|  |  |  |  |     /* SUTURING */              {ALLOW,   0}, | 
		
	
		
			
				|  |  |  |  |     /* DRESSING_WOUNDS */       {ALLOW,   0}, | 
		
	
		
			
				|  |  |  |  |     /* FEED_WATER_CIVILIANS */  {ALLOW,   0}, | 
		
	
		
			
				|  |  |  |  |     /* FEED_WATER_CIVILIANS */  {HAULERS, 0}, // This could also be ALLOW
 | 
		
	
		
			
				|  |  |  |  |     /* RECOVER_WOUNDED */       {HAULERS, 0}, | 
		
	
		
			
				|  |  |  |  |     /* BUTCHER */               {ALLOW,   0}, | 
		
	
		
			
				|  |  |  |  |     /* TRAPPER */               {ALLOW,   0}, | 
		
	
	
		
			
				
					|  |  |  | @ -534,6 +539,7 @@ struct dwarf_info_t | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     // Current simplified employment status of dwarf
 | 
		
	
		
			
				|  |  |  |  |     dwarf_state state; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Set to true if for whatever reason we are exempting this dwarf
 | 
		
	
		
			
				|  |  |  |  |     // from hauling
 | 
		
	
		
			
				|  |  |  |  |     bool haul_exempt; | 
		
	
	
		
			
				
					|  |  |  | @ -704,6 +710,8 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <Plug | 
		
	
		
			
				|  |  |  |  |         "    List current status of all labors.\n" | 
		
	
		
			
				|  |  |  |  |         "  autohauler status\n" | 
		
	
		
			
				|  |  |  |  |         "    Show basic status information.\n" | 
		
	
		
			
				|  |  |  |  |         "  autohauler debug\n" | 
		
	
		
			
				|  |  |  |  |         "    In the next cycle, will output the state of every dwarf.\n" | 
		
	
		
			
				|  |  |  |  |         "Function:\n" | 
		
	
		
			
				|  |  |  |  |         "  When enabled, autohauler periodically checks your dwarves and assigns\n" | 
		
	
		
			
				|  |  |  |  |         "  hauling jobs to idle dwarves while removing them from busy dwarves.\n" | 
		
	
	
		
			
				
					|  |  |  | @ -818,6 +826,9 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) | 
		
	
		
			
				|  |  |  |  |         /* Before determining how to handle employment status, handle
 | 
		
	
		
			
				|  |  |  |  |          * hauling exemptions first */ | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         // Default deny condition of on break for later else-if series
 | 
		
	
		
			
				|  |  |  |  |         bool is_migrant = false; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         // Scan every labor. If a labor that disallows hauling is present
 | 
		
	
		
			
				|  |  |  |  |         // for the dwarf, the dwarf is hauling exempt
 | 
		
	
		
			
				|  |  |  |  |         FOR_ENUM_ITEMS(unit_labor, labor) | 
		
	
	
		
			
				
					|  |  |  | @ -836,8 +847,8 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) | 
		
	
		
			
				|  |  |  |  |         // to try to find real jobs first
 | 
		
	
		
			
				|  |  |  |  |         for (auto p = dwarfs[dwarf]->status.misc_traits.begin(); p < dwarfs[dwarf]->status.misc_traits.end(); p++) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             if ((*p)->id == misc_trait_type::Migrant || (*p)->id == misc_trait_type::OnBreak) | 
		
	
		
			
				|  |  |  |  |                 dwarf_info[dwarf].haul_exempt = true; | 
		
	
		
			
				|  |  |  |  |             if ((*p)->id == misc_trait_type::Migrant) | 
		
	
		
			
				|  |  |  |  |                 is_migrant = true; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         /* Now determine a dwarf's employment status and decide whether
 | 
		
	
	
		
			
				
					|  |  |  | @ -852,17 +863,24 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) | 
		
	
		
			
				|  |  |  |  |         // Account for any hauling exemptions here
 | 
		
	
		
			
				|  |  |  |  |         else if (dwarf_info[dwarf].haul_exempt) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             dwarf_info[dwarf].state = OTHER; | 
		
	
		
			
				|  |  |  |  |             dwarf_info[dwarf].state = BUSY; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         // Don't give hauling jobs to the military either
 | 
		
	
		
			
				|  |  |  |  |         // Account for the military
 | 
		
	
		
			
				|  |  |  |  |         else if (ENUM_ATTR(profession, military, dwarfs[dwarf]->profession)) | 
		
	
		
			
				|  |  |  |  |             dwarf_info[dwarf].state = MILITARY; | 
		
	
		
			
				|  |  |  |  |         // Account for dwarves on break or migrants
 | 
		
	
		
			
				|  |  |  |  |         // DF leaves the OnBreak trait type on some dwarves while they're not actually on break
 | 
		
	
		
			
				|  |  |  |  |         // Since they have no current job, they will default to IDLE
 | 
		
	
		
			
				|  |  |  |  |         else if (is_migrant) | 
		
	
		
			
				|  |  |  |  |         // Dwarf is unemployed with null job
 | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             dwarf_info[dwarf].state = OTHER; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if (dwarfs[dwarf]->job.current_job == NULL) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             dwarf_info[dwarf].state = IDLE; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         // If it gets to this point the dwarf is employed
 | 
		
	
		
			
				|  |  |  |  |         // If it gets to this point we look at the task and assign either BUSY or OTHER
 | 
		
	
		
			
				|  |  |  |  |         else | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             int job = dwarfs[dwarf]->job.current_job->job_type; | 
		
	
	
		
			
				
					|  |  |  | @ -870,17 +888,25 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) | 
		
	
		
			
				|  |  |  |  |                 dwarf_info[dwarf].state = dwarf_states[job]; | 
		
	
		
			
				|  |  |  |  |             else | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 // Warn the console that the dwarf has an unregistered labor, default to OTHER
 | 
		
	
		
			
				|  |  |  |  |                 // Warn the console that the dwarf has an unregistered labor, default to BUSY
 | 
		
	
		
			
				|  |  |  |  |                 out.print("Dwarf %i \"%s\" has unknown job %i\n", dwarf, dwarfs[dwarf]->name.first_name.c_str(), job); | 
		
	
		
			
				|  |  |  |  |                 dwarf_info[dwarf].state = OTHER; | 
		
	
		
			
				|  |  |  |  |                 dwarf_info[dwarf].state = BUSY; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         // Debug: Output dwarf job and state data
 | 
		
	
		
			
				|  |  |  |  |         if(print_debug) | 
		
	
		
			
				|  |  |  |  |             out.print("Dwarf %i %s State: %i\n", dwarf, dwarfs[dwarf]->name.first_name.c_str(), | 
		
	
		
			
				|  |  |  |  |                       dwarf_info[dwarf].state); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         // Increment corresponding labor in default_labor_infos struct
 | 
		
	
		
			
				|  |  |  |  |         state_count[dwarf_info[dwarf].state]++; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // At this point the debug if present has been completed
 | 
		
	
		
			
				|  |  |  |  |     print_debug = false; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // This is a vector of all the labors
 | 
		
	
		
			
				|  |  |  |  |     std::vector<df::unit_labor> labors; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -904,31 +930,21 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // IDLE     - Enable hauling
 | 
		
	
		
			
				|  |  |  |  |     // BUSY     - Disable hauling
 | 
		
	
		
			
				|  |  |  |  |     // OTHER - Disable hauling
 | 
		
	
		
			
				|  |  |  |  |     // OTHER    - Enable hauling
 | 
		
	
		
			
				|  |  |  |  |     // MILITARY - Enable hauling
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // This is a vector of potential hauler IDs
 | 
		
	
		
			
				|  |  |  |  |     std::vector<int> hauler_ids; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Pretty much we are only considering non-military, non-child dwarves
 | 
		
	
		
			
				|  |  |  |  |     for (int dwarf = 0; dwarf < n_dwarfs; dwarf++) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         if (dwarf_info[dwarf].state == IDLE || | 
		
	
		
			
				|  |  |  |  |             dwarf_info[dwarf].state == BUSY || | 
		
	
		
			
				|  |  |  |  |             dwarf_info[dwarf].state == OTHER) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             hauler_ids.push_back(dwarf); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     // There was no reason to put potential haulers in an array. All of them are
 | 
		
	
		
			
				|  |  |  |  |     // covered in the following for loop.
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Equivalent of Java for(unit_labor : labor)
 | 
		
	
		
			
				|  |  |  |  |     // For every labor...
 | 
		
	
		
			
				|  |  |  |  |     FOR_ENUM_ITEMS(unit_labor, labor) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         // If this is a non-labor skip this for loop
 | 
		
	
		
			
				|  |  |  |  |         // If this is a non-labor continue to next item
 | 
		
	
		
			
				|  |  |  |  |         if (labor == unit_labor::NONE) | 
		
	
		
			
				|  |  |  |  |             continue; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         // If this is not a hauling labor then skip this for loop
 | 
		
	
		
			
				|  |  |  |  |         // If this is not a hauling labor continue to next item
 | 
		
	
		
			
				|  |  |  |  |         if (labor_infos[labor].mode() != HAULERS) | 
		
	
		
			
				|  |  |  |  |             continue; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -936,15 +952,17 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) | 
		
	
		
			
				|  |  |  |  |         for(int dwarf = 0; dwarf < dwarfs.size(); dwarf++) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             // If the dwarf is idle, enable the hauling labor
 | 
		
	
		
			
				|  |  |  |  |             if(dwarf_info[dwarf].state == IDLE) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 // And enable the job for the dwarf
 | 
		
	
		
			
				|  |  |  |  |             // Set hauling labors based on employment states
 | 
		
	
		
			
				|  |  |  |  |             if(dwarf_info[dwarf].state == IDLE) { | 
		
	
		
			
				|  |  |  |  |                 dwarfs[dwarf]->status.labors[labor] = true; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |             // If the dwarf is busy, disable the hauling labor
 | 
		
	
		
			
				|  |  |  |  |             if(dwarf_info[dwarf].state == BUSY || dwarf_info[dwarf].state == OTHER) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |             else if(dwarf_info[dwarf].state == MILITARY) { | 
		
	
		
			
				|  |  |  |  |                 dwarfs[dwarf]->status.labors[labor] = true; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |             else if(dwarf_info[dwarf].state == OTHER) { | 
		
	
		
			
				|  |  |  |  |                 dwarfs[dwarf]->status.labors[labor] = true; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |             else if(dwarf_info[dwarf].state == BUSY) { | 
		
	
		
			
				|  |  |  |  |                 dwarfs[dwarf]->status.labors[labor] = false; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |             // If at the end of this the dwarf has the hauling labor, increment the
 | 
		
	
	
		
			
				
					|  |  |  | @ -954,6 +972,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) | 
		
	
		
			
				|  |  |  |  |                 labor_infos[labor].active_dwarfs++; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             // CHILD ignored
 | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Let's play a game of "find the missing bracket!" I hope this is correct.
 | 
		
	
	
		
			
				
					|  |  |  | 
 |