|  |  |  | @ -11,12 +11,14 @@ | 
		
	
		
			
				|  |  |  |  | #include "df/job.h" | 
		
	
		
			
				|  |  |  |  | #include "df/unit.h" | 
		
	
		
			
				|  |  |  |  | #include "df/world.h" | 
		
	
		
			
				|  |  |  |  | #include "df/item_quality.h" | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | #include "modules/Gui.h" | 
		
	
		
			
				|  |  |  |  | #include "modules/Items.h" | 
		
	
		
			
				|  |  |  |  | #include "modules/Job.h" | 
		
	
		
			
				|  |  |  |  | #include "modules/World.h" | 
		
	
		
			
				|  |  |  |  | #include "modules/Screen.h" | 
		
	
		
			
				|  |  |  |  | #include "modules/Maps.h" | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | using df::global::world; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -43,10 +45,13 @@ static void debug(const string &msg) | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | /*struct FlagDisplay
 | 
		
	
		
			
				|  |  |  |  | static string getQualityName(const df::item_quality quality) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | };*/ | 
		
	
		
			
				|  |  |  |  |     if (gps->dimx - SIDEBAR_WIDTH < 60) | 
		
	
		
			
				|  |  |  |  |         return int_to_string(quality); | 
		
	
		
			
				|  |  |  |  |     else | 
		
	
		
			
				|  |  |  |  |         return ENUM_KEY_STR(item_quality, quality); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | template <class T> | 
		
	
		
			
				|  |  |  |  | class StockListColumn : public ListColumn<T> | 
		
	
	
		
			
				
					|  |  |  | @ -97,6 +102,43 @@ class StockListColumn : public ListColumn<T> | 
		
	
		
			
				|  |  |  |  |             OutputString(COLOR_GREY, x, y, "I"); | 
		
	
		
			
				|  |  |  |  |         else | 
		
	
		
			
				|  |  |  |  |             OutputString(COLOR_LIGHTBLUE, x, y, " "); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         if (item->isImproved()) | 
		
	
		
			
				|  |  |  |  |             OutputString(COLOR_BLUE, x, y, "* "); | 
		
	
		
			
				|  |  |  |  |         else | 
		
	
		
			
				|  |  |  |  |             OutputString(COLOR_LIGHTBLUE, x, y, "  "); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         auto quality = static_cast<df::item_quality>(item->getQuality()); | 
		
	
		
			
				|  |  |  |  |         if (quality > item_quality::Ordinary) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             auto color = COLOR_BROWN; | 
		
	
		
			
				|  |  |  |  |             switch(quality) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |             case item_quality::FinelyCrafted: | 
		
	
		
			
				|  |  |  |  |                 color = COLOR_CYAN; | 
		
	
		
			
				|  |  |  |  |                 break; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             case item_quality::Superior: | 
		
	
		
			
				|  |  |  |  |                 color = COLOR_LIGHTBLUE; | 
		
	
		
			
				|  |  |  |  |                 break; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             case item_quality::Exceptional: | 
		
	
		
			
				|  |  |  |  |                 color = COLOR_GREEN; | 
		
	
		
			
				|  |  |  |  |                 break; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             case item_quality::Masterful: | 
		
	
		
			
				|  |  |  |  |                 color = COLOR_LIGHTGREEN; | 
		
	
		
			
				|  |  |  |  |                 break; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             case item_quality::Artifact: | 
		
	
		
			
				|  |  |  |  |                 color = COLOR_BLUE; | 
		
	
		
			
				|  |  |  |  |                 break; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             default: | 
		
	
		
			
				|  |  |  |  |                 break; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |             OutputString(color, x, y, getQualityName(quality)); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -104,6 +146,8 @@ class StockListColumn : public ListColumn<T> | 
		
	
		
			
				|  |  |  |  | class ViewscreenStocks : public dfhack_viewscreen | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | public: | 
		
	
		
			
				|  |  |  |  |     static df::item_flags hide_flags; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     ViewscreenStocks() | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         selected_column = 0; | 
		
	
	
		
			
				
					|  |  |  | @ -117,7 +161,23 @@ public: | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         items_column.changeHighlight(0); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         hide_flags.whole = 0; | 
		
	
		
			
				|  |  |  |  |         apply_to_all = false; | 
		
	
		
			
				|  |  |  |  |         hide_unflagged = false; | 
		
	
		
			
				|  |  |  |  |          | 
		
	
		
			
				|  |  |  |  |         checked_flags.bits.in_job = true; | 
		
	
		
			
				|  |  |  |  |         checked_flags.bits.rotten = true; | 
		
	
		
			
				|  |  |  |  |         checked_flags.bits.foreign = true; | 
		
	
		
			
				|  |  |  |  |         checked_flags.bits.owned = true; | 
		
	
		
			
				|  |  |  |  |         checked_flags.bits.forbid = true; | 
		
	
		
			
				|  |  |  |  |         checked_flags.bits.dump = true; | 
		
	
		
			
				|  |  |  |  |         checked_flags.bits.on_fire = true; | 
		
	
		
			
				|  |  |  |  |         checked_flags.bits.melt = true; | 
		
	
		
			
				|  |  |  |  |         checked_flags.bits.on_fire = true; | 
		
	
		
			
				|  |  |  |  |         checked_flags.bits.in_inventory = true; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         min_quality = item_quality::Ordinary; | 
		
	
		
			
				|  |  |  |  |         max_quality = item_quality::Artifact; | 
		
	
		
			
				|  |  |  |  |         min_wear = 0; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         populateItems(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -144,53 +204,100 @@ public: | 
		
	
		
			
				|  |  |  |  |             return; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         if  (input->count(interface_key::CUSTOM_SHIFT_G)) | 
		
	
		
			
				|  |  |  |  |         if (input->count(interface_key::CUSTOM_SHIFT_G)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             hide_flags.bits.foreign = !hide_flags.bits.foreign; | 
		
	
		
			
				|  |  |  |  |             populateItems(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if  (input->count(interface_key::CUSTOM_SHIFT_J)) | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::CUSTOM_SHIFT_J)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             hide_flags.bits.in_job = !hide_flags.bits.in_job; | 
		
	
		
			
				|  |  |  |  |             populateItems(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if  (input->count(interface_key::CUSTOM_SHIFT_N)) | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::CUSTOM_SHIFT_T)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             hide_flags.bits.rotten = !hide_flags.bits.rotten; | 
		
	
		
			
				|  |  |  |  |             populateItems(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if  (input->count(interface_key::CUSTOM_SHIFT_O)) | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::CUSTOM_SHIFT_O)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             hide_flags.bits.owned = !hide_flags.bits.owned; | 
		
	
		
			
				|  |  |  |  |             populateItems(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if  (input->count(interface_key::CUSTOM_SHIFT_F)) | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::CUSTOM_SHIFT_F)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             hide_flags.bits.forbid = !hide_flags.bits.forbid; | 
		
	
		
			
				|  |  |  |  |             populateItems(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if  (input->count(interface_key::CUSTOM_SHIFT_D)) | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::CUSTOM_SHIFT_D)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             hide_flags.bits.dump = !hide_flags.bits.dump; | 
		
	
		
			
				|  |  |  |  |             populateItems(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if  (input->count(interface_key::CUSTOM_SHIFT_R)) | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::CUSTOM_SHIFT_R)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             hide_flags.bits.on_fire = !hide_flags.bits.on_fire; | 
		
	
		
			
				|  |  |  |  |             populateItems(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if  (input->count(interface_key::CUSTOM_SHIFT_M)) | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::CUSTOM_SHIFT_M)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             hide_flags.bits.melt = !hide_flags.bits.melt; | 
		
	
		
			
				|  |  |  |  |             populateItems(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if  (input->count(interface_key::CUSTOM_SHIFT_I)) | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::CUSTOM_SHIFT_I)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             hide_flags.bits.in_inventory = !hide_flags.bits.in_inventory; | 
		
	
		
			
				|  |  |  |  |             populateItems(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::CUSTOM_SHIFT_N)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             hide_unflagged = !hide_unflagged; | 
		
	
		
			
				|  |  |  |  |             populateItems(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::CUSTOM_SHIFT_C)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             setAllFlags(true); | 
		
	
		
			
				|  |  |  |  |             populateItems(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::CUSTOM_SHIFT_E)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             setAllFlags(false); | 
		
	
		
			
				|  |  |  |  |             populateItems(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::SECONDSCROLL_UP)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             if (min_quality > item_quality::Ordinary) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 min_quality = static_cast<df::item_quality>(static_cast<int16_t>(min_quality) - 1); | 
		
	
		
			
				|  |  |  |  |                 populateItems(); | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::SECONDSCROLL_DOWN)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             if (min_quality < max_quality && min_quality < item_quality::Artifact) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 min_quality = static_cast<df::item_quality>(static_cast<int16_t>(min_quality) + 1); | 
		
	
		
			
				|  |  |  |  |                 populateItems(); | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::SECONDSCROLL_PAGEUP)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             if (max_quality > min_quality && max_quality > item_quality::Ordinary) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 max_quality = static_cast<df::item_quality>(static_cast<int16_t>(max_quality) - 1); | 
		
	
		
			
				|  |  |  |  |                 populateItems(); | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::SECONDSCROLL_PAGEDOWN)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             if (max_quality < item_quality::Artifact) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 max_quality = static_cast<df::item_quality>(static_cast<int16_t>(max_quality) + 1); | 
		
	
		
			
				|  |  |  |  |                 populateItems(); | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         else if  (input->count(interface_key::CUSTOM_SHIFT_Z)) | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::CUSTOM_SHIFT_Z)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             input->clear(); | 
		
	
		
			
				|  |  |  |  |             auto item = items_column.getFirstSelectedElem(); | 
		
	
	
		
			
				
					|  |  |  | @ -201,16 +308,34 @@ public: | 
		
	
		
			
				|  |  |  |  |                 return; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             Screen::dismiss(this); | 
		
	
		
			
				|  |  |  |  |             // Could be clever here, if item is in a container, to look inside the container.
 | 
		
	
		
			
				|  |  |  |  |             // But that's different for built containers vs bags/pots in stockpiles.
 | 
		
	
		
			
				|  |  |  |  |             send_key(interface_key::D_LOOK); | 
		
	
		
			
				|  |  |  |  |             move_cursor(*pos); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::CUSTOM_SHIFT_A)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             apply_to_all = !apply_to_all; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::CUSTOM_SHIFT_P)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             df::item_flags flags; | 
		
	
		
			
				|  |  |  |  |             flags.bits.dump = true; | 
		
	
		
			
				|  |  |  |  |             applyFlag(flags); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::CUSTOM_SHIFT_B)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             df::item_flags flags; | 
		
	
		
			
				|  |  |  |  |             flags.bits.forbid = true; | 
		
	
		
			
				|  |  |  |  |             applyFlag(flags); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         else if  (input->count(interface_key::CURSOR_LEFT)) | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::CURSOR_LEFT)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             --selected_column; | 
		
	
		
			
				|  |  |  |  |             validateColumn(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else if  (input->count(interface_key::CURSOR_RIGHT)) | 
		
	
		
			
				|  |  |  |  |         else if (input->count(interface_key::CURSOR_RIGHT)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             selected_column++; | 
		
	
		
			
				|  |  |  |  |             validateColumn(); | 
		
	
	
		
			
				
					|  |  |  | @ -224,7 +349,7 @@ public: | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     void move_cursor(df::coord &pos) | 
		
	
		
			
				|  |  |  |  |     void move_cursor(const df::coord &pos) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         Gui::setCursorCoords(pos.x, pos.y, pos.z); | 
		
	
		
			
				|  |  |  |  |         send_key(interface_key::CURSOR_DOWN_Z); | 
		
	
	
		
			
				
					|  |  |  | @ -264,7 +389,7 @@ public: | 
		
	
		
			
				|  |  |  |  |         OutputString(COLOR_BROWN, x, y, "Filters", true, left_margin); | 
		
	
		
			
				|  |  |  |  |         OutputString(COLOR_LIGHTRED, x, y, "Press Shift-Hotkey to Toggle", true, left_margin); | 
		
	
		
			
				|  |  |  |  |         OutputFilterString(x, y, "In Job", "J", !hide_flags.bits.in_job, true, left_margin, COLOR_LIGHTBLUE); | 
		
	
		
			
				|  |  |  |  |         OutputFilterString(x, y, "Rotten", "N", !hide_flags.bits.rotten, true, left_margin, COLOR_CYAN); | 
		
	
		
			
				|  |  |  |  |         OutputFilterString(x, y, "Rotten", "T", !hide_flags.bits.rotten, true, left_margin, COLOR_CYAN); | 
		
	
		
			
				|  |  |  |  |         OutputFilterString(x, y, "Foreign Made", "G", !hide_flags.bits.foreign, true, left_margin, COLOR_BROWN); | 
		
	
		
			
				|  |  |  |  |         OutputFilterString(x, y, "Owned", "O", !hide_flags.bits.owned, true, left_margin, COLOR_GREEN); | 
		
	
		
			
				|  |  |  |  |         OutputFilterString(x, y, "Forbidden", "F", !hide_flags.bits.forbid, true, left_margin, COLOR_RED); | 
		
	
	
		
			
				
					|  |  |  | @ -272,12 +397,29 @@ public: | 
		
	
		
			
				|  |  |  |  |         OutputFilterString(x, y, "On Fire", "R", !hide_flags.bits.on_fire, true, left_margin, COLOR_LIGHTRED); | 
		
	
		
			
				|  |  |  |  |         OutputFilterString(x, y, "Melt", "M", !hide_flags.bits.melt, true, left_margin, COLOR_BLUE); | 
		
	
		
			
				|  |  |  |  |         OutputFilterString(x, y, "In Inventory", "I", !hide_flags.bits.in_inventory, true, left_margin, COLOR_GREY); | 
		
	
		
			
				|  |  |  |  |         OutputFilterString(x, y, "No Flags", "N", !hide_unflagged, true, left_margin, COLOR_GREY); | 
		
	
		
			
				|  |  |  |  |         ++y; | 
		
	
		
			
				|  |  |  |  |         OutputHotkeyString(x, y, "Clear All", "Shift-C", true, left_margin); | 
		
	
		
			
				|  |  |  |  |         OutputHotkeyString(x, y, "Enable All", "Shift-E", true, left_margin); | 
		
	
		
			
				|  |  |  |  |         ++y; | 
		
	
		
			
				|  |  |  |  |         OutputHotkeyString(x, y, "Min Qual: ", "-+"); | 
		
	
		
			
				|  |  |  |  |         OutputString(COLOR_BROWN, x, y, getQualityName(min_quality), true, left_margin); | 
		
	
		
			
				|  |  |  |  |         OutputHotkeyString(x, y, "Max Qual: ", "/*"); | 
		
	
		
			
				|  |  |  |  |         OutputString(COLOR_BROWN, x, y, getQualityName(max_quality), true, left_margin); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         OutputHotkeyString(x, y, "Min Wear: ", "Shift-W"); | 
		
	
		
			
				|  |  |  |  |         OutputString(COLOR_BROWN, x, y, int_to_string(min_wear), true, left_margin); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         ++y; | 
		
	
		
			
				|  |  |  |  |         OutputString(COLOR_BROWN, x, y, "Actions (" + int_to_string(items_column.getDisplayedListSize()) + " Items)",  | 
		
	
		
			
				|  |  |  |  |             true, left_margin); | 
		
	
		
			
				|  |  |  |  |         OutputString(COLOR_BROWN, x, y, "Actions ("); | 
		
	
		
			
				|  |  |  |  |         OutputString(COLOR_LIGHTGREEN, x, y, int_to_string(items_column.getDisplayedListSize())); | 
		
	
		
			
				|  |  |  |  |         OutputString(COLOR_BROWN, x, y, " Items)", true, left_margin); | 
		
	
		
			
				|  |  |  |  |         OutputHotkeyString(x, y, "Zoom", "Shift-Z", true, left_margin); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         OutputHotkeyString(x, y, "Apply to: ", "Shift-A"); | 
		
	
		
			
				|  |  |  |  |         OutputString(COLOR_BROWN, x, y, (apply_to_all) ? "Listed" : "Selected", true, left_margin); | 
		
	
		
			
				|  |  |  |  |         OutputHotkeyString(x, y, "Dump", "Shift-P", true, left_margin); | 
		
	
		
			
				|  |  |  |  |         OutputHotkeyString(x, y, "Forbid", "Shift-B", true, left_margin); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     std::string getFocusString() { return "stocks_view"; } | 
		
	
	
		
			
				
					|  |  |  | @ -285,9 +427,12 @@ public: | 
		
	
		
			
				|  |  |  |  | private: | 
		
	
		
			
				|  |  |  |  |     StockListColumn<df::item *> items_column; | 
		
	
		
			
				|  |  |  |  |     int selected_column; | 
		
	
		
			
				|  |  |  |  |     df::item_flags hide_flags; | 
		
	
		
			
				|  |  |  |  |     bool apply_to_all, hide_unflagged; | 
		
	
		
			
				|  |  |  |  |     df::item_flags checked_flags; | 
		
	
		
			
				|  |  |  |  |     df::item_quality min_quality, max_quality; | 
		
	
		
			
				|  |  |  |  |     int16_t min_wear; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     df::coord *getRealPos(df::item *item) | 
		
	
		
			
				|  |  |  |  |     static df::coord *getRealPos(df::item *item) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         if (item->flags.bits.in_inventory) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
	
		
			
				
					|  |  |  | @ -318,6 +463,50 @@ private: | 
		
	
		
			
				|  |  |  |  |         return &item->pos; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     void applyFlag(const df::item_flags flags) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         if (apply_to_all) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             int state_to_apply = -1; | 
		
	
		
			
				|  |  |  |  |             for (auto iter = items_column.getDisplayList().begin(); iter != items_column.getDisplayList().end(); iter++) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 auto item = (*iter)->elem; | 
		
	
		
			
				|  |  |  |  |                 if (item) | 
		
	
		
			
				|  |  |  |  |                 { | 
		
	
		
			
				|  |  |  |  |                     // Set all flags based on state of first item in list
 | 
		
	
		
			
				|  |  |  |  |                     if (state_to_apply == -1) | 
		
	
		
			
				|  |  |  |  |                         state_to_apply = (item->flags.whole & flags.whole) ? 0 : 1; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                     if (state_to_apply) | 
		
	
		
			
				|  |  |  |  |                         item->flags.whole |= flags.whole; | 
		
	
		
			
				|  |  |  |  |                     else | 
		
	
		
			
				|  |  |  |  |                         item->flags.whole &= ~flags.whole; | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             auto item = items_column.getFirstSelectedElem(); | 
		
	
		
			
				|  |  |  |  |             if (item) | 
		
	
		
			
				|  |  |  |  |                 item->flags.whole ^= flags.whole; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     void setAllFlags(bool state) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         hide_flags.bits.in_job = state; | 
		
	
		
			
				|  |  |  |  |         hide_flags.bits.rotten = state; | 
		
	
		
			
				|  |  |  |  |         hide_flags.bits.foreign = state; | 
		
	
		
			
				|  |  |  |  |         hide_flags.bits.owned = state; | 
		
	
		
			
				|  |  |  |  |         hide_flags.bits.forbid = state; | 
		
	
		
			
				|  |  |  |  |         hide_flags.bits.dump = state; | 
		
	
		
			
				|  |  |  |  |         hide_flags.bits.on_fire = state; | 
		
	
		
			
				|  |  |  |  |         hide_flags.bits.melt = state; | 
		
	
		
			
				|  |  |  |  |         hide_flags.bits.on_fire = state; | 
		
	
		
			
				|  |  |  |  |         hide_flags.bits.in_inventory = state; | 
		
	
		
			
				|  |  |  |  |         hide_unflagged = state; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     void populateItems() | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         items_column.clear(); | 
		
	
	
		
			
				
					|  |  |  | @ -347,10 +536,41 @@ private: | 
		
	
		
			
				|  |  |  |  |             if (item->pos.x == -30000) | 
		
	
		
			
				|  |  |  |  |                 continue; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             if (!getRealPos(item)) | 
		
	
		
			
				|  |  |  |  |             auto pos = getRealPos(item); | 
		
	
		
			
				|  |  |  |  |             if (!pos) | 
		
	
		
			
				|  |  |  |  |                 continue; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             auto designation = Maps::getTileDesignation(*pos); | 
		
	
		
			
				|  |  |  |  |             if (!designation) | 
		
	
		
			
				|  |  |  |  |                 continue; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             auto label = pad_string(Items::getDescription(item, 0, true), MAX_NAME, false, true); | 
		
	
		
			
				|  |  |  |  |             if (designation->bits.hidden) | 
		
	
		
			
				|  |  |  |  |                 continue; // Items in parts of the map not yet revealed
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             if (hide_unflagged && !(item->flags.whole & checked_flags.whole)) | 
		
	
		
			
				|  |  |  |  |                 continue; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             auto quality = static_cast<df::item_quality>(item->getQuality()); | 
		
	
		
			
				|  |  |  |  |             if (quality < min_quality || quality > max_quality) | 
		
	
		
			
				|  |  |  |  |                 continue; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             auto wear = item->getWear(); | 
		
	
		
			
				|  |  |  |  |             if (wear < min_wear) | 
		
	
		
			
				|  |  |  |  |                 continue; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             auto label = Items::getDescription(item, 0, false); | 
		
	
		
			
				|  |  |  |  |             if (wear > 0) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |                 string wearX = ""; | 
		
	
		
			
				|  |  |  |  |                 for (int i = 0; i < wear; i++) | 
		
	
		
			
				|  |  |  |  |                 { | 
		
	
		
			
				|  |  |  |  |                     wearX += "X"; | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                 label = wearX + label + wearX; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             label = pad_string(label, MAX_NAME, false, true); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             items_column.add(label, item); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
	
		
			
				
					|  |  |  | @ -371,6 +591,8 @@ private: | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | df::item_flags ViewscreenStocks::hide_flags; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | static command_result stocks_cmd(color_ostream &out, vector <string> & parameters) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
	
		
			
				
					|  |  |  | @ -402,6 +624,8 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <Plug | 
		
	
		
			
				|  |  |  |  |         "stocks", "An improved stocks display screen", | 
		
	
		
			
				|  |  |  |  |         stocks_cmd, false, "")); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     ViewscreenStocks::hide_flags.whole = 0; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     return CR_OK; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -410,6 +634,7 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     switch (event) { | 
		
	
		
			
				|  |  |  |  |     case SC_MAP_LOADED: | 
		
	
		
			
				|  |  |  |  |         ViewscreenStocks::hide_flags.whole = 0; | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |     default: | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
	
		
			
				
					|  |  |  | 
 |