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.
develop
Alexander Gavrilov 2012-03-07 18:10:53 +04:00
parent cbd254991f
commit 9b071097de
2 changed files with 33 additions and 23 deletions

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

@ -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<df::general_ref_contains_itemst>(ref))
continue;
if (strict_virtual_cast<df::general_ref_unit_holderst>(ref))
return 0;
if (!rec && strict_virtual_cast<df::general_ref_contained_in_itemst>(ref))
return 0;
if (strict_virtual_cast<df::general_ref_contains_itemst>(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,20 +796,19 @@ command_result adv_tools (Core * c, std::vector <std::string> & parameters)
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++)
auto &items = world->items.all;
for (size_t i = 0; i < items.size(); i++)
{
df::item *item = df::item::find(block->items[j]);
if (!item)
continue;
df::item *item = items[i];
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;
@ -810,7 +818,6 @@ command_result adv_tools (Core * c, std::vector <std::string> & parameters)
dgn.bits.hidden = 0; // revealed
dgn.bits.pile = 1; // visible
}
}
joinCounts(counts);