|  |  |  | @ -248,11 +248,14 @@ struct UnitInfo | 
		
	
		
			
				|  |  |  |  |     string profession; | 
		
	
		
			
				|  |  |  |  |     int8_t color; | 
		
	
		
			
				|  |  |  |  |     int active_index; | 
		
	
		
			
				|  |  |  |  |     string squad_effective_name; | 
		
	
		
			
				|  |  |  |  |     string squad_info; | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | enum altsort_mode { | 
		
	
		
			
				|  |  |  |  |     ALTSORT_NAME, | 
		
	
		
			
				|  |  |  |  |     ALTSORT_PROFESSION, | 
		
	
		
			
				|  |  |  |  |     ALTSORT_SQUAD, | 
		
	
		
			
				|  |  |  |  |     ALTSORT_HAPPINESS, | 
		
	
		
			
				|  |  |  |  |     ALTSORT_ARRIVAL, | 
		
	
		
			
				|  |  |  |  |     ALTSORT_MAX | 
		
	
	
		
			
				
					|  |  |  | @ -278,6 +281,22 @@ bool sortByProfession (const UnitInfo *d1, const UnitInfo *d2) | 
		
	
		
			
				|  |  |  |  |         return (d1->profession < d2->profession); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | bool sortBySquad (const UnitInfo *d1, const UnitInfo *d2) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     bool gt = false; | 
		
	
		
			
				|  |  |  |  |     if (d1->unit->military.squad_id == -1 && d2->unit->military.squad_id == -1) | 
		
	
		
			
				|  |  |  |  |         gt = d1->name > d2->name; | 
		
	
		
			
				|  |  |  |  |     else if (d1->unit->military.squad_id == -1) | 
		
	
		
			
				|  |  |  |  |         gt = true; | 
		
	
		
			
				|  |  |  |  |     else if (d2->unit->military.squad_id == -1) | 
		
	
		
			
				|  |  |  |  |         gt = false; | 
		
	
		
			
				|  |  |  |  |     else if (d1->unit->military.squad_id != d2->unit->military.squad_id) | 
		
	
		
			
				|  |  |  |  |         gt = d1->squad_effective_name > d2->squad_effective_name; | 
		
	
		
			
				|  |  |  |  |     else | 
		
	
		
			
				|  |  |  |  |         gt = d1->unit->military.squad_position > d2->unit->military.squad_position; | 
		
	
		
			
				|  |  |  |  |     return descending ? gt : !gt; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | bool sortByHappiness (const UnitInfo *d1, const UnitInfo *d2) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     if (descending) | 
		
	
	
		
			
				
					|  |  |  | @ -337,6 +356,7 @@ enum display_columns { | 
		
	
		
			
				|  |  |  |  |     DISP_COLUMN_HAPPINESS, | 
		
	
		
			
				|  |  |  |  |     DISP_COLUMN_NAME, | 
		
	
		
			
				|  |  |  |  |     DISP_COLUMN_PROFESSION, | 
		
	
		
			
				|  |  |  |  |     DISP_COLUMN_SQUAD, | 
		
	
		
			
				|  |  |  |  |     DISP_COLUMN_LABORS, | 
		
	
		
			
				|  |  |  |  |     DISP_COLUMN_MAX, | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
	
		
			
				
					|  |  |  | @ -450,6 +470,13 @@ void viewscreen_unitlaborsst::refreshNames() | 
		
	
		
			
				|  |  |  |  |         cur->name = Translation::TranslateName(Units::getVisibleName(unit), false); | 
		
	
		
			
				|  |  |  |  |         cur->transname = Translation::TranslateName(Units::getVisibleName(unit), true); | 
		
	
		
			
				|  |  |  |  |         cur->profession = Units::getProfessionName(unit); | 
		
	
		
			
				|  |  |  |  |         if (unit->military.squad_id > -1) { | 
		
	
		
			
				|  |  |  |  |             cur->squad_effective_name = Units::getSquadName(unit); | 
		
	
		
			
				|  |  |  |  |             cur->squad_info = stl_sprintf("%i", unit->military.squad_position + 1) + "." + cur->squad_effective_name; | 
		
	
		
			
				|  |  |  |  |         } else { | 
		
	
		
			
				|  |  |  |  |             cur->squad_effective_name = ""; | 
		
	
		
			
				|  |  |  |  |             cur->squad_info = ""; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     calcSize(); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
	
		
			
				
					|  |  |  | @ -458,7 +485,7 @@ void viewscreen_unitlaborsst::calcSize() | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     auto dim = Screen::getWindowSize(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     num_rows = dim.y - 10; | 
		
	
		
			
				|  |  |  |  |     num_rows = dim.y - 11; | 
		
	
		
			
				|  |  |  |  |     if (num_rows > units.size()) | 
		
	
		
			
				|  |  |  |  |         num_rows = units.size(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -469,11 +496,13 @@ void viewscreen_unitlaborsst::calcSize() | 
		
	
		
			
				|  |  |  |  |     int col_maxwidth[DISP_COLUMN_MAX]; | 
		
	
		
			
				|  |  |  |  |     col_minwidth[DISP_COLUMN_HAPPINESS] = 4; | 
		
	
		
			
				|  |  |  |  |     col_maxwidth[DISP_COLUMN_HAPPINESS] = 4; | 
		
	
		
			
				|  |  |  |  |     col_minwidth[DISP_COLUMN_NAME] = 16; | 
		
	
		
			
				|  |  |  |  |     col_maxwidth[DISP_COLUMN_NAME] = 16;        // adjusted in the loop below
 | 
		
	
		
			
				|  |  |  |  |     col_minwidth[DISP_COLUMN_NAME] = 12; | 
		
	
		
			
				|  |  |  |  |     col_maxwidth[DISP_COLUMN_NAME] = 12;        // adjusted in the loop below
 | 
		
	
		
			
				|  |  |  |  |     col_minwidth[DISP_COLUMN_PROFESSION] = 10; | 
		
	
		
			
				|  |  |  |  |     col_maxwidth[DISP_COLUMN_PROFESSION] = 10;  // adjusted in the loop below
 | 
		
	
		
			
				|  |  |  |  |     col_minwidth[DISP_COLUMN_LABORS] = num_columns*3/5;     // 60%
 | 
		
	
		
			
				|  |  |  |  |     col_minwidth[DISP_COLUMN_SQUAD] = 10; | 
		
	
		
			
				|  |  |  |  |     col_maxwidth[DISP_COLUMN_SQUAD] = 10;  // adjusted in the loop below
 | 
		
	
		
			
				|  |  |  |  |     col_minwidth[DISP_COLUMN_LABORS] = num_columns / 2;     // 50%
 | 
		
	
		
			
				|  |  |  |  |     col_maxwidth[DISP_COLUMN_LABORS] = NUM_COLUMNS; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // get max_name/max_prof from strings length
 | 
		
	
	
		
			
				
					|  |  |  | @ -483,6 +512,8 @@ void viewscreen_unitlaborsst::calcSize() | 
		
	
		
			
				|  |  |  |  |             col_maxwidth[DISP_COLUMN_NAME] = units[i]->name.size(); | 
		
	
		
			
				|  |  |  |  |         if (col_maxwidth[DISP_COLUMN_PROFESSION] < units[i]->profession.size()) | 
		
	
		
			
				|  |  |  |  |             col_maxwidth[DISP_COLUMN_PROFESSION] = units[i]->profession.size(); | 
		
	
		
			
				|  |  |  |  |         if (col_maxwidth[DISP_COLUMN_SQUAD] < units[i]->squad_info.size()) | 
		
	
		
			
				|  |  |  |  |             col_maxwidth[DISP_COLUMN_SQUAD] = units[i]->squad_info.size(); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // check how much room we have
 | 
		
	
	
		
			
				
					|  |  |  | @ -764,6 +795,17 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events) | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |             break; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         case DISP_COLUMN_SQUAD: | 
		
	
		
			
				|  |  |  |  |             if (enabler->mouse_lbut || enabler->mouse_rbut) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 input_sort = ALTSORT_SQUAD; | 
		
	
		
			
				|  |  |  |  |                 if (enabler->mouse_lbut) | 
		
	
		
			
				|  |  |  |  |                     events->insert(interface_key::SECONDSCROLL_PAGEDOWN); | 
		
	
		
			
				|  |  |  |  |                 if (enabler->mouse_rbut) | 
		
	
		
			
				|  |  |  |  |                     events->insert(interface_key::SECONDSCROLL_PAGEUP); | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |             break; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         case DISP_COLUMN_LABORS: | 
		
	
		
			
				|  |  |  |  |             if (enabler->mouse_lbut || enabler->mouse_rbut) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
	
		
			
				
					|  |  |  | @ -784,6 +826,7 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         case DISP_COLUMN_NAME: | 
		
	
		
			
				|  |  |  |  |         case DISP_COLUMN_PROFESSION: | 
		
	
		
			
				|  |  |  |  |         case DISP_COLUMN_SQUAD: | 
		
	
		
			
				|  |  |  |  |             // left-click to view, right-click to zoom
 | 
		
	
		
			
				|  |  |  |  |             if (enabler->mouse_lbut) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
	
		
			
				
					|  |  |  | @ -882,6 +925,9 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events) | 
		
	
		
			
				|  |  |  |  |         case ALTSORT_PROFESSION: | 
		
	
		
			
				|  |  |  |  |             std::sort(units.begin(), units.end(), sortByProfession); | 
		
	
		
			
				|  |  |  |  |             break; | 
		
	
		
			
				|  |  |  |  |         case ALTSORT_SQUAD: | 
		
	
		
			
				|  |  |  |  |             std::sort(units.begin(), units.end(), sortBySquad); | 
		
	
		
			
				|  |  |  |  |             break; | 
		
	
		
			
				|  |  |  |  |         case ALTSORT_HAPPINESS: | 
		
	
		
			
				|  |  |  |  |             std::sort(units.begin(), units.end(), sortByHappiness); | 
		
	
		
			
				|  |  |  |  |             break; | 
		
	
	
		
			
				
					|  |  |  | @ -898,6 +944,9 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events) | 
		
	
		
			
				|  |  |  |  |             altsort = ALTSORT_PROFESSION; | 
		
	
		
			
				|  |  |  |  |             break; | 
		
	
		
			
				|  |  |  |  |         case ALTSORT_PROFESSION: | 
		
	
		
			
				|  |  |  |  |             altsort = ALTSORT_SQUAD; | 
		
	
		
			
				|  |  |  |  |             break; | 
		
	
		
			
				|  |  |  |  |         case ALTSORT_SQUAD: | 
		
	
		
			
				|  |  |  |  |             altsort = ALTSORT_HAPPINESS; | 
		
	
		
			
				|  |  |  |  |             break; | 
		
	
		
			
				|  |  |  |  |         case ALTSORT_HAPPINESS: | 
		
	
	
		
			
				
					|  |  |  | @ -950,6 +999,7 @@ void viewscreen_unitlaborsst::render() | 
		
	
		
			
				|  |  |  |  |     Screen::paintString(Screen::Pen(' ', 7, 0), col_offsets[DISP_COLUMN_HAPPINESS], 2, "Hap."); | 
		
	
		
			
				|  |  |  |  |     Screen::paintString(Screen::Pen(' ', 7, 0), col_offsets[DISP_COLUMN_NAME], 2, "Name"); | 
		
	
		
			
				|  |  |  |  |     Screen::paintString(Screen::Pen(' ', 7, 0), col_offsets[DISP_COLUMN_PROFESSION], 2, "Profession"); | 
		
	
		
			
				|  |  |  |  |     Screen::paintString(Screen::Pen(' ', 7, 0), col_offsets[DISP_COLUMN_SQUAD], 2, "Squad"); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     for (int col = 0; col < col_widths[DISP_COLUMN_LABORS]; col++) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
	
		
			
				
					|  |  |  | @ -1025,6 +1075,11 @@ void viewscreen_unitlaborsst::render() | 
		
	
		
			
				|  |  |  |  |         bg = 0; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         Screen::paintString(Screen::Pen(' ', fg, bg), col_offsets[DISP_COLUMN_PROFESSION], 4 + row, profession); | 
		
	
		
			
				|  |  |  |  |          | 
		
	
		
			
				|  |  |  |  |         fg = 15; | 
		
	
		
			
				|  |  |  |  |         string squad = cur->squad_info; | 
		
	
		
			
				|  |  |  |  |         squad.resize(col_widths[DISP_COLUMN_SQUAD]); | 
		
	
		
			
				|  |  |  |  |         Screen::paintString(Screen::Pen(' ', fg, bg), col_offsets[DISP_COLUMN_SQUAD], 4 + row, squad); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         // Print unit's skills and labor assignments
 | 
		
	
		
			
				|  |  |  |  |         for (int col = 0; col < col_widths[DISP_COLUMN_LABORS]; col++) | 
		
	
	
		
			
				
					|  |  |  | @ -1114,7 +1169,25 @@ void viewscreen_unitlaborsst::render() | 
		
	
		
			
				|  |  |  |  |             else | 
		
	
		
			
				|  |  |  |  |                 str = stl_sprintf("Not %s (0/500)", ENUM_ATTR_STR(job_skill, caption_noun, columns[sel_column].skill)); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         Screen::paintString(Screen::Pen(' ', 9, 0), x, 3 + num_rows + 2, str); | 
		
	
		
			
				|  |  |  |  |         Screen::paintString(Screen::Pen(' ', 9, 0), x, y, str); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         if (cur->unit->military.squad_id > -1) { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             x = 1; | 
		
	
		
			
				|  |  |  |  |             y++; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             string squadLabel = "Squad: "; | 
		
	
		
			
				|  |  |  |  |             Screen::paintString(white_pen, x, y, squadLabel); | 
		
	
		
			
				|  |  |  |  |             x += squadLabel.size(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             string squad = cur->squad_effective_name; | 
		
	
		
			
				|  |  |  |  |             Screen::paintString(Screen::Pen(' ', 11, 0), x, y, squad); | 
		
	
		
			
				|  |  |  |  |             x += squad.size(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             string pos = stl_sprintf(" Pos %i", cur->unit->military.squad_position + 1); | 
		
	
		
			
				|  |  |  |  |             Screen::paintString(Screen::Pen(' ', 9, 0), x, y, pos); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         canToggle = (cur->allowEdit) && (columns[sel_column].labor != unit_labor::NONE); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
	
		
			
				
					|  |  |  | @ -1153,6 +1226,9 @@ void viewscreen_unitlaborsst::render() | 
		
	
		
			
				|  |  |  |  |     case ALTSORT_PROFESSION: | 
		
	
		
			
				|  |  |  |  |         OutputString(15, x, y, "Profession"); | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |     case ALTSORT_SQUAD: | 
		
	
		
			
				|  |  |  |  |         OutputString(15, x, y, "Squad"); | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |     case ALTSORT_HAPPINESS: | 
		
	
		
			
				|  |  |  |  |         OutputString(15, x, y, "Happiness"); | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
	
		
			
				
					|  |  |  | 
 |