Merge remote-tracking branch 'ab9rf/master'
						commit
						1b5ce7b717
					
				| @ -0,0 +1,116 @@ | |||||||
|  | #include "Core.h" | ||||||
|  | #include "Console.h" | ||||||
|  | #include "Export.h" | ||||||
|  | #include "PluginManager.h" | ||||||
|  | 
 | ||||||
|  | #include "DataDefs.h" | ||||||
|  | #include "df/world.h" | ||||||
|  | #include "df/ui.h" | ||||||
|  | #include "df/building_nest_boxst.h" | ||||||
|  | #include "df/building_type.h" | ||||||
|  | #include "df/global_objects.h" | ||||||
|  | #include "df/item.h" | ||||||
|  | #include "df/unit.h" | ||||||
|  | #include "df/building.h" | ||||||
|  | #include "df/items_other_id.h" | ||||||
|  | #include "df/creature_raw.h" | ||||||
|  | #include "modules/MapCache.h" | ||||||
|  | #include "modules/Items.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | using std::vector; | ||||||
|  | using std::string; | ||||||
|  | using std::endl; | ||||||
|  | using namespace DFHack; | ||||||
|  | using namespace df::enums; | ||||||
|  | 
 | ||||||
|  | using df::global::world; | ||||||
|  | using df::global::ui; | ||||||
|  | 
 | ||||||
|  | static command_result nestboxes(color_ostream &out, vector <string> & parameters); | ||||||
|  | 
 | ||||||
|  | DFHACK_PLUGIN("nestboxes"); | ||||||
|  | 
 | ||||||
