summaryrefslogtreecommitdiff
path: root/plugins/advtools.cpp
diff options
context:
space:
mode:
authorAlexander Gavrilov2012-03-02 11:10:34 +0400
committerAlexander Gavrilov2012-03-02 11:10:34 +0400
commitae655daf1afde907d8e8e796c88fbc299cdb4900 (patch)
treec4f180ddf63a770850edb1b63f95ea1f17b84717 /plugins/advtools.cpp
parentd01455467955e31c2b338301d310a45cc42afebf (diff)
downloaddfhack-ae655daf1afde907d8e8e796c88fbc299cdb4900.tar.gz
dfhack-ae655daf1afde907d8e8e796c88fbc299cdb4900.tar.bz2
dfhack-ae655daf1afde907d8e8e796c88fbc299cdb4900.tar.xz
Add an advtool for detecting metal stuff in shops.
Inspired by Q's advmode reveal. Obviously doesn't work in travel mode.
Diffstat (limited to 'plugins/advtools.cpp')
-rw-r--r--plugins/advtools.cpp97
1 files changed, 97 insertions, 0 deletions
diff --git a/plugins/advtools.cpp b/plugins/advtools.cpp
index 7ccb4302..a1329d1a 100644
--- a/plugins/advtools.cpp
+++ b/plugins/advtools.cpp
@@ -11,12 +11,15 @@
#include "DataDefs.h"
#include "df/world.h"
#include "df/ui_advmode.h"
+#include "df/item.h"
#include "df/unit.h"
#include "df/unit_inventory_item.h"
+#include "df/map_block.h"
#include "df/nemesis_record.h"
#include "df/historical_figure.h"
#include "df/general_ref_is_nemesisst.h"
#include "df/general_ref_contains_itemst.h"
+#include "df/general_ref_building_civzone_assignedst.h"
#include "df/material.h"
#include "df/craft_material_class.h"
#include "df/viewscreen_optionst.h"
@@ -59,6 +62,9 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
" list-equipped [all]\n"
" List armor and weapons equipped by your companions.\n"
" If all is specified, also lists non-metal clothing.\n"
+ " metal-detector [all-types] [non-trader]\n"
+ " Reveal metal armor and weapons in shops. The options\n"
+ " disable the checks on item type and being in shop.\n"
));
commands.push_back(PluginCommand(
@@ -384,6 +390,36 @@ void listUnitInventory(std::vector<inv_item> *list, df::unit *unit)
}
}
+bool isShopItem(df::item *item)
+{
+ for (size_t k = 0; k < item->itemrefs.size(); k++)
+ {
+ auto ref = item->itemrefs[k];
+ if (virtual_cast<df::general_ref_building_civzone_assignedst>(ref))
+ return true;
+ }
+
+ return false;
+}
+
+bool isWeaponArmor(df::item *item)
+{
+ using namespace df::enums::item_type;
+
+ switch (item->getType()) {
+ case HELM:
+ case ARMOR:
+ case WEAPON:
+ case AMMO:
+ case GLOVES:
+ case PANTS:
+ case SHOES:
+ return true;
+ default:
+ return false;
+ }
+}
+
/*********************
* FORMATTING *
*********************/
@@ -640,6 +676,67 @@ command_result adv_tools (Core * c, std::vector <std::string> & parameters)
return CR_OK;
}
+ else if (command == "metal-detector")
+ {
+ bool all = false, non_trader = false;
+ for (size_t i = 1; i < parameters.size(); i++)
+ {
+ if (parameters[i] == "all-types")
+ all = true;
+ else if (parameters[i] == "non-trader")
+ non_trader = true;
+ else
+ return CR_WRONG_USAGE;
+ }
+
+ auto *player = getPlayerNemesis(c, false);
+ if (!player)
+ return CR_FAILURE;
+
+ df::coord player_pos = player->unit->pos;
+
+ int total = 0;
+ std::map<df::coord,int> counts;
+
+ for (size_t i = 0; i < world->map.map_blocks.size(); i++)
+ {
+ df::map_block *block = world->map.map_blocks[i];
+
+ for (size_t j = 0; j < block->items.size(); j++)
+ {
+ df::item *item = df::item::find(block->items[j]);
+ if (!item)
+ continue;
+
+ if (!non_trader && !isShopItem(item))
+ continue;
+ if (!all && !isWeaponArmor(item))
+ continue;
+
+ MaterialInfo minfo(item);
+ if (minfo.getCraftClass() != craft_material_class::Metal)
+ continue;
+
+ total++;
+ counts[(item->pos - player_pos)/10]++;
+
+ auto &designations = block->designation;
+ auto &dgn = designations[item->pos.x%16][item->pos.y%16];
+
+ dgn.bits.hidden = 0; // revealed
+ dgn.bits.pile = 1; // visible
+ }
+ }
+
+ c->con.print("%d items of metal merchandise found in the vicinity.\n", total);
+ for (auto it = counts.begin(); it != counts.end(); it++)
+ {
+ df::coord delta = it->first * 10;
+ c->con.print(" %+d,%+d,%+d: %d\n", delta.x, delta.y, delta.z, it->second);
+ }
+
+ return CR_OK;
+ }
else
return CR_WRONG_USAGE;
}