#include #include #include #include #include #include #include #include #include // sprintf() using std::vector; using std::string; using namespace DFHack; ////////////////////// // START item choosers ////////////////////// class item_chooser { public: item_chooser(Core* _c, DFHack::Items* _Items) : c(_c), Items(_Items) { } virtual bool doPrint(DFHack::dfh_item *itm) = 0; virtual void postPrint(DFHack::dfh_item *itm) { } protected: Core *c; DFHack::Items *Items; }; class choose_all : public item_chooser { public: choose_all(Core* _c, ::Items* _Items) : item_chooser(_c, _Items) { } virtual bool doPrint(DFHack::dfh_item *itm) { return (true); } }; class choose_unknown : public item_chooser { public: choose_unknown(Core* _c, ::Items* _Items) : item_chooser(_c, _Items) { } virtual bool doPrint(DFHack::dfh_item *itm) { if (itm->base->unk1.size() > 0) return true; std::vector refs; std::vector values; if (Items->unknownRefs(*itm, refs, values)) return true; t_itemflags &f = itm->base->flags; return (f.unk1 || f.unk2 || f.unk3 || f.unk4 || f.unk5 || f.unk6 || f.unk7 || // f.unk8 || f.unk9 || /* Too common */ f.unk10 || f.unk11); } virtual void postPrint(DFHack::dfh_item *itm) { std::vector flags; t_itemflags &f = itm->base->flags; if (itm->base->unk1.size() > 0) c->con.print(" vec1: %p\n", itm->base->unk1[0]); std::vector refs; std::vector values; if (Items->unknownRefs(*itm, refs, values)) { c->con.print(" refs: "); for (size_t i = 0; i < refs.size(); i++) { c->con.print("%s: %d", refs[i].c_str(), values[i]); if ( (i + 1) < refs.size() ) c->con.print(", "); } c->con.print("\n"); } if (f.unk1) flags.push_back("unk1"); if (f.unk2) flags.push_back("unk2"); if (f.unk3) flags.push_back("unk3"); if (f.unk4) flags.push_back("unk4"); if (f.unk5) flags.push_back("unk5"); if (f.unk6) flags.push_back("unk6"); if (f.unk7) flags.push_back("unk7"); if (f.unk8) flags.push_back("unk8"); if (f.unk9) flags.push_back("unk9"); if (f.unk10) flags.push_back("unk10"); if (f.unk11) flags.push_back("unk11"); if (flags.size() > 0) { c->con.print(" flags: "); for (size_t i = 0; i < flags.size(); i++) { c->con.print("%s", flags[i].c_str()); if ( (i + 1) < flags.size() ) c->con.print(", "); } c->con.print("\n"); } } }; class choose_cursor : public item_chooser { public: choose_cursor(Core* _c, ::Items* _Items, int32_t _x, int32_t _y, int32_t _z) : item_chooser(_c, _Items), x(_x), y(_y), z(_z) { } virtual bool doPrint(DFHack::dfh_item *itm) { return (itm->base->x == x && itm->base->y == y && itm->base->z == z && itm->base->flags.on_ground && !itm->base->flags.in_chest && !itm->base->flags.in_inventory && !itm->base->flags.in_building); } protected: int32_t x, y, z; }; ////////////////////// // END item choosers ////////////////////// DFhackCExport command_result df_dumpitems (Core * c, vector & parameters); DFhackCExport const char * plugin_name ( void ) { return "itemhacks"; } DFhackCExport command_result plugin_init ( Core * c, std::vector &commands) { commands.clear(); commands.push_back(PluginCommand("dumpitems", "Dump items\ \n Options:\ \n unkown: Dump items that have anything unknown set", df_dumpitems)); return CR_OK; } DFhackCExport command_result plugin_shutdown ( Core * c ) { return CR_OK; } DFhackCExport command_result df_dumpitems (Core * c, vector & parameters) { c->Suspend(); DFHack::Materials * Materials = c->getMaterials(); Materials->ReadAllMaterials(); DFHack::Gui * Gui = c->getGui(); DFHack::Items * Items = c->getItems(); Items->Start(); int32_t x,y,z; Gui->getCursorCoords(x,y,z); std::vector p_items; Items->readItemVector(p_items); uint32_t size = p_items.size(); item_chooser *chooser = NULL; if (x != -30000) chooser = new choose_cursor(c, Items, x, y, z); else if (parameters.size() == 0) chooser = new choose_all(c, Items); else if (parameters[0] == "unknown") chooser = new choose_unknown(c, Items); else { c->con.printerr("Invalid option: %s\n", parameters[0].c_str()); Items->Finish(); c->Resume(); return CR_FAILURE; } for(size_t i = 0; i < size; i++) { DFHack::dfh_item itm; memset(&itm, 0, sizeof(DFHack::dfh_item)); Items->readItem(p_items[i],itm); if (!chooser->doPrint(&itm)) continue; // Print something useful, instead of (-30000,-30000,-30000), if // the item isn't on the ground. char location[80]; if (itm.base->flags.in_chest) sprintf(location, "chest"); else if (itm.base->flags.in_inventory) sprintf(location, "inventory"); else if (itm.base->flags.in_building) sprintf(location, "building"); else sprintf(location, "%d,%d,%d", itm.base->x, itm.base->y, itm.base->z); c->con.print( "%5d: addr:0x%08x %6d %08x (%s) vptr:0x%08x [%d]\n" " *%d %s - %s\n", i, itm.base, itm.base->id, itm.base->flags.whole, location, itm.base->vptr, itm.wear_level, itm.quantity, Items->getItemClass(itm.matdesc.itemType).c_str(), Items->getItemDescription(itm, Materials).c_str() ); chooser->postPrint(&itm); /* if (print_hex) hexdump(DF,p_items[i],0x300); */ /* if (print_acc) c->con << Items->dumpAccessors(itm) << endl; */ /* if (print_refs) { DFHack::DfVector p_refs(p, itm.origin + ref_vector); for (size_t j = 0; j < p_refs.size(); j++) { uint32_t vptr = p->readDWord(p_refs[j]); uint32_t val = p->readDWord(p_refs[j]+4); c->con.print("\t-> %d \t%s\n", int(val), p->readClassName(vptr).c_str()); } } */ } c->Resume(); Items->Finish(); delete chooser; return CR_OK; }