|  | DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands) | ||||||
|  | { | ||||||
|  |     if (world && ui) { | ||||||
|  | 		commands.push_back( | ||||||
|  | 			PluginCommand("nestboxes", "Derp.", | ||||||
|  | 				nestboxes, false,  | ||||||
|  | 				"Derp.\n" | ||||||
|  | 			) | ||||||
|  | 		); | ||||||
|  |     } | ||||||
|  |     return CR_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | DFhackCExport command_result plugin_shutdown ( color_ostream &out ) | ||||||
|  | { | ||||||
|  |     return CR_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static command_result nestboxes(color_ostream &out, vector <string> & parameters) | ||||||
|  | { | ||||||
|  | 	CoreSuspender suspend; | ||||||
|  | 	bool clean = false; | ||||||
|  |     int dump_count = 0; | ||||||
|  |     int good_egg = 0; | ||||||
|  | 
 | ||||||
|  |     if (parameters.size() == 1 && parameters[0] == "clean")  | ||||||
|  |     { | ||||||
|  |         clean = true; | ||||||
|  |     } | ||||||
|  | 	for (int i = 0; i < world->buildings.all.size(); ++i) | ||||||
|  | 	{ | ||||||
|  | 		df::building *build = world->buildings.all[i]; | ||||||
|  | 		auto type = build->getType(); | ||||||
|  | 		if (df::enums::building_type::NestBox == type) | ||||||
|  | 		{ | ||||||
|  |             bool needs_clean = false; | ||||||
|  | 			df::building_nest_boxst *nb = virtual_cast<df::building_nest_boxst>(build); | ||||||
|  | 			out << "Nestbox at (" << nb->x1 << "," << nb->y1 << ","<< nb->z << "): claimed-by " << nb->claimed_by << ", contained item count " << nb->contained_items.size() << " (" << nb->anon_1 << ")" << endl; | ||||||
|  |             if (nb->contained_items.size() > 1) | ||||||
|  |                 needs_clean = true; | ||||||
|  |             if (nb->claimed_by != -1)  | ||||||
|  |             { | ||||||
|  |                 df::unit* u = df::unit::find(nb->claimed_by); | ||||||
|  |                 if (u)  | ||||||
|  |                 { | ||||||
|  |                     out << "  Claimed by "; | ||||||
|  |                     if (u->name.has_name)  | ||||||
|  |                         out << u->name.first_name << ", "; | ||||||
|  |                     df::creature_raw *raw = df::global::world->raws.creatures.all[u->race]; | ||||||
|  |                     out << raw->creature_id | ||||||
|  |                         << ", pregnancy timer " << u->relations.pregnancy_timer << endl; | ||||||
|  |                     if (u->relations.pregnancy_timer > 0)  | ||||||
|  |                         needs_clean = false; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             for (int j = 1; j < nb->contained_items.size(); j++) | ||||||
|  |             { | ||||||
|  |                 df::item* item = nb->contained_items[j]->item; | ||||||
|  |                 if (needs_clean) { | ||||||
|  |                     if (clean && !item->flags.bits.dump)  | ||||||
|  |                     { | ||||||
|  |                         item->flags.bits.dump = 1; | ||||||
|  |                         dump_count += item->getStackSize(); | ||||||
|  |                      | ||||||
|  |                     } | ||||||
|  |                 } else { | ||||||
|  |                     good_egg += item->getStackSize(); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 		} | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (clean) | ||||||
|  |     { | ||||||
|  |         out << dump_count << " eggs dumped." << endl; | ||||||
|  |     } | ||||||
|  |     out << good_egg << " fertile eggs found." << endl; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	return CR_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| @ -0,0 +1,163 @@ | |||||||
|  | // Produces a list of materials available on the map.
 | ||||||
|  | // Options:
 | ||||||
|  | //  -a : show unrevealed tiles
 | ||||||
|  | //  -p : don't show plants
 | ||||||
|  | //  -s : don't show slade
 | ||||||
|  | //  -t : don't show demon temple
 | ||||||
|  | 
 | ||||||
|  | //#include <cstdlib>
 | ||||||
|  | #include <iostream> | ||||||
|  | #include <iomanip> | ||||||
|  | #include <map> | ||||||
|  | #include <algorithm> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | using namespace std; | ||||||
|  | #include "Core.h" | ||||||
|  | #include "Console.h" | ||||||
|  | #include "Export.h" | ||||||
|  | #include "PluginManager.h" | ||||||
|  | #include "modules/MapCache.h" | ||||||
|  | 
 | ||||||
|  | #include "MiscUtils.h" | ||||||
|  | 
 | ||||||
|  | #include "DataDefs.h" | ||||||
|  | #include "df/world.h" | ||||||
|  | #include "df/world_data.h" | ||||||
|  | #include "df/world_region_details.h" | ||||||
|  | #include "df/world_geo_biome.h" | ||||||
|  | #include "df/world_geo_layer.h" | ||||||
|  | #include "df/inclusion_type.h" | ||||||
|  | #include "df/viewscreen_choose_start_sitest.h" | ||||||
|  | 
 | ||||||
|  | using namespace DFHack; | ||||||
|  | using namespace df::enums; | ||||||
|  | using df::global::world; | ||||||
|  | using df::coord2d; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | command_result rprobe (color_ostream &out, vector <string> & parameters); | ||||||
|  | 
 | ||||||
|  | DFHACK_PLUGIN("rprobe"); | ||||||
|  | 
 | ||||||
|  | DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands) | ||||||
|  | { | ||||||
|  |     commands.push_back(PluginCommand( | ||||||
|  |         "rprobe", "Display assorted region information from embark screen", | ||||||
|  |         rprobe, false, | ||||||
|  |         "Display assorted region information from embark screen\n" | ||||||
|  |     )); | ||||||
|  |     return CR_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | DFhackCExport command_result plugin_shutdown ( color_ostream &out ) | ||||||
|  | { | ||||||
|  |     return CR_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | command_result rprobe (color_ostream &out, vector <string> & parameters) | ||||||
|  | { | ||||||
|  |     CoreSuspender suspend; | ||||||
|  | 
 | ||||||
|  |     bool set = false; | ||||||
|  |     int to_set, set_field, set_val; | ||||||
|  | 
 | ||||||
|  |     // Embark screen active: estimate using world geology data
 | ||||||
|  |     VIRTUAL_CAST_VAR(screen, df::viewscreen_choose_start_sitest, Core::getTopViewscreen()); | ||||||
|  | 	 | ||||||
|  | 	if (!screen)  | ||||||
|  | 		return CR_WRONG_USAGE; | ||||||
|  | 	 | ||||||
|  |     if (!world || !world->world_data) | ||||||
|  |     { | ||||||
|  |         out.printerr("World data is not available.\n"); | ||||||
|  |         return CR_FAILURE; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     if (parameters.size() == 2)  | ||||||
|  |     { | ||||||
|  |         if (parameters[0] == "wet")  | ||||||
|  |             set_field = 0; | ||||||
|  |         else if (parameters[0] == "veg") | ||||||
|  |             set_field = 1; | ||||||
|  |         else if (parameters[0] == "tem") | ||||||
|  |             set_field = 2; | ||||||
|  |         else if (parameters[0] == "evi") | ||||||
|  |             set_field = 3; | ||||||
|  |         else if (parameters[0] == "hil") | ||||||
|  |             set_field = 4; | ||||||
|  |         else if (parameters[0] == "sav") | ||||||
|  |             set_field = 5; | ||||||
|  |         else if (parameters[0] == "sal") | ||||||
|  |             set_field = 6; | ||||||
|  |         else | ||||||
|  |             return CR_WRONG_USAGE; | ||||||
|  | 
 | ||||||
|  |         if (screen->biome_highlighted)  | ||||||
|  |             to_set = screen->biome_idx; | ||||||
|  |         else | ||||||
|  |             to_set = 0; | ||||||
|  | 
 | ||||||
|  |         set = true; | ||||||
|  |         set_val = atoi(parameters[1].c_str()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     df::world_data *data = world->world_data; | ||||||
|  |     coord2d cur_region = screen->region_pos; | ||||||
|  | 
 | ||||||
|  |     // Compute biomes
 | ||||||
|  |     for (int i = 0; i < screen->biome_rgn.size(); i++)  | ||||||
|  |     { | ||||||
|  |         coord2d rg = screen->biome_rgn[i]; | ||||||
|  | 
 | ||||||
|  |         df::world_data::T_region_map* rd = &data->region_map[rg.x][rg.y]; | ||||||
|  | 
 | ||||||
|  |         if (set && i == to_set) { | ||||||
|  |             if (set_field == 0) | ||||||
|  |                 rd->wetness = set_val; | ||||||
|  |             else if (set_field == 1) | ||||||
|  |                 rd->vegetation = set_val; | ||||||
|  |             else if (set_field == 2) | ||||||
|  |                 rd->temperature = set_val; | ||||||
|  |             else if (set_field == 3) | ||||||
|  |                 rd->evilness = set_val; | ||||||
|  |             else if (set_field == 4) | ||||||
|  |                 rd->hilliness = set_val; | ||||||
|  |             else if (set_field == 5) | ||||||
|  |                 rd->savagery = set_val; | ||||||
|  |             else if (set_field == 6) | ||||||
|  |                 rd->saltiness = set_val; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         out << i << ": x = " << rg.x << ", y = " << rg.y; | ||||||
|  | 
 | ||||||
|  |         out << | ||||||
|  |             " region_id: " << rd->region_id << | ||||||
|  |             " geo_index: " << rd->geo_index << | ||||||
|  |             " landmass_id: " << rd->landmass_id << | ||||||
|  |             " flags: " << hex << rd->flags.as_int() << dec << endl; | ||||||
|  |         out <<  | ||||||
|  |             "wet: " << rd->wetness << " " << | ||||||
|  |             "veg: " << rd->vegetation << " " << | ||||||
|  |             "tem: " << rd->temperature << " " << | ||||||
|  |             "evi: " << rd->evilness << " " << | ||||||
|  |             "hil: " << rd->hilliness << " " << | ||||||
|  |             "sav: " << rd->savagery << " " << | ||||||
|  |             "sal: " << rd->saltiness; | ||||||
|  |              | ||||||
|  |         int32_t *p = (int32_t *)rd; | ||||||
|  |         int c = sizeof(*rd) / sizeof(int32_t); | ||||||
|  |         for (int j = 0; j < c; j++) { | ||||||
|  |             if (j % 8 == 0)  | ||||||
|  |             out << endl << setfill('0') << setw(8) << hex << (int)(rd+j) << ": "; | ||||||
|  |             out << " " << setfill('0') << setw(8) << hex << p[j]; | ||||||
|  |         } | ||||||
|  |         out << setfill(' ') << setw(0) << dec << endl; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     return CR_OK; | ||||||
|  | } | ||||||
| @ -0,0 +1,278 @@ | |||||||
|  | #include "Core.h" | ||||||
|  | #include "Console.h" | ||||||
|  | #include "Export.h" | ||||||
|  | #include "PluginManager.h" | ||||||
|  | 
 | ||||||
|  | #include "DataDefs.h" | ||||||
|  | #include "df/world.h" | ||||||
|  | #include "df/ui.h" | ||||||
|  | #include "df/building_stockpilest.h" | ||||||
|  | #include "df/global_objects.h" | ||||||
|  | #include "df/item.h" | ||||||
|  | #include "df/unit.h" | ||||||
|  | #include "df/building.h" | ||||||
|  | #include "df/items_other_id.h" | ||||||
|  | #include "df/item_stockpile_ref.h" | ||||||
|  | #include "modules/MapCache.h" | ||||||
|  | #include "modules/Items.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | using std::vector; | ||||||
|  | using std::string; | ||||||
|  | using std::endl; | ||||||
|  | using namespace DFHack; | ||||||
|  | using namespace df::enums; | ||||||
|  | 
 | ||||||
|  | using df::global::world; | ||||||
|  | using df::global::ui; | ||||||
|  | using df::global::selection_rect; | ||||||
|  | 
 | ||||||
|  | using df::building_stockpilest; | ||||||
|  | 
 | ||||||
|  | static command_result copystock(color_ostream &out, vector <string> & parameters); | ||||||
|  | static command_result stockcheck(color_ostream &out, vector <string> & parameters); | ||||||
|  | static bool copystock_guard(df::viewscreen *top); | ||||||
|  | 
 | ||||||
|  | DFHACK_PLUGIN("stockcheck"); | ||||||
|  | 
 | ||||||
|  | DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands) | ||||||
|  | { | ||||||
|  |     if (world && ui) { | ||||||
|  | 		commands.push_back( | ||||||
|  | 			PluginCommand("stockcheck", "Check for unprotected rottable items.", | ||||||
|  | 				stockcheck, false,  | ||||||
|  | 				"Scan world for items that are susceptible to rot.  Currently just lists the items.\n" | ||||||
|  | 			) | ||||||
|  | 		); | ||||||
|  |     } | ||||||
|  |     return CR_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | DFhackCExport command_result plugin_shutdown ( color_ostream &out ) | ||||||
|  | { | ||||||
|  |     return CR_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct StockpileInfo { | ||||||
|  | 	building_stockpilest* sp; | ||||||
|  | 	int size; | ||||||
|  | 	int free; | ||||||
|  | 	int x1, x2, y1, y2, z; | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  | 	StockpileInfo(building_stockpilest *sp_) : sp(sp_)  | ||||||
|  | 	{ | ||||||
|  | 		MapExtras::MapCache mc; | ||||||
|  | 
 | ||||||
|  | 		z = sp_->z; | ||||||
|  | 		x1 = sp_->room.x;  | ||||||
|  | 		x2 = sp_->room.x + sp_->room.width; | ||||||
|  | 		y1 = sp_->room.y; | ||||||
|  | 		y2 = sp_->room.y + sp_->room.height; | ||||||
|  | 		int e = 0; | ||||||
|  | 		size = 0; | ||||||
|  | 		free = 0; | ||||||
|  | 		for (int y = y1; y < y2; y++)  | ||||||
|  | 			for (int x = x1; x < x2; x++)  | ||||||
|  | 				if (sp_->room.extents[e++] == 1)  | ||||||
|  | 				{ | ||||||
|  | 					size++; | ||||||
|  | 					DFCoord cursor (x,y,z); | ||||||
|  | 					uint32_t blockX = x / 16; | ||||||
|  | 					uint32_t tileX = x % 16; | ||||||
|  | 					uint32_t blockY = y / 16; | ||||||
|  | 					uint32_t tileY = y % 16; | ||||||
|  | 					MapExtras::Block * b = mc.BlockAt(cursor/16); | ||||||
|  | 					if(b && b->is_valid()) | ||||||
|  | 					{ | ||||||
|  | 						auto &block = *b->getRaw(); | ||||||
|  | 						df::tile_occupancy &occ = block.occupancy[tileX][tileY]; | ||||||
|  | 						if (!occ.bits.item) | ||||||
|  | 							free++; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	bool isFull() { return free == 0; } | ||||||
|  | 
 | ||||||
|  | 	bool canHold(df::item *i)  | ||||||
|  | 	{ | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	bool inStockpile(df::item *i) | ||||||
|  | 	{ | ||||||
|  | 		df::item *container = Items::getContainer(i); | ||||||
|  | 		if (container)  | ||||||
|  | 			return inStockpile(container); | ||||||
|  | 
 | ||||||
|  | 		if (i->pos.z != z) return false; | ||||||
|  | 		if (i->pos.x < x1 || i->pos.x >= x2 || | ||||||
|  | 			i->pos.y < y1 || i->pos.y >= y2) return false; | ||||||
|  | 		int e = (i->pos.x - x1) + (i->pos.y - y1) * sp->room.width; | ||||||
|  | 		return sp->room.extents[e] == 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	int getId() { return sp->id; } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static command_result stockcheck(color_ostream &out, vector <string> & parameters) | ||||||
|  | { | ||||||
|  | 	CoreSuspender suspend; | ||||||
|  | 	 | ||||||
|  | 	std::vector<StockpileInfo*> stockpiles; | ||||||
|  | 
 | ||||||
|  | 	for (int i = 0; i < world->buildings.all.size(); ++i) | ||||||
|  | 	{ | ||||||
|  | 		df::building *build = world->buildings.all[i]; | ||||||
|  | 		auto type = build->getType(); | ||||||
|  | 		if (df::enums::building_type::Stockpile == type) | ||||||
|  | 		{ | ||||||
|  | 			building_stockpilest *sp = virtual_cast<building_stockpilest>(build); | ||||||
|  | 			StockpileInfo *spi = new StockpileInfo(sp); | ||||||
|  | 			stockpiles.push_back(spi); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	std::vector<df::item*> &items = world->items.other[items_other_id::ANY_FREE]; | ||||||
|  | 
 | ||||||
|  | 	// Precompute a bitmask with the bad flags
 | ||||||
|  |     df::item_flags bad_flags; | ||||||
|  |     bad_flags.whole = 0; | ||||||
|  | 
 | ||||||
|  | #define F(x) bad_flags.bits.x = true; | ||||||
|  |     F(dump); F(forbid); F(garbage_collect); | ||||||
|  |     F(hostile); F(on_fire); F(rotten); F(trader); | ||||||
|  |     F(in_building); F(construction); F(artifact1); | ||||||
|  | 	F(spider_web); F(owned); F(in_job); | ||||||
|  | #undef F | ||||||
|  | 
 | ||||||
|  |     for (size_t i = 0; i < items.size(); i++) | ||||||
|  |     { | ||||||
|  |         df::item *item = items[i]; | ||||||
|  | 		if (item->flags.whole & bad_flags.whole) | ||||||
|  |             continue; | ||||||
|  | 
 | ||||||
|  | 		// we really only care about MEAT, FISH, FISH_RAW, PLANT, CHEESE, FOOD, and EGG
 | ||||||
|  | 
 | ||||||
|  | 		df::item_type typ = item->getType(); | ||||||
|  | 		if (typ != df::enums::item_type::MEAT && | ||||||
|  | 			typ != df::enums::item_type::FISH && | ||||||
|  | 			typ != df::enums::item_type::FISH_RAW && | ||||||
|  | 			typ != df::enums::item_type::PLANT && | ||||||
|  | 			typ != df::enums::item_type::CHEESE && | ||||||
|  | 			typ != df::enums::item_type::FOOD && | ||||||
|  | 			typ != df::enums::item_type::EGG) | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		df::item *container = 0; | ||||||
|  | 		df::unit *holder = 0; | ||||||
|  | 		df::building *building = 0; | ||||||
|  | 
 | ||||||
|  |         for (size_t i = 0; i < item->itemrefs.size(); i++) | ||||||
|  |         { | ||||||
|  |             df::general_ref *ref = item->itemrefs[i]; | ||||||
|  | 
 | ||||||
|  |             switch (ref->getType()) | ||||||
|  |             { | ||||||
|  |             case general_ref_type::CONTAINED_IN_ITEM: | ||||||
|  | 				container = ref->getItem(); | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case general_ref_type::UNIT_HOLDER: | ||||||
|  | 				holder = ref->getUnit(); | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case general_ref_type::BUILDING_HOLDER: | ||||||
|  | 				building = ref->getBuilding(); | ||||||
|  |                 break; | ||||||
|  |              | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		df::item *nextcontainer = container; | ||||||
|  | 		df::item *lastcontainer = 0; | ||||||
|  | 
 | ||||||
|  | 		while(nextcontainer) { | ||||||
|  | 			df::item *thiscontainer = nextcontainer; | ||||||
|  | 			nextcontainer = 0; | ||||||
|  | 	        for (size_t i = 0; i < thiscontainer->itemrefs.size(); i++) | ||||||
|  | 		    { | ||||||
|  | 			    df::general_ref *ref = thiscontainer->itemrefs[i]; | ||||||
|  | 
 | ||||||
|  | 	            switch (ref->getType()) | ||||||
|  | 				{ | ||||||
|  | 	            case general_ref_type::CONTAINED_IN_ITEM: | ||||||
|  | 					lastcontainer = nextcontainer = ref->getItem(); | ||||||
|  | 			        break; | ||||||
|  | 
 | ||||||
|  | 	            case general_ref_type::UNIT_HOLDER: | ||||||
|  | 					holder = ref->getUnit(); | ||||||
|  | 			        break; | ||||||
|  | 
 | ||||||
|  | 	            case general_ref_type::BUILDING_HOLDER: | ||||||
|  | 					building = ref->getBuilding(); | ||||||
|  | 			        break; | ||||||
|  |              | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (holder)  | ||||||
|  | 			continue; // carried items do not rot as far as i know
 | ||||||
|  | 		 | ||||||
|  | 		if (building) { | ||||||
|  | 			df::building_type btype = building->getType(); | ||||||
|  | 			if (btype == df::enums::building_type::TradeDepot || | ||||||
|  | 				btype == df::enums::building_type::Wagon) | ||||||
|  | 				continue; // items in trade depot or the embark wagon do not rot
 | ||||||
|  | 			 | ||||||
|  | 			if (typ == df::enums::item_type::EGG && btype ==df::enums::building_type::NestBox) | ||||||
|  | 				continue; // eggs in nest box do not rot			
 | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		int canHoldCount = 0; | ||||||
|  | 		StockpileInfo *current = 0; | ||||||
|  | 
 | ||||||
|  | 		for (int idx = 0; idx < stockpiles.size(); idx++) | ||||||
|  | 		{ | ||||||
|  | 			StockpileInfo *spi = stockpiles[idx]; | ||||||
|  | 			if (spi->canHold(item)) canHoldCount++; | ||||||
|  | 			if (spi->inStockpile(item)) current=spi; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (current)  | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		std::string description; | ||||||
|  | 		item->getItemDescription(&description, 0); | ||||||
|  | 		out << " * " << description; | ||||||
|  | 
 | ||||||
|  |         if (container) { | ||||||
|  | 			std::string containerDescription; | ||||||
|  | 			container->getItemDescription(&containerDescription, 0); | ||||||
|  | 			out << ", in container " << containerDescription; | ||||||
|  | 			if (lastcontainer) { | ||||||
|  | 				std::string lastcontainerDescription; | ||||||
|  | 				lastcontainer->getItemDescription(&lastcontainerDescription, 0); | ||||||
|  | 				out << ", in container " << lastcontainerDescription; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (holder) { | ||||||
|  | 			out << ", carried"; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (building) { | ||||||
|  | 			out << ", in building " << building->id << " (type=" << building->getType() << ")"; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		out << ", flags=" << std::hex << item->flags.whole << std::dec; | ||||||
|  | 		out << endl; | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return CR_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| @ -0,0 +1,103 @@ | |||||||
|  | 
 | ||||||
|  | #include <iostream> | ||||||
|  | #include <iomanip> | ||||||
|  | #include <climits> | ||||||
|  | #include <vector> | ||||||
|  | #include <algorithm> | ||||||
|  | #include <string> | ||||||
|  | #include <sstream> | ||||||
|  | #include <ctime> | ||||||
|  | #include <cstdio> | ||||||
|  | using namespace std; | ||||||
|  | 
 | ||||||
|  | #include "Core.h" | ||||||
|  | #include "Console.h" | ||||||
|  | #include "Export.h" | ||||||
|  | #include "PluginManager.h" | ||||||
|  | #include "modules/Units.h" | ||||||
|  | #include "modules/Maps.h" | ||||||
|  | #include "modules/Gui.h" | ||||||
|  | #include "modules/World.h" | ||||||
|  | #include "MiscUtils.h" | ||||||
|  | 
 | ||||||
|  | #include <df/ui.h> | ||||||
|  | #include "df/world.h" | ||||||
|  | #include "df/world_raws.h" | ||||||
|  | #include "df/building_def.h" | ||||||
|  | #include "df/unit_inventory_item.h" | ||||||
|  | #include <df/creature_raw.h> | ||||||
|  | #include <df/caste_raw.h> | ||||||
|  | 
 | ||||||
|  | using std::vector; | ||||||
|  | using std::string; | ||||||
|  | using namespace DFHack; | ||||||
|  | using namespace df::enums; | ||||||
|  | using df::global::world; | ||||||
|  | using df::global::cursor; | ||||||
|  | using df::global::ui; | ||||||
|  | 
 | ||||||
|  | using namespace DFHack::Gui; | ||||||
|  | 
 | ||||||
|  | command_result df_stripcaged(color_ostream &out, vector <string> & parameters); | ||||||
|  | 
 | ||||||
|  | DFHACK_PLUGIN("stripcaged"); | ||||||
|  | 
 | ||||||
|  | // check if contained in item (e.g. animals in cages)
 | ||||||
|  | bool isContainedInItem(df::unit* unit) | ||||||
|  | { | ||||||
|  |     bool contained = false; | ||||||
|  |     for (size_t r=0; r < unit->refs.size(); r++) | ||||||
|  |     { | ||||||
|  |         df::general_ref * ref = unit->refs[r]; | ||||||
|  |         auto rtype = ref->getType(); | ||||||
|  |         if(rtype == df::general_ref_type::CONTAINED_IN_ITEM) | ||||||
|  |         { | ||||||
|  |             contained = true; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return contained; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands) | ||||||
|  | { | ||||||
|  | 	commands.push_back(PluginCommand( | ||||||
|  | 		"stripcaged", "strip caged units of all items", | ||||||
|  | 		df_stripcaged, false, | ||||||
|  | 		"Clears forbid and sets dump for the inventories of all caged units." | ||||||
|  | 		)); | ||||||
|  |     return CR_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | DFhackCExport command_result plugin_shutdown ( color_ostream &out ) | ||||||
|  | { | ||||||
|  |     return CR_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | command_result df_stripcaged(color_ostream &out, vector <string> & parameters) | ||||||
|  | { | ||||||
|  |     CoreSuspender suspend; | ||||||
|  | 
 | ||||||
|  | 	size_t count = 0; | ||||||
|  |     for (size_t i=0; i < world->units.all.size(); i++) | ||||||
|  |     { | ||||||
|  |         df::unit* unit = world->units.all[i]; | ||||||
|  | 		if (isContainedInItem(unit))  | ||||||
|  | 		{ | ||||||
|  | 			for (size_t j=0; j < unit->inventory.size(); j++)  | ||||||
|  | 			{ | ||||||
|  | 				df::unit_inventory_item* uii = unit->inventory[j]; | ||||||
|  | 				if (uii->item) | ||||||
|  | 				{ | ||||||
|  | 					uii->item->flags.bits.forbid = 0; | ||||||
|  | 					uii->item->flags.bits.dump = 1; | ||||||
|  | 					count++; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	out << count << " items marked for dumping" << endl; | ||||||
|  | 
 | ||||||
|  |     return CR_OK; | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue