Skip to content

Commit 9b07109

Browse files
committed
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.
1 parent cbd2549 commit 9b07109

2 files changed

Lines changed: 33 additions & 23 deletions

File tree

library/include/modules/Maps.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,9 @@ extern DFHACK_EXPORT void getPosition(int32_t& x, int32_t& y, int32_t& z);
272272
extern DFHACK_EXPORT df::map_block * getBlock (int32_t blockx, int32_t blocky, int32_t blockz);
273273
extern DFHACK_EXPORT df::map_block * getBlockAbs (int32_t x, int32_t y, int32_t z);
274274

275+
inline df::map_block * getBlock (df::coord pos) { return getBlock(pos.x, pos.y, pos.z); }
276+
inline df::map_block * getBlockAbs (df::coord pos) { return getBlockAbs(pos.x, pos.y, pos.z); }
277+
275278
/// copy the whole map block at block coords (see DFTypes.h for the block structure)
276279
extern DFHACK_EXPORT bool ReadBlock40d(uint32_t blockx, uint32_t blocky, uint32_t blockz, mapblock40d * buffer);
277280

plugins/advtools.cpp

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "modules/World.h"
77
#include "modules/Translation.h"
88
#include "modules/Materials.h"
9+
#include "modules/Maps.h"
910
#include "modules/Items.h"
1011

1112
#include "DataDefs.h"
@@ -19,6 +20,8 @@
1920
#include "df/historical_figure.h"
2021
#include "df/general_ref_is_nemesisst.h"
2122
#include "df/general_ref_contains_itemst.h"
23+
#include "df/general_ref_contained_in_itemst.h"
24+
#include "df/general_ref_unit_holderst.h"
2225
#include "df/general_ref_building_civzone_assignedst.h"
2326
#include "df/material.h"
2427
#include "df/craft_material_class.h"
@@ -421,21 +424,27 @@ bool isWeaponArmor(df::item *item)
421424
}
422425
}
423426

424-
int containsMetalItems(df::item *item, bool all, bool non_trader)
427+
int containsMetalItems(df::item *item, bool all, bool non_trader, bool rec = false)
425428
{
426429
int cnt = 0;
427430

428431
auto &refs = item->itemrefs;
429432
for (size_t i = 0; i < refs.size(); i++)
430433
{
431434
auto ref = refs[i];
432-
if (!strict_virtual_cast<df::general_ref_contains_itemst>(ref))
433-
continue;
434435

435-
df::item *child = ref->getItem();
436-
if (!child) continue;
436+
if (strict_virtual_cast<df::general_ref_unit_holderst>(ref))
437+
return 0;
438+
if (!rec && strict_virtual_cast<df::general_ref_contained_in_itemst>(ref))
439+
return 0;
440+
441+
if (strict_virtual_cast<df::general_ref_contains_itemst>(ref))
442+
{
443+
df::item *child = ref->getItem();
444+
if (!child) continue;
437445

438-
cnt += containsMetalItems(child, all, non_trader);
446+
cnt += containsMetalItems(child, all, non_trader, true);
447+
}
439448
}
440449

441450
if (!non_trader && !isShopItem(item))
@@ -787,29 +796,27 @@ command_result adv_tools (Core * c, std::vector <std::string> & parameters)
787796
int total = 0;
788797
std::map<df::coord,int> counts;
789798

790-
for (size_t i = 0; i < world->map.map_blocks.size(); i++)
799+
auto &items = world->items.all;
800+
for (size_t i = 0; i < items.size(); i++)
791801
{
792-
df::map_block *block = world->map.map_blocks[i];
802+
df::item *item = items[i];
793803

794-
for (size_t j = 0; j < block->items.size(); j++)
795-
{
796-
df::item *item = df::item::find(block->items[j]);
797-
if (!item)
798-
continue;
804+
int num = containsMetalItems(item, all, non_trader);
805+
if (!num)
806+
continue;
799807

800-
int num = containsMetalItems(item, all, non_trader);
801-
if (!num)
802-
continue;
808+
df::map_block *block = Maps::getBlockAbs(item->pos);
809+
if (!block)
810+
continue;
803811

804-
total += num;
805-
counts[(item->pos - player_pos)/10] += num;
812+
total += num;
813+
counts[(item->pos - player_pos)/10] += num;
806814

807-
auto &designations = block->designation;
808-
auto &dgn = designations[item->pos.x%16][item->pos.y%16];
815+
auto &designations = block->designation;
816+
auto &dgn = designations[item->pos.x%16][item->pos.y%16];
809817

810-
dgn.bits.hidden = 0; // revealed
811-
dgn.bits.pile = 1; // visible
812-
}
818+
dgn.bits.hidden = 0; // revealed
819+
dgn.bits.pile = 1; // visible
813820
}
814821

815822
joinCounts(counts);

0 commit comments

Comments
 (0)