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