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);