From 9b071097de73dc19e5f3d5be31134810bad3e6f7 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Wed, 7 Mar 2012 18:10:53 +0400 Subject: [PATCH] Fix advtools metal-detector Trader items are now inside tables, and thus not in the block item lists. Thus it is necessary to scan the global item vector and look up blocks by coords. --- library/include/modules/Maps.h | 3 ++ plugins/advtools.cpp | 53 +++++++++++++++++++--------------- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/library/include/modules/Maps.h b/library/include/modules/Maps.h index d67000048..67e2aac89 100644 --- a/library/include/modules/Maps.h +++ b/library/include/modules/Maps.h @@ -272,6 +272,9 @@ extern DFHACK_EXPORT void getPosition(int32_t& x, int32_t& y, int32_t& z); extern DFHACK_EXPORT df::map_block * getBlock (int32_t blockx, int32_t blocky, int32_t blockz); extern DFHACK_EXPORT df::map_block * getBlockAbs (int32_t x, int32_t y, int32_t z); +inline df::map_block * getBlock (df::coord pos) { return getBlock(pos.x, pos.y, pos.z); } +inline df::map_block * getBlockAbs (df::coord pos) { return getBlockAbs(pos.x, pos.y, pos.z); } + /// copy the whole map block at block coords (see DFTypes.h for the block structure) extern DFHACK_EXPORT bool ReadBlock40d(uint32_t blockx, uint32_t blocky, uint32_t blockz, mapblock40d * buffer); diff --git a/plugins/advtools.cpp b/plugins/advtools.cpp index 15a7cad92..381eb7ab3 100644 --- a/plugins/advtools.cpp +++ b/plugins/advtools.cpp @@ -6,6 +6,7 @@ #include "modules/World.h" #include "modules/Translation.h" #include "modules/Materials.h" +#include "modules/Maps.h" #include "modules/Items.h" #include "DataDefs.h" @@ -19,6 +20,8 @@ #include "df/historical_figure.h" #include "df/general_ref_is_nemesisst.h" #include "df/general_ref_contains_itemst.h" +#include "df/general_ref_contained_in_itemst.h" +#include "df/general_ref_unit_holderst.h" #include "df/general_ref_building_civzone_assignedst.h" #include "df/material.h" #include "df/craft_material_class.h" @@ -421,7 +424,7 @@ bool isWeaponArmor(df::item *item) } } -int containsMetalItems(df::item *item, bool all, bool non_trader) +int containsMetalItems(df::item *item, bool all, bool non_trader, bool rec = false) { int cnt = 0; @@ -429,13 +432,19 @@ int containsMetalItems(df::item *item, bool all, bool non_trader) for (size_t i = 0; i < refs.size(); i++) { auto ref = refs[i]; - if (!strict_virtual_cast(ref)) - continue; - df::item *child = ref->getItem(); - if (!child) continue; + if (strict_virtual_cast(ref)) + return 0; + if (!rec && strict_virtual_cast(ref)) + return 0; + + if (strict_virtual_cast(ref)) + { + df::item *child = ref->getItem(); + if (!child) continue; - cnt += containsMetalItems(child, all, non_trader); + cnt += containsMetalItems(child, all, non_trader, true); + } } if (!non_trader && !isShopItem(item)) @@ -787,29 +796,27 @@ command_result adv_tools (Core * c, std::vector & parameters) int total = 0; std::map counts; - for (size_t i = 0; i < world->map.map_blocks.size(); i++) + auto &items = world->items.all; + for (size_t i = 0; i < items.size(); i++) { - df::map_block *block = world->map.map_blocks[i]; + df::item *item = items[i]; - for (size_t j = 0; j < block->items.size(); j++) - { - df::item *item = df::item::find(block->items[j]); - if (!item) - continue; + int num = containsMetalItems(item, all, non_trader); + if (!num) + continue; - int num = containsMetalItems(item, all, non_trader); - if (!num) - continue; + df::map_block *block = Maps::getBlockAbs(item->pos); + if (!block) + continue; - total += num; - counts[(item->pos - player_pos)/10] += num; + total += num; + counts[(item->pos - player_pos)/10] += num; - auto &designations = block->designation; - auto &dgn = designations[item->pos.x%16][item->pos.y%16]; + 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 - } + dgn.bits.hidden = 0; // revealed + dgn.bits.pile = 1; // visible } joinCounts(counts);