@ -11,6 +11,7 @@
# include <vector>
# include <vector>
# include <string>
# include <string>
# include <set>
# include <set>
# include <algorithm>
# include <VTableInterpose.h>
# include <VTableInterpose.h>
# include "df/world.h"
# include "df/world.h"
@ -22,6 +23,7 @@
# include "df/unit.h"
# include "df/unit.h"
# include "df/unit_soul.h"
# include "df/unit_soul.h"
# include "df/unit_skill.h"
# include "df/unit_skill.h"
# include "df/creature_graphics_role.h"
# include "df/creature_raw.h"
# include "df/creature_raw.h"
# include "df/caste_raw.h"
# include "df/caste_raw.h"
@ -37,8 +39,6 @@ using df::global::ui;
using df : : global : : gps ;
using df : : global : : gps ;
using df : : global : : enabler ;
using df : : global : : enabler ;
DFHACK_PLUGIN ( " manipulator " ) ;
struct SkillLevel
struct SkillLevel
{
{
const char * name ;
const char * name ;
@ -75,166 +75,168 @@ const SkillLevel skill_levels[] = {
struct SkillColumn
struct SkillColumn
{
{
df : : profession profession ;
int group ; // for navigation and mass toggling
df : : unit_labor labor ;
int8_t color ; // for column headers
df : : job_skill skill ;
df : : profession profession ; // to display graphical tiles
char label [ 3 ] ;
df : : unit_labor labor ; // toggled when pressing Enter
df : : job_skill skill ; // displayed rating
char label [ 3 ] ; // column header
bool special ; // specified labor is mutually exclusive with all other special labors
bool special ; // specified labor is mutually exclusive with all other special labors
} ;
} ;
# define NUM_COLUMNS (sizeof(columns) / sizeof(SkillColumn))
# define NUM_COLUMNS (sizeof(columns) / sizeof(SkillColumn))
// All of the skill/labor columns we want to display. Includes profession (for color), labor, skill, and 2 character label
// All of the skill/labor columns we want to display.
const SkillColumn columns [ ] = {
const SkillColumn columns [ ] = {
// Mining
// Mining
{ profession : : MINER , unit_labor : : MINE , job_skill : : MINING , " Mi " , true } ,
{ 0 , 7 , profession : : MINER , unit_labor : : MINE , job_skill : : MINING , " Mi " , true } ,
// Woodworking
// Woodworking
{ profession : : WOODWORK ER, unit_labor : : CARPENTER , job_skill : : CARPENTRY , " Ca " } ,
{ 1 , 14 , profession : : CARPENT ER, unit_labor : : CARPENTER , job_skill : : CARPENTRY , " Ca " } ,
{ profession : : WOODWORK ER, unit_labor : : BOWYER , job_skill : : BOWYER , " Bw " } ,
{ 1 , 14 , profession : : BOWY ER, unit_labor : : BOWYER , job_skill : : BOWYER , " Bw " } ,
{ profession : : WOODWORK ER, unit_labor : : CUTWOOD , job_skill : : WOODCUTTING , " WC " , true } ,
{ 1 , 14 , profession : : WOODCUTT ER, unit_labor : : CUTWOOD , job_skill : : WOODCUTTING , " WC " , true } ,
// Stoneworking
// Stoneworking
{ profession : : ST ONEWORKER , unit_labor : : MASON , job_skill : : MASONRY , " Ma " } ,
{ 2 , 15 , profession : : MA SON, unit_labor : : MASON , job_skill : : MASONRY , " Ma " } ,
{ profession : : STONEWORK ER, unit_labor : : DETAIL , job_skill : : DETAILSTONE , " En " } ,
{ 2 , 15 , profession : : ENGRAV ER, unit_labor : : DETAIL , job_skill : : DETAILSTONE , " En " } ,
// Hunting/Related
// Hunting/Related
{ profession : : RANG ER, unit_labor : : ANIMALTRAIN , job_skill : : ANIMALTRAIN , " T r " } ,
{ 3 , 2 , profession : : ANIMAL_T RAI NER, unit_labor : : ANIMALTRAIN , job_skill : : ANIMALTRAIN , " T n " } ,
{ profession : : RANG ER, unit_labor : : ANIMALCARE , job_skill : : ANIMALCARE , " Ca " } ,
{ 3 , 2 , profession : : ANIMAL_CARETAK ER, unit_labor : : ANIMALCARE , job_skill : : ANIMALCARE , " Ca " } ,
{ profession : : RANG ER, unit_labor : : HUNT , job_skill : : SNEAK , " Hu " , true } ,
{ 3 , 2 , profession : : HUNT ER, unit_labor : : HUNT , job_skill : : SNEAK , " Hu " , true } ,
{ profession : : RANG ER, unit_labor : : TRAPPER , job_skill : : TRAPPING , " Tr " } ,
{ 3 , 2 , profession : : TRAPP ER, unit_labor : : TRAPPER , job_skill : : TRAPPING , " Tr " } ,
{ profession : : RANGE R, unit_labor : : DISSECT_VERMIN , job_skill : : DISSECT_VERMIN , " Di " } ,
{ 3 , 2 , profession : : ANIMAL_DISSECTO R, unit_labor : : DISSECT_VERMIN , job_skill : : DISSECT_VERMIN , " Di " } ,
// Healthcare
// Healthcare
{ profession : : DOCTO R, unit_labor : : DIAGNOSE , job_skill : : DIAGNOSE , " Di " } ,
{ 4 , 5 , profession : : DIAGNOSE R, unit_labor : : DIAGNOSE , job_skill : : DIAGNOSE , " Di " } ,
{ profession : : DOCTOR , unit_labor : : SURGERY , job_skill : : SURGERY , " Su " } ,
{ 4 , 5 , profession : : SURGEON , unit_labor : : SURGERY , job_skill : : SURGERY , " Su " } ,
{ profession : : DOCTO R, unit_labor : : BONE_SETTING , job_skill : : SET_BONE , " Bo " } ,
{ 4 , 5 , profession : : BONE_SETTE R, unit_labor : : BONE_SETTING , job_skill : : SET_BONE , " Bo " } ,
{ profession : : DOCTO R, unit_labor : : SUTURING , job_skill : : SUTURE , " St " } ,
{ 4 , 5 , profession : : SUTURE R, unit_labor : : SUTURING , job_skill : : SUTURE , " St " } ,
{ profession : : DOCTOR , unit_labor : : DRESSING_WOUNDS , job_skill : : DRESS_WOUNDS , " Dr " } ,
{ 4 , 5 , profession : : DOCTOR , unit_labor : : DRESSING_WOUNDS , job_skill : : DRESS_WOUNDS , " Dr " } ,
{ profession : : DOCTOR , unit_labor : : FEED_WATER_CIVILIANS , job_skill : : NONE , " Fd " } ,
{ 4 , 5 , profession : : NONE , unit_labor : : FEED_WATER_CIVILIANS , job_skill : : NONE , " Fd " } ,
{ profession : : DOCTOR , unit_labor : : RECOVER_WOUNDED , job_skill : : NONE , " Re " } ,
{ 4 , 5 , profession : : NONE , unit_labor : : RECOVER_WOUNDED , job_skill : : NONE , " Re " } ,
// Farming/Related
// Farming/Related
{ profession : : FARM ER, unit_labor : : BUTCHER , job_skill : : BUTCHER , " Bu " } ,
{ 5 , 6 , profession : : BUTCH ER, unit_labor : : BUTCHER , job_skill : : BUTCHER , " Bu " } ,
{ profession : : FARM ER, unit_labor : : TANNER , job_skill : : TANNER , " Ta " } ,
{ 5 , 6 , profession : : TANN ER, unit_labor : : TANNER , job_skill : : TANNER , " Ta " } ,
{ profession : : FARM ER, unit_labor : : PLANT , job_skill : : PLANT , " Gr " } ,
{ 5 , 6 , profession : : PLANT ER, unit_labor : : PLANT , job_skill : : PLANT , " Gr " } ,
{ profession : : FARM ER, unit_labor : : DYER , job_skill : : DYER , " Dy " } ,
{ 5 , 6 , profession : : DY ER, unit_labor : : DYER , job_skill : : DYER , " Dy " } ,
{ profession : : FARM ER, unit_labor : : SOAP_MAKER , job_skill : : SOAP_MAKING , " So " } ,
{ 5 , 6 , profession : : SOAP_MAK ER, unit_labor : : SOAP_MAKER , job_skill : : SOAP_MAKING , " So " } ,
{ profession : : FARM ER, unit_labor : : BURN_WOOD , job_skill : : WOOD_BURNING , " WB " } ,
{ 5 , 6 , profession : : WOOD_BURN ER, unit_labor : : BURN_WOOD , job_skill : : WOOD_BURNING , " WB " } ,
{ profession : : FARM ER, unit_labor : : POTASH_MAKING , job_skill : : POTASH_MAKING , " Po " } ,
{ 5 , 6 , profession : : POTASH_MAK ER, unit_labor : : POTASH_MAKING , job_skill : : POTASH_MAKING , " Po " } ,
{ profession : : FARM ER, unit_labor : : LYE_MAKING , job_skill : : LYE_MAKING , " Ly " } ,
{ 5 , 6 , profession : : LYE_MAK ER, unit_labor : : LYE_MAKING , job_skill : : LYE_MAKING , " Ly " } ,
{ profession : : FAR MER, unit_labor : : MILLER , job_skill : : MILLING , " Ml " } ,
{ 5 , 6 , profession : : MILL ER, unit_labor : : MILLER , job_skill : : MILLING , " Ml " } ,
{ profession : : FARM ER, unit_labor : : BREWER , job_skill : : BREWING , " Br " } ,
{ 5 , 6 , profession : : BREW ER, unit_labor : : BREWER , job_skill : : BREWING , " Br " } ,
{ profession : : FARMER , unit_labor : : HERBALIST , job_skill : : HERBALISM , " He " } ,
{ 5 , 6 , profession : : HERBALIST , unit_labor : : HERBALIST , job_skill : : HERBALISM , " He " } ,
{ profession : : FARM ER, unit_labor : : PROCESS_PLANT , job_skill : : PROCESSPLANTS , " Th " } ,
{ 5 , 6 , profession : : THRESH ER, unit_labor : : PROCESS_PLANT , job_skill : : PROCESSPLANTS , " Th " } ,
{ profession : : FARM ER, unit_labor : : MAKE_CHEESE , job_skill : : CHEESEMAKING , " Ch " } ,
{ 5 , 6 , profession : : CHEESE_MAK ER, unit_labor : : MAKE_CHEESE , job_skill : : CHEESEMAKING , " Ch " } ,
{ profession : : FAR MER, unit_labor : : MILK , job_skill : : MILK , " Mk " } ,
{ 5 , 6 , profession : : MILK ER, unit_labor : : MILK , job_skill : : MILK , " Mk " } ,
{ profession : : FARM ER, unit_labor : : SHEARER , job_skill : : SHEARING , " Sh " } ,
{ 5 , 6 , profession : : SHEAR ER, unit_labor : : SHEARER , job_skill : : SHEARING , " Sh " } ,
{ profession : : FARM ER, unit_labor : : SPINNER , job_skill : : SPINNING , " Sp " } ,
{ 5 , 6 , profession : : SPINN ER, unit_labor : : SPINNER , job_skill : : SPINNING , " Sp " } ,
{ profession : : FARMER , unit_labor : : COOK , job_skill : : COOK , " Co " } ,
{ 5 , 6 , profession : : COOK , unit_labor : : COOK , job_skill : : COOK , " Co " } ,
{ profession : : FARM ER, unit_labor : : PRESSING , job_skill : : PRESSING , " Pr " } ,
{ 5 , 6 , profession : : PRESS ER, unit_labor : : PRESSING , job_skill : : PRESSING , " Pr " } ,
{ profession : : FARM ER, unit_labor : : BEEKEEPING , job_skill : : BEEKEEPING , " Be " } ,
{ 5 , 6 , profession : : BEEKEEP ER, unit_labor : : BEEKEEPING , job_skill : : BEEKEEPING , " Be " } ,
// Fishing/Related
// Fishing/Related
{ profession : : FISHERMAN , unit_labor : : FISH , job_skill : : FISH , " Fi " } ,
{ 6 , 1 , profession : : FISHERMAN , unit_labor : : FISH , job_skill : : FISH , " Fi " } ,
{ profession : : FISH ERM AN, unit_labor : : CLEAN_FISH , job_skill : : PROCESSFISH , " Cl " } ,
{ 6 , 1 , profession : : FISH _CL EANER , unit_labor : : CLEAN_FISH , job_skill : : PROCESSFISH , " Cl " } ,
{ profession : : FISH ERMAN , unit_labor : : DISSECT_FISH , job_skill : : DISSECT_FISH , " Di " } ,
{ 6 , 1 , profession : : FISH _DISS ECTO R, unit_labor : : DISSECT_FISH , job_skill : : DISSECT_FISH , " Di " } ,
// Metalsmithing
// Metalsmithing
{ profession : : METALSMITH , unit_labor : : SMELT , job_skill : : SMELT , " Fu " } ,
{ 7 , 8 , profession : : FURNACE_OPERATOR , unit_labor : : SMELT , job_skill : : SMELT , " Fu " } ,
{ profession : : METAL SMITH, unit_labor : : FORGE_WEAPON , job_skill : : FORGE_WEAPON , " We " } ,
{ 7 , 8 , profession : : WEAPON SMITH, unit_labor : : FORGE_WEAPON , job_skill : : FORGE_WEAPON , " We " } ,
{ profession : : METALSMITH , unit_labor : : FORGE_ARMOR , job_skill : : FORGE_ARMOR , " Ar " } ,
{ 7 , 8 , profession : : ARMORER , unit_labor : : FORGE_ARMOR , job_skill : : FORGE_ARMOR , " Ar " } ,
{ profession : : METAL SMITH, unit_labor : : FORGE_FURNITURE , job_skill : : FORGE_FURNITURE , " Bl " } ,
{ 7 , 8 , profession : : BLACK SMITH, unit_labor : : FORGE_FURNITURE , job_skill : : FORGE_FURNITURE , " Bl " } ,
{ profession : : METALSMITH , unit_labor : : METAL_CRAFT , job_skill : : METALCRAFT , " Cr " } ,
{ 7 , 8 , profession : : METALCRAFTER , unit_labor : : METAL_CRAFT , job_skill : : METALCRAFT , " Cr " } ,
// Jewelry
// Jewelry
{ profession : : JEWEL ER, unit_labor : : CUT_GEM , job_skill : : CUTGEM , " Cu " } ,
{ 8 , 10 , profession : : GEM_CUTT ER, unit_labor : : CUT_GEM , job_skill : : CUTGEM , " Cu " } ,
{ profession : : JEWEL ER, unit_labor : : ENCRUST_GEM , job_skill : : ENCRUSTGEM , " Se " } ,
{ 8 , 10 , profession : : GEM_SETT ER, unit_labor : : ENCRUST_GEM , job_skill : : ENCRUSTGEM , " Se " } ,
// Crafts
// Crafts
{ profession : : CRAFTSMAN , unit_labor : : LEATHER , job_skill : : LEATHERWORK , " Le " } ,
{ 9 , 9 , profession : : LEATHERWORKER , unit_labor : : LEATHER , job_skill : : LEATHERWORK , " Le " } ,
{ profession : : CRAFTSMAN , unit_labor : : WOOD_CRAFT , job_skill : : WOODCRAFT , " Wo " } ,
{ 9 , 9 , profession : : WOODCRAFTER , unit_labor : : WOOD_CRAFT , job_skill : : WOODCRAFT , " Wo " } ,
{ profession : : CRAFTSMAN , unit_labor : : STONE_CRAFT , job_skill : : STONECRAFT , " St " } ,
{ 9 , 9 , profession : : STONECRAFTER , unit_labor : : STONE_CRAFT , job_skill : : STONECRAFT , " St " } ,
{ profession : : CRAFTSMAN , unit_labor : : BONE_CARVE , job_skill : : BONECARVE , " Bo " } ,
{ 9 , 9 , profession : : BONE_ CARVE R, unit_labor : : BONE_CARVE , job_skill : : BONECARVE , " Bo " } ,
{ profession : : CRAFTSMAN , unit_labor : : GLASSMAKER , job_skill : : GLASSMAKER , " Gl " } ,
{ 9 , 9 , profession : : GLASSMAKER , unit_labor : : GLASSMAKER , job_skill : : GLASSMAKER , " Gl " } ,
{ profession : : CRAFTSMAN , unit_labor : : WEAVER , job_skill : : WEAVING , " We " } ,
{ 9 , 9 , profession : : WEAVER , unit_labor : : WEAVER , job_skill : : WEAVING , " We " } ,
{ profession : : C RAFTSMAN , unit_labor : : CLOTHESMAKER , job_skill : : CLOTHESMAKING , " Cl " } ,
{ 9 , 9 , profession : : C LOTHIE R, unit_labor : : CLOTHESMAKER , job_skill : : CLOTHESMAKING , " Cl " } ,
{ profession : : CRAFTSMAN , unit_labor : : EXTRACT_STRAND , job_skill : : EXTRACT_STRAND , " Ad " } ,
{ 9 , 9 , profession : : STRAND_EXTRACTOR , unit_labor : : EXTRACT_STRAND , job_skill : : EXTRACT_STRAND , " Ad " } ,
{ profession : : CRAFTSMAN , unit_labor : : POTTERY , job_skill : : POTTERY , " Po " } ,
{ 9 , 9 , profession : : POTTER , unit_labor : : POTTERY , job_skill : : POTTERY , " Po " } ,
{ profession : : CRAFTSMAN , unit_labor : : GLAZING , job_skill : : GLAZING , " Gl " } ,
{ 9 , 9 , profession : : GLAZER , unit_labor : : GLAZING , job_skill : : GLAZING , " Gl " } ,
{ profession : : CRAFTSMAN , unit_labor : : WAX_WORKING , job_skill : : WAX_WORKING , " Wx " } ,
{ 9 , 9 , profession : : WAX_WORKER , unit_labor : : WAX_WORKING , job_skill : : WAX_WORKING , " Wx " } ,
// Engineering
// Engineering
{ profession : : ENGINEER, unit_labor : : SIEGECRAFT , job_skill : : SIEGECRAFT , " En " } ,
{ 10 , 12 , profession : : SIEGE_ ENGINEER, unit_labor : : SIEGECRAFT , job_skill : : SIEGECRAFT , " En " } ,
{ profession : : EN GIN EER, unit_labor : : SIEGEOPERATE , job_skill : : SIEGEOPERATE , " Op " } ,
{ 10 , 12 , profession : : SI EGE_OP ERATO R, unit_labor : : SIEGEOPERATE , job_skill : : SIEGEOPERATE , " Op " } ,
{ profession : : ENGINEER , unit_labor : : MECHANIC , job_skill : : MECHANICS , " Me " } ,
{ 10 , 12 , profession : : MECHANIC , unit_labor : : MECHANIC , job_skill : : MECHANICS , " Me " } ,
{ profession : : ENGINEE R, unit_labor : : OPERATE_PUMP , job_skill : : OPERATE_PUMP , " Pu " } ,
{ 10 , 12 , profession : : PUMP_OPERATO R, unit_labor : : OPERATE_PUMP , job_skill : : OPERATE_PUMP , " Pu " } ,
// Hauling
// Hauling
{ profession : : STANDARD , unit_labor : : HAUL_STONE , job_skill : : NONE , " St " } ,
{ 11 , 3 , profession : : NONE , unit_labor : : HAUL_STONE , job_skill : : NONE , " St " } ,
{ profession : : STANDARD , unit_labor : : HAUL_WOOD , job_skill : : NONE , " Wo " } ,
{ 11 , 3 , profession : : NONE , unit_labor : : HAUL_WOOD , job_skill : : NONE , " Wo " } ,
{ profession : : STANDARD , unit_labor : : HAUL_ITEM , job_skill : : NONE , " It " } ,
{ 11 , 3 , profession : : NONE , unit_labor : : HAUL_ITEM , job_skill : : NONE , " It " } ,
{ profession : : STANDARD , unit_labor : : HAUL_BODY , job_skill : : NONE , " Bu " } ,
{ 11 , 3 , profession : : NONE , unit_labor : : HAUL_BODY , job_skill : : NONE , " Bu " } ,
{ profession : : STANDARD , unit_labor : : HAUL_FOOD , job_skill : : NONE , " Fo " } ,
{ 11 , 3 , profession : : NONE , unit_labor : : HAUL_FOOD , job_skill : : NONE , " Fo " } ,
{ profession : : STANDARD , unit_labor : : HAUL_REFUSE , job_skill : : NONE , " Re " } ,
{ 11 , 3 , profession : : NONE , unit_labor : : HAUL_REFUSE , job_skill : : NONE , " Re " } ,
{ profession : : STANDARD , unit_labor : : HAUL_FURNITURE , job_skill : : NONE , " Fu " } ,
{ 11 , 3 , profession : : NONE , unit_labor : : HAUL_FURNITURE , job_skill : : NONE , " Fu " } ,
{ profession : : STANDARD , unit_labor : : HAUL_ANIMAL , job_skill : : NONE , " An " } ,
{ 11 , 3 , profession : : NONE , unit_labor : : HAUL_ANIMAL , job_skill : : NONE , " An " } ,
{ profession : : STANDARD , unit_labor : : PUSH_HAUL_VEHICLE , job_skill : : NONE , " Ve " } ,
{ 11 , 3 , profession : : NONE , unit_labor : : PUSH_HAUL_VEHICLE , job_skill : : NONE , " Ve " } ,
// Other Jobs
// Other Jobs
{ profession : : CHILD , unit_labor : : ARCHITECT , job_skill : : DESIGNBUILDING , " Ar " } ,
{ 12 , 4 , profession : : ARCHITECT , unit_labor : : ARCHITECT , job_skill : : DESIGNBUILDING , " Ar " } ,
{ profession : : CHILD , unit_labor : : ALCHEMIST , job_skill : : ALCHEMY , " Al " } ,
{ 12 , 4 , profession : : ALCHEMIST , unit_labor : : ALCHEMIST , job_skill : : ALCHEMY , " Al " } ,
{ profession : : CHILD , unit_labor : : CLEAN , job_skill : : NONE , " Cl " } ,
{ 12 , 4 , profession : : NONE , unit_labor : : CLEAN , job_skill : : NONE , " Cl " } ,
// Military
// Military - Weapons
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : WRESTLING , " Wr " } ,
{ 13 , 7 , profession : : WRESTLER , unit_labor : : NONE , job_skill : : WRESTLING , " Wr " } ,
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : AXE , " Ax " } ,
{ 13 , 7 , profession : : AXEMAN , unit_labor : : NONE , job_skill : : AXE , " Ax " } ,
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : SWORD , " Sw " } ,
{ 13 , 7 , profession : : SWORDSMAN , unit_labor : : NONE , job_skill : : SWORD , " Sw " } ,
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : MACE , " Mc " } ,
{ 13 , 7 , profession : : MACEMAN , unit_labor : : NONE , job_skill : : MACE , " Mc " } ,
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : HAMMER , " Ha " } ,
{ 13 , 7 , profession : : HAMMERMAN , unit_labor : : NONE , job_skill : : HAMMER , " Ha " } ,
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : SPEAR , " Sp " } ,
{ 13 , 7 , profession : : SPEARMAN , unit_labor : : NONE , job_skill : : SPEAR , " Sp " } ,
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : DAGGER, " Kn " } ,
{ 13 , 7 , profession : : CROSSBOWMAN , unit_labor : : NONE , job_skill : : CROSSBOW, " Cb " } ,
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : CROSSBOW, " Cb " } ,
{ 13 , 7 , profession : : THIEF , unit_labor : : NONE , job_skill : : DAGGER, " Kn " } ,
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : BOW , " Bo " } ,
{ 13 , 7 , profession : : BOWMAN , unit_labor : : NONE , job_skill : : BOW , " Bo " } ,
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : BLOWGUN , " Bl " } ,
{ 13 , 7 , profession : : BLOWGUNMAN , unit_labor : : NONE , job_skill : : BLOWGUN , " Bl " } ,
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : PIKE , " Pk " } ,
{ 13 , 7 , profession : : PIKEMAN , unit_labor : : NONE , job_skill : : PIKE , " Pk " } ,
{ profession : : WREST LER, unit_labor : : NONE , job_skill : : WHIP , " La " } ,
{ 13 , 7 , profession : : LASH ER, unit_labor : : NONE , job_skill : : WHIP , " La " } ,
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : ARMOR , " Ar " } ,
// Military - Other Combat
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : SHIELD, " Sh " } ,
{ 14 , 15 , profession : : NONE , unit_labor : : NONE , job_skill : : BITE, " Bi " } ,
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : BITE, " Bi " } ,
{ 14 , 15 , profession : : NONE , unit_labor : : NONE , job_skill : : GRASP_STRIKE, " St " } ,
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : GRASP_STRIKE, " Pu " } ,
{ 14 , 15 , profession : : NONE , unit_labor : : NONE , job_skill : : STANCE_STRIKE, " Ki " } ,
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : STANCE_STRIKE, " K i" } ,
{ 14 , 15 , profession : : NONE , unit_labor : : NONE , job_skill : : MISC_WEAPON, " M i" } ,
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : DODGING, " Do " } ,
{ 14 , 15 , profession : : NONE , unit_labor : : NONE , job_skill : : MELEE_COMBAT, " Fg " } ,
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : MISC_WEAPON, " Mi " } ,
{ 14 , 15 , profession : : NONE , unit_labor : : NONE , job_skill : : RANGED_COMBAT, " Ac " } ,
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : MELEE_COMBAT, " Fi " } ,
{ 14 , 15 , profession : : NONE , unit_labor : : NONE , job_skill : : ARMOR, " Ar " } ,
{ profession : : WRESTLER , unit_labor : : NONE , job_skill : : RANGED_COMBAT, " Ar " } ,
{ 14 , 15 , profession : : NONE , unit_labor : : NONE , job_skill : : SHIELD, " Sh " } ,
{ 14 , 15 , profession : : NONE , unit_labor : : NONE , job_skill : : DODGING , " Do " } ,
{ profession : : RECRUIT , unit_labor : : NONE , job_skill : : LEADERSHIP , " Le " } ,
// Military - Misc
{ profession : : RECRUIT , unit_labor : : NONE , job_skill : : TEACHING, " Te " } ,
{ 15 , 8 , profession : : NONE , unit_labor : : NONE , job_skill : : LEADERSHIP, " Ld " } ,
{ profession : : RECRUIT , unit_labor : : NONE , job_skill : : KNOWLEDGE_ACQUISITION, " Lr " } ,
{ 15 , 8 , profession : : NONE , unit_labor : : NONE , job_skill : : TEACHING, " Te " } ,
{ profession : : RECRUIT , unit_labor : : NONE , job_skill : : DISCIPLINE, " Di " } ,
{ 15 , 8 , profession : : NONE , unit_labor : : NONE , job_skill : : KNOWLEDGE_ACQUISITION, " St " } ,
{ profession : : RECRUIT , unit_labor : : NONE , job_skill : : CONCENTRATION, " Co " } ,
{ 15 , 8 , profession : : NONE , unit_labor : : NONE , job_skill : : DISCIPLINE, " Di " } ,
{ profession : : RECRUIT , unit_labor : : NONE , job_skill : : SITUATIONAL_AWARENESS, " Aw " } ,
{ 15 , 8 , profession : : NONE , unit_labor : : NONE , job_skill : : CONCENTRATION, " Co " } ,
{ profession : : RECRUIT , unit_labor : : NONE , job_skill : : COORDINATION, " Cr " } ,
{ 15 , 8 , profession : : NONE , unit_labor : : NONE , job_skill : : SITUATIONAL_AWARENESS, " Ob " } ,
{ profession : : RECRUIT , unit_labor : : NONE , job_skill : : BALANCE, " Ba " } ,
{ 15 , 8 , profession : : NONE , unit_labor : : NONE , job_skill : : COORDINATION, " Cr " } ,
{ 15 , 8 , profession : : NONE , unit_labor : : NONE , job_skill : : BALANCE , " Ba " } ,
// Social
// Social
{ profession : : STANDARD , unit_labor : : NONE , job_skill : : PERSUASION , " Pe " } ,
{ 16 , 3 , profession : : NONE , unit_labor : : NONE , job_skill : : PERSUASION , " Pe " } ,
{ profession : : STANDARD , unit_labor : : NONE , job_skill : : NEGOTIATION , " Ne " } ,
{ 16 , 3 , profession : : NONE , unit_labor : : NONE , job_skill : : NEGOTIATION , " Ne " } ,
{ profession : : STANDARD , unit_labor : : NONE , job_skill : : JUDGING_INTENT , " Ju " } ,
{ 16 , 3 , profession : : NONE , unit_labor : : NONE , job_skill : : JUDGING_INTENT , " Ju " } ,
{ profession : : STANDARD , unit_labor : : NONE , job_skill : : LYING , " L y " } ,
{ 16 , 3 , profession : : NONE , unit_labor : : NONE , job_skill : : LYING , " L i " } ,
{ profession : : STANDARD , unit_labor : : NONE , job_skill : : INTIMIDATION , " In " } ,
{ 16 , 3 , profession : : NONE , unit_labor : : NONE , job_skill : : INTIMIDATION , " In " } ,
{ profession : : STANDARD , unit_labor : : NONE , job_skill : : CONVERSATION , " Cn " } ,
{ 16 , 3 , profession : : NONE , unit_labor : : NONE , job_skill : : CONVERSATION , " Cn " } ,
{ profession : : STANDARD , unit_labor : : NONE , job_skill : : COMEDY , " Cm " } ,
{ 16 , 3 , profession : : NONE , unit_labor : : NONE , job_skill : : COMEDY , " Cm " } ,
{ profession : : STANDARD , unit_labor : : NONE , job_skill : : FLATTERY , " Fl " } ,
{ 16 , 3 , profession : : NONE , unit_labor : : NONE , job_skill : : FLATTERY , " Fl " } ,
{ profession : : STANDARD , unit_labor : : NONE , job_skill : : CONSOLE , " Cs " } ,
{ 16 , 3 , profession : : NONE , unit_labor : : NONE , job_skill : : CONSOLE , " Cs " } ,
{ profession : : STANDARD , unit_labor : : NONE , job_skill : : PACIFY , " Pc " } ,
{ 16 , 3 , profession : : NONE , unit_labor : : NONE , job_skill : : PACIFY , " Pc " } ,
{ profession : : ADMINISTRATOR , unit_labor : : NONE , job_skill : : APPRAISAL , " Ap " } ,
// Noble
{ profession : : ADMINISTRATO R, unit_labor : : NONE , job_skill : : ORGANIZATION, " Or " } ,
{ 17 , 5 , profession : : TRADE R, unit_labor : : NONE , job_skill : : APPRAISAL, " Ap " } ,
{ profession : : ADMINISTRATOR , unit_labor : : NONE , job_skill : : RECORD_KEEPING, " RK " } ,
{ 17 , 5 , profession : : ADMINISTRATOR , unit_labor : : NONE , job_skill : : ORGANIZATION, " Or " } ,
{ 17 , 5 , profession : : CLERK , unit_labor : : NONE , job_skill : : RECORD_KEEPING , " RK " } ,
// Miscellaneous
// Miscellaneous
{ profession : : STANDARD , unit_labor : : NONE , job_skill : : THROW , " Th " } ,
{ 18 , 3 , profession : : NONE , unit_labor : : NONE , job_skill : : THROW , " Th " } ,
{ profession : : STANDARD , unit_labor : : NONE , job_skill : : CRUTCH_WALK , " CW " } ,
{ 18 , 3 , profession : : NONE , unit_labor : : NONE , job_skill : : CRUTCH_WALK , " CW " } ,
{ profession : : STANDARD , unit_labor : : NONE , job_skill : : SWIMMING , " Sw " } ,
{ 18 , 3 , profession : : NONE , unit_labor : : NONE , job_skill : : SWIMMING , " Sw " } ,
{ profession : : STANDARD , unit_labor : : NONE , job_skill : : KNAPPING , " Kn " } ,
{ 18 , 3 , profession : : NONE , unit_labor : : NONE , job_skill : : KNAPPING , " Kn " } ,
{ profession : : DRUNK , unit_labor : : NONE , job_skill : : WRITING , " Wr " } ,
{ 19 , 6 , profession : : NONE , unit_labor : : NONE , job_skill : : WRITING , " Wr " } ,
{ profession : : DRUNK , unit_labor : : NONE , job_skill : : PROSE , " Pr " } ,
{ 19 , 6 , profession : : NONE , unit_labor : : NONE , job_skill : : PROSE , " Pr " } ,
{ profession : : DRUNK , unit_labor : : NONE , job_skill : : POETRY , " Po " } ,
{ 19 , 6 , profession : : NONE , unit_labor : : NONE , job_skill : : POETRY , " Po " } ,
{ profession : : DRUNK , unit_labor : : NONE , job_skill : : READING , " Rd " } ,
{ 19 , 6 , profession : : NONE , unit_labor : : NONE , job_skill : : READING , " Rd " } ,
{ profession : : DRUNK , unit_labor : : NONE , job_skill : : SPEAKING , " Sp " } ,
{ 19 , 6 , profession : : NONE , unit_labor : : NONE , job_skill : : SPEAKING , " Sp " } ,
{ profession : : ADMINISTRATOR , unit_labor : : NONE , job_skill : : MILITARY_TACTICS , " MT " } ,
{ 20 , 5 , profession : : NONE , unit_labor : : NONE , job_skill : : MILITARY_TACTICS , " MT " } ,
{ profession : : ADMINISTRATOR , unit_labor : : NONE , job_skill : : TRACKING , " Tr " } ,
{ 20 , 5 , profession : : NONE , unit_labor : : NONE , job_skill : : TRACKING , " Tr " } ,
{ profession : : ADMINISTRATOR , unit_labor : : NONE , job_skill : : MAGIC_NATURE , " Dr " } ,
{ 20 , 5 , profession : : NONE , unit_labor : : NONE , job_skill : : MAGIC_NATURE , " Dr " } ,
} ;
} ;
struct UnitInfo
struct UnitInfo
@ -247,17 +249,69 @@ struct UnitInfo
int8_t color ;
int8_t color ;
} ;
} ;
# define FILTER_NONWORKERS 0x0001
enum altsort_mode {
# define FILTER_NONDWARVES 0x0002
ALTSORT_NAME ,
# define FILTER_NONCIV 0x0004
ALTSORT_PROFESSION ,
# define FILTER_ANIMALS 0x0008
ALTSORT_MAX
# define FILTER_LIVING 0x0010
} ;
# define FILTER_DEAD 0x0020
bool descending ;
df : : job_skill sort_skill ;
df : : unit_labor sort_labor ;
bool sortByName ( const UnitInfo * d1 , const UnitInfo * d2 )
{
if ( descending )
return ( d1 - > name > d2 - > name ) ;
else
return ( d1 - > name < d2 - > name ) ;
}
bool sortByProfession ( const UnitInfo * d1 , const UnitInfo * d2 )
{
if ( descending )
return ( d1 - > profession > d2 - > profession ) ;
else
return ( d1 - > profession < d2 - > profession ) ;
}
bool sortBySkill ( const UnitInfo * d1 , const UnitInfo * d2 )
{
if ( sort_skill ! = job_skill : : NONE )
{
df : : unit_skill * s1 = binsearch_in_vector < df : : unit_skill , df : : enum_field < df : : job_skill , int16_t > > ( d1 - > unit - > status . current_soul - > skills , & df : : unit_skill : : id , sort_skill ) ;
df : : unit_skill * s2 = binsearch_in_vector < df : : unit_skill , df : : enum_field < df : : job_skill , int16_t > > ( d2 - > unit - > status . current_soul - > skills , & df : : unit_skill : : id , sort_skill ) ;
int l1 = s1 ? s1 - > rating : 0 ;
int l2 = s2 ? s2 - > rating : 0 ;
int e1 = s1 ? s1 - > experience : 0 ;
int e2 = s2 ? s2 - > experience : 0 ;
if ( descending )
{
if ( l1 ! = l2 )
return l1 > l2 ;
if ( e1 ! = e2 )
return e1 > e2 ;
}
else
{
if ( l1 ! = l2 )
return l1 < l2 ;
if ( e1 ! = e2 )
return e1 < e2 ;
}
}
if ( sort_labor ! = unit_labor : : NONE )
{
if ( descending )
return d1 - > unit - > status . labors [ sort_labor ] > d2 - > unit - > status . labors [ sort_labor ] ;
else
return d1 - > unit - > status . labors [ sort_labor ] < d2 - > unit - > status . labors [ sort_labor ] ;
}
return sortByName ( d1 , d2 ) ;
}
class viewscreen_unitlaborsst : public dfhack_viewscreen {
class viewscreen_unitlaborsst : public dfhack_viewscreen {
public :
public :
static viewscreen_unitlaborsst * create ( char pushtype , df : : viewscreen * scr = NULL ) ;
void feed ( set < df : : interface_key > * events ) ;
void feed ( set < df : : interface_key > * events ) ;
void render ( ) ;
void render ( ) ;
@ -267,86 +321,41 @@ public:
std : : string getFocusString ( ) { return " unitlabors " ; }
std : : string getFocusString ( ) { return " unitlabors " ; }
viewscreen_unitlaborsst ( ) ;
viewscreen_unitlaborsst ( vector < df : : unit * > & src ) ;
~ viewscreen_unitlaborsst ( ) { } ;
~ viewscreen_unitlaborsst ( ) { } ;
protected :
protected :
vector < UnitInfo * > units ;
vector < UnitInfo * > units ;
int filter ;
altsort_mode altsort ;
int first_row , sel_row ;
int first_row , sel_row ;
int first_column , sel_column ;
int first_column , sel_column ;
int height , name_width , prof_width , labors_width ;
int height , name_width , prof_width , labors_width ;
// bool descending;
// int sort_skill;
// int sort_labor;
void readUnits ( ) ;
void calcSize ( ) ;
void calcSize ( ) ;
} ;
} ;
viewscreen_unitlaborsst : : viewscreen_unitlaborsst ( )
viewscreen_unitlaborsst : : viewscreen_unitlaborsst ( vector < df : : unit * > & src )
{
{
filter = FILTER_LIVING ;
for ( size_t i = 0 ; i < src . size ( ) ; i + + )
first_row = sel_row = 0 ;
first_column = sel_column = 0 ;
calcSize ( ) ;
readUnits ( ) ;
}
void viewscreen_unitlaborsst : : readUnits ( )
{
for ( size_t i = 0 ; i < units . size ( ) ; i + + )
delete units [ i ] ;
units . clear ( ) ;
UnitInfo * cur = new UnitInfo ;
for ( size_t i = 0 ; i < world - > units . active . size ( ) ; i + + )
{
{
df : : unit * unit = world - > units . active [ i ] ;
UnitInfo * cur = new UnitInfo ;
df : : unit * unit = src [ i ] ;
cur - > unit = unit ;
cur - > unit = unit ;
cur - > allowEdit = true ;
cur - > allowEdit = true ;
if ( unit - > race ! = ui - > race_id )
if ( unit - > race ! = ui - > race_id )
{
cur - > allowEdit = false ;
cur - > allowEdit = false ;
if ( ! ( filter & FILTER_NONDWARVES ) )
continue ;
}
if ( unit - > civ_id ! = ui - > civ_id )
if ( unit - > civ_id ! = ui - > civ_id )
{
cur - > allowEdit = false ;
cur - > allowEdit = false ;
if ( ! ( filter & FILTER_NONCIV ) )
continue ;
}
if ( unit - > flags1 . bits . dead )
if ( unit - > flags1 . bits . dead )
{
cur - > allowEdit = false ;
cur - > allowEdit = false ;
if ( ! ( filter & FILTER_DEAD ) )
continue ;
}
else
{
if ( ! ( filter & FILTER_LIVING ) )
continue ;
}
if ( ! ENUM_ATTR ( profession , can_assign_labor , unit - > profession ) )
if ( ! ENUM_ATTR ( profession , can_assign_labor , unit - > profession ) )
{
cur - > allowEdit = false ;
cur - > allowEdit = false ;
if ( ! ( filter & FILTER_NONWORKERS ) )
continue ;
}
if ( ! unit - > name . first_name . length ( ) )
{
if ( ! ( filter & FILTER_ANIMALS ) )
continue ;
}
cur - > name = Translation : : TranslateName ( & unit - > name , false ) ;
cur - > name = Translation : : TranslateName ( & unit - > name , false ) ;
cur - > transname = Translation : : TranslateName ( & unit - > name , true ) ;
cur - > transname = Translation : : TranslateName ( & unit - > name , true ) ;
@ -354,9 +363,13 @@ void viewscreen_unitlaborsst::readUnits ()
cur - > color = Units : : getProfessionColor ( unit ) ;
cur - > color = Units : : getProfessionColor ( unit ) ;
units . push_back ( cur ) ;
units . push_back ( cur ) ;
cur = new UnitInfo ;
}
}
delete cur ;
std : : sort ( units . begin ( ) , units . end ( ) , sortByName ) ;
altsort = ALTSORT_NAME ;
first_row = sel_row = 0 ;
first_column = sel_column = 0 ;
calcSize ( ) ;
}
}
void viewscreen_unitlaborsst : : calcSize ( )
void viewscreen_unitlaborsst : : calcSize ( )
@ -421,8 +434,6 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
return ;
return ;
}
}
// TODO - allow modifying filters
if ( ! units . size ( ) )
if ( ! units . size ( ) )
return ;
return ;
@ -458,16 +469,16 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
{
{
// go to beginning of current column group; if already at the beginning, go to the beginning of the previous one
// go to beginning of current column group; if already at the beginning, go to the beginning of the previous one
sel_column - - ;
sel_column - - ;
df : : profession cur = columns [ sel_column ] . profession ;
int cur = columns [ sel_column ] . group ;
while ( ( sel_column > 0 ) & & columns [ sel_column - 1 ] . profession = = cur )
while ( ( sel_column > 0 ) & & columns [ sel_column - 1 ] . group = = cur )
sel_column - - ;
sel_column - - ;
}
}
if ( ( sel_column ! = NUM_COLUMNS - 1 ) & & events - > count ( interface_key : : CURSOR_DOWN_Z ) )
if ( ( sel_column ! = NUM_COLUMNS - 1 ) & & events - > count ( interface_key : : CURSOR_DOWN_Z ) )
{
{
// go to end of current column group; if already at the end, go to the end of the next one
// go to end of current column group; if already at the end, go to the end of the next one
sel_column + + ;
sel_column + + ;
df : : profession cur = columns [ sel_column ] . profession ;
int cur = columns [ sel_column ] . group ;
while ( ( sel_column < NUM_COLUMNS - 1 ) & & columns [ sel_column + 1 ] . profession = = cur )
while ( ( sel_column < NUM_COLUMNS - 1 ) & & columns [ sel_column + 1 ] . group = = cur )
sel_column + + ;
sel_column + + ;
}
}
@ -486,9 +497,10 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
{
{
df : : unit * unit = cur - > unit ;
df : : unit * unit = cur - > unit ;
const SkillColumn & col = columns [ sel_column ] ;
const SkillColumn & col = columns [ sel_column ] ;
bool newstatus = ! unit - > status . labors [ col . labor ] ;
if ( col . special )
if ( col . special )
{
{
if ( ! unit - > status . labors [ col . labor ] )
if ( newstatus )
{
{
for ( int i = 0 ; i < NUM_COLUMNS ; i + + )
for ( int i = 0 ; i < NUM_COLUMNS ; i + + )
{
{
@ -498,12 +510,91 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
}
}
unit - > military . pickup_flags . bits . update = true ;
unit - > military . pickup_flags . bits . update = true ;
}
}
unit - > status . labors [ col . labor ] = ! unit - > status . labors [ col . labor ] ;
unit - > status . labors [ col . labor ] = newstatus ;
}
if ( events - > count ( interface_key : : SELECT_ALL ) & & ( cur - > allowEdit ) )
{
df : : unit * unit = cur - > unit ;
const SkillColumn & col = columns [ sel_column ] ;
bool newstatus = ! unit - > status . labors [ col . labor ] ;
for ( int i = 0 ; i < NUM_COLUMNS ; i + + )
{
if ( columns [ i ] . group ! = col . group )
continue ;
if ( columns [ i ] . special )
{
if ( newstatus )
{
for ( int j = 0 ; j < NUM_COLUMNS ; j + + )
{
if ( ( columns [ j ] . labor ! = unit_labor : : NONE ) & & columns [ j ] . special )
unit - > status . labors [ columns [ j ] . labor ] = false ;
}
}
unit - > military . pickup_flags . bits . update = true ;
}
unit - > status . labors [ columns [ i ] . labor ] = newstatus ;
}
}
if ( events - > count ( interface_key : : SECONDSCROLL_UP ) | | events - > count ( interface_key : : SECONDSCROLL_DOWN ) )
{
descending = events - > count ( interface_key : : SECONDSCROLL_UP ) ;
sort_skill = columns [ sel_column ] . skill ;
sort_labor = columns [ sel_column ] . labor ;
std : : sort ( units . begin ( ) , units . end ( ) , sortBySkill ) ;
}
}
// TODO: add sorting
if ( events - > count ( interface_key : : SECONDSCROLL_PAGEUP ) | | events - > count ( interface_key : : SECONDSCROLL_PAGEDOWN ) )
{
descending = events - > count ( interface_key : : SECONDSCROLL_PAGEUP ) ;
switch ( altsort )
{
case ALTSORT_NAME :
std : : sort ( units . begin ( ) , units . end ( ) , sortByName ) ;
break ;
case ALTSORT_PROFESSION :
std : : sort ( units . begin ( ) , units . end ( ) , sortByProfession ) ;
break ;
}
}
if ( events - > count ( interface_key : : CHANGETAB ) )
{
switch ( altsort )
{
case ALTSORT_NAME :
altsort = ALTSORT_PROFESSION ;
break ;
case ALTSORT_PROFESSION :
altsort = ALTSORT_NAME ;
break ;
}
}
if ( VIRTUAL_CAST_VAR ( unitlist , df : : viewscreen_unitlistst , parent ) )
{
if ( events - > count ( interface_key : : UNITJOB_VIEW ) | | events - > count ( interface_key : : UNITJOB_ZOOM_CRE ) )
{
for ( int i = 0 ; i < unitlist - > units [ unitlist - > page ] . size ( ) ; i + + )
{
if ( unitlist - > units [ unitlist - > page ] [ i ] = = units [ sel_row ] - > unit )
{
unitlist - > cursor_pos [ unitlist - > page ] = i ;
unitlist - > feed ( events ) ;
if ( Screen : : isDismissed ( unitlist ) )
Screen : : dismiss ( this ) ;
break ;
}
}
}
}
}
}
void OutputString ( int8_t color , int & x , int y , const std : : string & text )
{
Screen : : paintString ( Screen : : Pen ( ' ' , color , 0 ) , x , y , text ) ;
x + = text . length ( ) ;
}
void viewscreen_unitlaborsst : : render ( )
void viewscreen_unitlaborsst : : render ( )
{
{
if ( Screen : : isDismissed ( this ) )
if ( Screen : : isDismissed ( this ) )
@ -520,7 +611,7 @@ void viewscreen_unitlaborsst::render()
if ( col_offset > = NUM_COLUMNS )
if ( col_offset > = NUM_COLUMNS )
break ;
break ;
int8_t fg = Units: : getCasteProfessionColor ( ui - > race_id , - 1 , columns[ col_offset ] . profession) ;
int8_t fg = columns[ col_offset ] . color ;
int8_t bg = 0 ;
int8_t bg = 0 ;
if ( col_offset = = sel_column )
if ( col_offset = = sel_column )
@ -528,8 +619,19 @@ void viewscreen_unitlaborsst::render()
fg = 0 ;
fg = 0 ;
bg = 7 ;
bg = 7 ;
}
}
Screen : : paintTile ( Screen : : Pen ( columns [ col_offset ] . label [ 0 ] , fg , bg ) , 1 + name_width + 1 + prof_width + 1 + col , 1 ) ;
Screen : : paintTile ( Screen : : Pen ( columns [ col_offset ] . label [ 0 ] , fg , bg ) , 1 + name_width + 1 + prof_width + 1 + col , 1 ) ;
Screen : : paintTile ( Screen : : Pen ( columns [ col_offset ] . label [ 1 ] , fg , bg ) , 1 + name_width + 1 + prof_width + 1 + col , 2 ) ;
Screen : : paintTile ( Screen : : Pen ( columns [ col_offset ] . label [ 1 ] , fg , bg ) , 1 + name_width + 1 + prof_width + 1 + col , 2 ) ;
df : : profession profession = columns [ col_offset ] . profession ;
if ( profession ! = profession : : NONE )
{
auto graphics = world - > raws . creatures . all [ ui - > race_id ] - > graphics ;
Screen : : paintTile (
Screen : : Pen ( ' ' , fg , 0 ,
graphics . profession_add_color [ creature_graphics_role : : DEFAULT ] [ profession ] ,
graphics . profession_texpos [ creature_graphics_role : : DEFAULT ] [ profession ] ) ,
1 + name_width + 1 + prof_width + 1 + col , 3 ) ;
}
}
}
for ( int row = 0 ; row < height ; row + + )
for ( int row = 0 ; row < height ; row + + )
@ -537,6 +639,7 @@ void viewscreen_unitlaborsst::render()
int row_offset = row + first_row ;
int row_offset = row + first_row ;
if ( row_offset > = units . size ( ) )
if ( row_offset > = units . size ( ) )
break ;
break ;
UnitInfo * cur = units [ row_offset ] ;
UnitInfo * cur = units [ row_offset ] ;
df : : unit * unit = cur - > unit ;
df : : unit * unit = cur - > unit ;
int8_t fg = 15 , bg = 0 ;
int8_t fg = 15 , bg = 0 ;
@ -548,13 +651,14 @@ void viewscreen_unitlaborsst::render()
string name = cur - > name ;
string name = cur - > name ;
name . resize ( name_width ) ;
name . resize ( name_width ) ;
Screen : : paintString ( Screen : : Pen ( ' ' , fg , bg ) , 1 , 3 + row , name ) ;
Screen : : paintString ( Screen : : Pen ( ' ' , fg , bg ) , 1 , 4 + row , name ) ;
string profession = cur - > profession ;
string profession = cur - > profession ;
profession . resize ( prof_width ) ;
profession . resize ( prof_width ) ;
fg = cur - > color ;
fg = cur - > color ;
bg = 0 ;
bg = 0 ;
Screen : : paintString ( Screen : : Pen ( ' ' , fg , bg ) , 1 + prof_width + 1 , 3 + row , profession ) ;
Screen : : paintString ( Screen : : Pen ( ' ' , fg , bg ) , 1 + name_width + 1 , 4 + row , profession ) ;
// Print unit's skills and labor assignments
// Print unit's skills and labor assignments
for ( int col = 0 ; col < labors_width ; col + + )
for ( int col = 0 ; col < labors_width ; col + + )
@ -562,11 +666,9 @@ void viewscreen_unitlaborsst::render()
int col_offset = col + first_column ;
int col_offset = col + first_column ;
fg = 15 ;
fg = 15 ;
bg = 0 ;
bg = 0 ;
uint8_t c = 0xFA ;
if ( ( col_offset = = sel_column ) & & ( row_offset = = sel_row ) )
if ( ( col_offset = = sel_column ) & & ( row_offset = = sel_row ) )
fg = 9 ;
fg = 9 ;
if ( ( columns [ col_offset ] . labor ! = unit_labor : : NONE ) & & ( unit - > status . labors [ columns [ col_offset ] . labor ] ) )
bg = 7 ;
char c = ' - ' ;
if ( columns [ col_offset ] . skill ! = job_skill : : NONE )
if ( columns [ col_offset ] . skill ! = job_skill : : NONE )
{
{
df : : unit_skill * skill = binsearch_in_vector < df : : unit_skill , df : : enum_field < df : : job_skill , int16_t > > ( unit - > status . current_soul - > skills , & df : : unit_skill : : id , columns [ col_offset ] . skill ) ;
df : : unit_skill * skill = binsearch_in_vector < df : : unit_skill , df : : enum_field < df : : job_skill , int16_t > > ( unit - > status . current_soul - > skills , & df : : unit_skill : : id , columns [ col_offset ] . skill ) ;
@ -577,24 +679,44 @@ void viewscreen_unitlaborsst::render()
level = NUM_SKILL_LEVELS - 1 ;
level = NUM_SKILL_LEVELS - 1 ;
c = skill_levels [ level ] . abbrev ;
c = skill_levels [ level ] . abbrev ;
}
}
else
c = ' - ' ;
}
}
Screen : : paintTile ( Screen : : Pen ( c , fg , bg ) , 1 + name_width + 1 + prof_width + 1 + col , 3 + row ) ;
if ( columns [ col_offset ] . labor ! = unit_labor : : NONE )
{
if ( unit - > status . labors [ columns [ col_offset ] . labor ] )
{
bg = 7 ;
if ( columns [ col_offset ] . skill = = job_skill : : NONE )
c = 0xF9 ;
}
}
else
bg = 4 ;
Screen : : paintTile ( Screen : : Pen ( c , fg , bg ) , 1 + name_width + 1 + prof_width + 1 + col , 4 + row ) ;
}
}
}
}
UnitInfo * cur = units [ sel_row ] ;
UnitInfo * cur = units [ sel_row ] ;
bool canToggle = false ;
if ( cur ! = NULL )
if ( cur ! = NULL )
{
{
df : : unit * unit = cur - > unit ;
df : : unit * unit = cur - > unit ;
string str = cur - > transname ;
int x = 1 ;
if ( str . length ( ) )
Screen : : paintString ( Screen : : Pen ( ' ' , 15 , 0 ) , x , 3 + height + 2 , cur - > transname ) ;
str + = " , " ;
x + = cur - > transname . length ( ) ;
str + = cur - > profession ;
str + = " : " ;
Screen : : paintString ( Screen : : Pen ( ' ' , 15 , 0 ) , 1 , 3 + height + 2 , str ) ;
if ( cur - > transname . length ( ) )
int y = 1 + str . length ( ) + 1 ;
{
Screen : : paintString ( Screen : : Pen ( ' ' , 15 , 0 ) , x , 3 + height + 2 , " , " ) ;
x + = 2 ;
}
Screen : : paintString ( Screen : : Pen ( ' ' , 15 , 0 ) , x , 3 + height + 2 , cur - > profession ) ;
x + = cur - > profession . length ( ) ;
Screen : : paintString ( Screen : : Pen ( ' ' , 15 , 0 ) , x , 3 + height + 2 , " : " ) ;
x + = 2 ;
string str ;
if ( columns [ sel_column ] . skill = = job_skill : : NONE )
if ( columns [ sel_column ] . skill = = job_skill : : NONE )
{
{
str = ENUM_ATTR_STR ( unit_labor , caption , columns [ sel_column ] . labor ) ;
str = ENUM_ATTR_STR ( unit_labor , caption , columns [ sel_column ] . labor ) ;
@ -602,7 +724,6 @@ void viewscreen_unitlaborsst::render()
str + = " Enabled " ;
str + = " Enabled " ;
else
else
str + = " Not Enabled " ;
str + = " Not Enabled " ;
Screen : : paintString ( Screen : : Pen ( ' ' , 9 , 0 ) , y , 3 + height + 2 , str ) ;
}
}
else
else
{
{
@ -618,11 +739,50 @@ void viewscreen_unitlaborsst::render()
}
}
else
else
str = stl_sprintf ( " Not %s (0/500) " , ENUM_ATTR_STR ( job_skill , caption_noun , columns [ sel_column ] . skill ) ) ;
str = stl_sprintf ( " Not %s (0/500) " , ENUM_ATTR_STR ( job_skill , caption_noun , columns [ sel_column ] . skill ) ) ;
Screen : : paintString ( Screen : : Pen ( ' ' , 9 , 0 ) , y , 3 + height + 2 , str ) ;
}
}
Screen : : paintString ( Screen : : Pen ( ' ' , 9 , 0 ) , x , 3 + height + 2 , str ) ;
canToggle = ( cur - > allowEdit ) & & ( columns [ sel_column ] . labor ! = unit_labor : : NONE ) ;
}
}
// TODO - print command help info
int x = 2 ;
OutputString ( 10 , x , gps - > dimy - 3 , " Enter " ) ; // SELECT key
OutputString ( canToggle ? 15 : 8 , x , gps - > dimy - 3 , " : Toggle labor, " ) ;
OutputString ( 10 , x , gps - > dimy - 3 , " Shift+Enter " ) ; // SELECT_ALL key
OutputString ( canToggle ? 15 : 8 , x , gps - > dimy - 3 , " : Toggle Group, " ) ;
OutputString ( 10 , x , gps - > dimy - 3 , " v " ) ; // UNITJOB_VIEW key
OutputString ( 15 , x , gps - > dimy - 3 , " : ViewCre, " ) ;
OutputString ( 10 , x , gps - > dimy - 3 , " c " ) ; // UNITJOB_ZOOM_CRE key
OutputString ( 15 , x , gps - > dimy - 3 , " : Zoom-Cre " ) ;
x = 2 ;
OutputString ( 10 , x , gps - > dimy - 2 , " Esc " ) ; // LEAVESCREEN key
OutputString ( 15 , x , gps - > dimy - 2 , " : Done, " ) ;
OutputString ( 10 , x , gps - > dimy - 2 , " + " ) ; // SECONDSCROLL_DOWN key
OutputString ( 10 , x , gps - > dimy - 2 , " - " ) ; // SECONDSCROLL_UP key
OutputString ( 15 , x , gps - > dimy - 2 , " : Sort by Skill, " ) ;
OutputString ( 10 , x , gps - > dimy - 2 , " * " ) ; // SECONDSCROLL_PAGEDOWN key
OutputString ( 10 , x , gps - > dimy - 2 , " / " ) ; // SECONDSCROLL_PAGEUP key
OutputString ( 15 , x , gps - > dimy - 2 , " : Sort by ( " ) ;
OutputString ( 10 , x , gps - > dimy - 2 , " Tab " ) ; // CHANGETAB key
OutputString ( 15 , x , gps - > dimy - 2 , " ) " ) ;
switch ( altsort )
{
case ALTSORT_NAME :
OutputString ( 15 , x , gps - > dimy - 2 , " Name " ) ;
break ;
case ALTSORT_PROFESSION :
OutputString ( 15 , x , gps - > dimy - 2 , " Profession " ) ;
break ;
default :
OutputString ( 15 , x , gps - > dimy - 2 , " Unknown " ) ;
break ;
}
}
}
struct unitlist_hook : df : : viewscreen_unitlistst
struct unitlist_hook : df : : viewscreen_unitlistst
@ -633,29 +793,43 @@ struct unitlist_hook : df::viewscreen_unitlistst
{
{
if ( input - > count ( interface_key : : UNITVIEW_PRF_PROF ) )
if ( input - > count ( interface_key : : UNITVIEW_PRF_PROF ) )
{
{
Screen : : dismiss ( this ) ;
if ( units [ page ] . size ( ) )
Screen : : show ( new viewscreen_unitlaborsst ( ) ) ;
{
Screen : : show ( new viewscreen_unitlaborsst ( units [ page ] ) ) ;
return ;
return ;
}
}
}
INTERPOSE_NEXT ( feed ) ( input ) ;
INTERPOSE_NEXT ( feed ) ( input ) ;
}
}
DEFINE_VMETHOD_INTERPOSE ( void , render , ( ) )
{
INTERPOSE_NEXT ( render ) ( ) ;
if ( units [ page ] . size ( ) )
{
int x = 2 ;
OutputString ( 12 , x , gps - > dimy - 2 , " l " ) ; // UNITVIEW_PRF_PROF key
OutputString ( 15 , x , gps - > dimy - 2 , " : Manage labors " ) ;
}
}
} ;
} ;
IMPLEMENT_VMETHOD_INTERPOSE ( unitlist_hook , feed ) ;
IMPLEMENT_VMETHOD_INTERPOSE ( unitlist_hook , feed ) ;
IMPLEMENT_VMETHOD_INTERPOSE ( unitlist_hook , render ) ;
DFHACK_PLUGIN ( " manipulator " ) ;
DFhackCExport command_result plugin_init ( color_ostream & out , vector < PluginCommand > & commands )
DFhackCExport command_result plugin_init ( color_ostream & out , vector < PluginCommand > & commands )
{
{
if ( gps )
if ( ! gps | | ! INTERPOSE_HOOK ( unitlist_hook , feed ) . apply ( ) | | ! INTERPOSE_HOOK ( unitlist_hook , render ) . apply ( ) )
{
out . printerr ( " Could not insert Dwarf Manipulator hooks! \n " ) ;
if ( ! INTERPOSE_HOOK ( unitlist_hook , feed ) . apply ( ) )
out . printerr ( " Could not interpose viewscreen_unitlistst::feed \n " ) ;
}
return CR_OK ;
return CR_OK ;
}
}
DFhackCExport command_result plugin_shutdown ( color_ostream & out )
DFhackCExport command_result plugin_shutdown ( color_ostream & out )
{
{
INTERPOSE_HOOK ( unitlist_hook , feed ) . remove ( ) ;
INTERPOSE_HOOK ( unitlist_hook , feed ) . remove ( ) ;
INTERPOSE_HOOK ( unitlist_hook , render ) . remove ( ) ;
return CR_OK ;
return CR_OK ;
}
}