diff --git a/plugins/manipulator.cpp b/plugins/manipulator.cpp index 56c1f8894..119c92dc1 100644 --- a/plugins/manipulator.cpp +++ b/plugins/manipulator.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -270,11 +271,17 @@ struct UnitInfo int active_index; string squad_effective_name; string squad_info; + string job_info; }; +enum detail_cols { + DETAIL_MODE_PROFESSION, + DETAIL_MODE_SQUAD, + DETAIL_MODE_JOB +}; enum altsort_mode { ALTSORT_NAME, - ALTSORT_PROFESSION_OR_SQUAD, + ALTSORT_DETAIL, ALTSORT_STRESS, ALTSORT_ARRIVAL, ALTSORT_MAX @@ -316,6 +323,20 @@ bool sortBySquad (const UnitInfo *d1, const UnitInfo *d2) return descending ? gt : !gt; } +bool sortByJob (const UnitInfo *d1, const UnitInfo *d2) +{ + bool gt = false; + + if (d1->job_info == "Idle") + gt = false; + else if (d2->job_info == "Idle") + gt = true; + else + gt = (d1->job_info > d2->job_info); + + return descending ? gt : !gt; +} + bool sortByStress (const UnitInfo *d1, const UnitInfo *d2) { if (!d1->unit->status.current_soul) @@ -379,7 +400,7 @@ bool sortBySkill (const UnitInfo *d1, const UnitInfo *d2) enum display_columns { DISP_COLUMN_STRESS, DISP_COLUMN_NAME, - DISP_COLUMN_PROFESSION_OR_SQUAD, + DISP_COLUMN_DETAIL, DISP_COLUMN_LABORS, DISP_COLUMN_MAX, }; @@ -409,9 +430,9 @@ public: protected: vector units; altsort_mode altsort; - bool show_squad; bool do_refresh_names; + int detail_mode; int first_row, sel_row, num_rows; int first_column, sel_column; @@ -462,7 +483,7 @@ viewscreen_unitlaborsst::viewscreen_unitlaborsst(vector &src, int cur units.push_back(cur); } altsort = ALTSORT_NAME; - show_squad = false; + detail_mode = DETAIL_MODE_PROFESSION; first_column = sel_column = 0; refreshNames(); @@ -495,6 +516,12 @@ 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->job.current_job == NULL) { + cur->job_info = "Idle"; + } else { + cur->job_info = DFHack::Job::getName(unit->job.current_job); + } 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; @@ -523,8 +550,8 @@ void viewscreen_unitlaborsst::calcSize() col_maxwidth[DISP_COLUMN_STRESS] = 6; col_minwidth[DISP_COLUMN_NAME] = 16; col_maxwidth[DISP_COLUMN_NAME] = 16; // adjusted in the loop below - col_minwidth[DISP_COLUMN_PROFESSION_OR_SQUAD] = 10; - col_maxwidth[DISP_COLUMN_PROFESSION_OR_SQUAD] = 10; // adjusted in the loop below + col_minwidth[DISP_COLUMN_DETAIL] = 10; + col_maxwidth[DISP_COLUMN_DETAIL] = 10; // adjusted in the loop below col_minwidth[DISP_COLUMN_LABORS] = 1; col_maxwidth[DISP_COLUMN_LABORS] = NUM_COLUMNS; @@ -533,13 +560,17 @@ void viewscreen_unitlaborsst::calcSize() { if (col_maxwidth[DISP_COLUMN_NAME] < units[i]->name.size()) col_maxwidth[DISP_COLUMN_NAME] = units[i]->name.size(); - if (show_squad) { - if (col_maxwidth[DISP_COLUMN_PROFESSION_OR_SQUAD] < units[i]->squad_info.size()) - col_maxwidth[DISP_COLUMN_PROFESSION_OR_SQUAD] = units[i]->squad_info.size(); + + size_t detail_cmp; + if (detail_mode == DETAIL_MODE_SQUAD) { + detail_cmp = units[i]->squad_info.size(); + } else if (detail_mode == DETAIL_MODE_JOB) { + detail_cmp = units[i]->job_info.size(); } else { - if (col_maxwidth[DISP_COLUMN_PROFESSION_OR_SQUAD] < units[i]->profession.size()) - col_maxwidth[DISP_COLUMN_PROFESSION_OR_SQUAD] = units[i]->profession.size(); + detail_cmp = units[i]->profession.size(); } + if (col_maxwidth[DISP_COLUMN_DETAIL] < detail_cmp) + col_maxwidth[DISP_COLUMN_DETAIL] = detail_cmp; } // check how much room we have @@ -810,10 +841,10 @@ void viewscreen_unitlaborsst::feed(set *events) } break; - case DISP_COLUMN_PROFESSION_OR_SQUAD: + case DISP_COLUMN_DETAIL: if (enabler->mouse_lbut || enabler->mouse_rbut) { - input_sort = ALTSORT_PROFESSION_OR_SQUAD; + input_sort = ALTSORT_DETAIL; if (enabler->mouse_lbut) events->insert(interface_key::SECONDSCROLL_PAGEDOWN); if (enabler->mouse_rbut) @@ -840,7 +871,7 @@ void viewscreen_unitlaborsst::feed(set *events) break; case DISP_COLUMN_NAME: - case DISP_COLUMN_PROFESSION_OR_SQUAD: + case DISP_COLUMN_DETAIL: // left-click to view, right-click to zoom if (enabler->mouse_lbut) { @@ -938,8 +969,14 @@ void viewscreen_unitlaborsst::feed(set *events) case ALTSORT_NAME: std::stable_sort(units.begin(), units.end(), sortByName); break; - case ALTSORT_PROFESSION_OR_SQUAD: - std::stable_sort(units.begin(), units.end(), show_squad ? sortBySquad : sortByProfession); + case ALTSORT_DETAIL: + if (detail_mode == DETAIL_MODE_SQUAD) { + std::stable_sort(units.begin(), units.end(), sortBySquad); + } else if (detail_mode == DETAIL_MODE_JOB) { + std::stable_sort(units.begin(), units.end(), sortByJob); + } else { + std::stable_sort(units.begin(), units.end(), sortByProfession); + } break; case ALTSORT_STRESS: std::stable_sort(units.begin(), units.end(), sortByStress); @@ -954,9 +991,9 @@ void viewscreen_unitlaborsst::feed(set *events) switch (altsort) { case ALTSORT_NAME: - altsort = ALTSORT_PROFESSION_OR_SQUAD; + altsort = ALTSORT_DETAIL; break; - case ALTSORT_PROFESSION_OR_SQUAD: + case ALTSORT_DETAIL: altsort = ALTSORT_STRESS; break; case ALTSORT_STRESS: @@ -969,7 +1006,13 @@ void viewscreen_unitlaborsst::feed(set *events) } if (events->count(interface_key::OPTION20)) { - show_squad = !show_squad; + if (detail_mode == DETAIL_MODE_SQUAD) { + detail_mode = DETAIL_MODE_JOB; + } else if (detail_mode == DETAIL_MODE_JOB) { + detail_mode = DETAIL_MODE_PROFESSION; + } else { + detail_mode = DETAIL_MODE_SQUAD; + } } if (VIRTUAL_CAST_VAR(unitlist, df::viewscreen_unitlistst, parent)) @@ -1012,7 +1055,16 @@ void viewscreen_unitlaborsst::render() Screen::paintString(Screen::Pen(' ', 7, 0), col_offsets[DISP_COLUMN_STRESS], 2, "Stress"); Screen::paintString(Screen::Pen(' ', 7, 0), col_offsets[DISP_COLUMN_NAME], 2, "Name"); - Screen::paintString(Screen::Pen(' ', 7, 0), col_offsets[DISP_COLUMN_PROFESSION_OR_SQUAD], 2, show_squad ? "Squad" : "Profession"); + + string detail_str; + if (detail_mode == DETAIL_MODE_SQUAD) { + detail_str = "Squad"; + } else if (detail_mode == DETAIL_MODE_JOB) { + detail_str = "Job"; + } else { + detail_str = "Profession"; + } + Screen::paintString(Screen::Pen(' ', 7, 0), col_offsets[DISP_COLUMN_DETAIL], 2, detail_str); for (int col = 0; col < col_widths[DISP_COLUMN_LABORS]; col++) { @@ -1082,16 +1134,22 @@ void viewscreen_unitlaborsst::render() Screen::paintString(Screen::Pen(' ', fg, bg), col_offsets[DISP_COLUMN_NAME], 4 + row, name); bg = 0; - string profession_or_squad; - if (show_squad) { + if (detail_mode == DETAIL_MODE_SQUAD) { fg = 11; - profession_or_squad = cur->squad_info; + detail_str = cur->squad_info; + } else if (detail_mode == DETAIL_MODE_JOB) { + detail_str = cur->job_info; + if (detail_str == "Idle") { + fg = 14; + } else { + fg = 10; + } } else { fg = cur->color; - profession_or_squad = cur->profession; + detail_str = cur->profession; } - profession_or_squad.resize(col_widths[DISP_COLUMN_PROFESSION_OR_SQUAD]); - Screen::paintString(Screen::Pen(' ', fg, bg), col_offsets[DISP_COLUMN_PROFESSION_OR_SQUAD], 4 + row, profession_or_squad); + detail_str.resize(col_widths[DISP_COLUMN_DETAIL]); + Screen::paintString(Screen::Pen(' ', fg, bg), col_offsets[DISP_COLUMN_DETAIL], 4 + row, detail_str); // Print unit's skills and labor assignments for (int col = 0; col < col_widths[DISP_COLUMN_LABORS]; col++) @@ -1238,8 +1296,14 @@ void viewscreen_unitlaborsst::render() case ALTSORT_NAME: OutputString(15, x, y, "Name"); break; - case ALTSORT_PROFESSION_OR_SQUAD: - OutputString(15, x, y, show_squad ? "Squad" : "Profession"); + case ALTSORT_DETAIL: + if (detail_mode == DETAIL_MODE_SQUAD) { + OutputString(15, x, y, "Squad"); + } else if (detail_mode == DETAIL_MODE_JOB) { + OutputString(15, x, y, "Job"); + } else { + OutputString(15, x, y, "Profession"); + } break; case ALTSORT_STRESS: OutputString(15, x, y, "Stress Level");